/*
 * 版权所有 (c) 2010-2011，MiCode 开源社区 (www.micode.net)
 * 根据 Apache 许可证 2.0 版本（"许可证"）授权；
 * 除非符合许可证的规定，否则不得使用本文件。
 * 您可以从以下网址获取许可证副本：
 * http://www.apache.org/licenses/LICENSE-2.0
 * 除非适用法律要求或书面同意，本软件按"原样"分发，
 * 没有任何明示或暗示的保证或条件。
 * 详见许可证中规定的权限和限制。
 * （注：这是一份标准的Apache许可证2.0版本的开源声明）
 */

// 定义当前类的包路径，属于net.micode.notes.ui 包
package net.micode.notes.ui;

// 导入Android基础类
import android.content.Context;         // 上下文对象，提供应用环境信息
import android.database.Cursor;       // 数据库查询结果游标
import android.text.TextUtils;        // 文本处理工具类

// 导入项目自定义类
import net.micode.notes.data.Contact;       // 联系人数据类
import net.micode.notes.data.Notes;         // 笔记数据常量定义
import net.micode.notes.data.Notes.NoteColumns;   // 笔记表列名定义
import net.micode.notes.tool.DataUtils;    // 数据工具类

/**
 * 笔记项数据类，封装单条笔记的所有数据
 */
public class NoteItemData {
    // 数据库查询列名投影（指定需要查询的列）
    static final String[] PROJECTION = new String[] {
            NoteColumns.ID,               // 笔记ID
            NoteColumns.ALERTED_DATE,     // 提醒日期
            NoteColumns.BG_COLOR_ID,      // 背景颜色ID
            NoteColumns.CREATED_DATE,     // 创建日期
            NoteColumns.HAS_ATTACHMENT,   // 是否有附件
            NoteColumns.MODIFIED_DATE,    // 修改日期
            NoteColumns.NOTES_COUNT,      // 笔记数量（针对文件夹）
            NoteColumns.PARENT_ID,        // 父项ID
            NoteColumns.SNIPPET,          // 内容摘要
            NoteColumns.TYPE,             // 笔记类型
            NoteColumns.WIDGET_ID,        // 关联小部件ID
            NoteColumns.WIDGET_TYPE,      // 小部件类型
    };

    // 列索引常量定义（对应PROJECTION顺序）
    private static final int ID_COLUMN = 0;                    // ID列索引
    private static final int ALERTED_DATE_COLUMN = 1;         // 提醒日期列索引
    private static final int BG_COLOR_ID_COLUMN = 2;          // 背景颜色列索引
    private static final int CREATED_DATE_COLUMN = 3;         // 创建日期列索引
    private static final int HAS_ATTACHMENT_COLUMN = 4;       // 附件列索引
    private static final int MODIFIED_DATE_COLUMN = 5;        // 修改日期列索引
    private static final int NOTES_COUNT_COLUMN = 6;          // 笔记数量列索引
    private static final int PARENT_ID_COLUMN = 7;             // 父项ID列索引
    private static final int SNIPPET_COLUMN = 8;              // 摘要列索引
    private static final int TYPE_COLUMN = 9;                 // 类型列索引
    private static final int WIDGET_ID_COLUMN = 10;           // 小部件ID列索引
    private static final int WIDGET_TYPE_COLUMN = 11;         // 小部件类型列索引

    /* 笔记数据字段 */
    private final long mId;                // 笔记唯一ID
    private final long mAlertDate;         // 提醒时间戳
    private final int mBgColorId;         // 背景颜色资源ID
    private final long mCreatedDate;      // 创建时间戳
    private final boolean mHasAttachment;  // 是否有附件
    private final long mModifiedDate;      // 最后修改时间戳
    private final int mNotesCount;         // 包含的笔记数量（文件夹用）
    private final long mParentId;          // 父文件夹ID
    private String mSnippet;              // 笔记内容摘要
    private final int mType;              // 笔记类型（笔记/文件夹等）
    private final int mWidgetId;          // 关联的小部件ID
    private final int mWidgetType;        // 小部件类型

    /* 联系人相关字段 */
    private String mName;                 // 联系人姓名（通话记录用）
    private String mPhoneNumber;          // 电话号码（通话记录用）

    /* 位置状态标识 */
    private boolean mIsLastItem;           // 是否是列表最后一项
    private boolean mIsFirstItem;          // 是否是列表第一项
    private boolean mIsOnlyOneItem;       // 是否是唯一一项
    private boolean mIsOneNoteFollowingFolder;  // 是否是单个笔记跟随文件夹
    private boolean mIsMultiNotesFollowingFolder; // 是否是多个笔记跟随文件夹

    /**
     * 构造函数，从游标初始化笔记数据
     * @param context 上下文对象
     * @param cursor 数据库查询结果游标
     */
    public NoteItemData(Context context, Cursor cursor) {
        // 从游标读取各列数据
        mId = cursor.getLong(ID_COLUMN);
        mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN);
        mBgColorId = cursor.getInt(BG_COLOR_ID_COLUMN);
        mCreatedDate = cursor.getLong(CREATED_DATE_COLUMN);
        // 将整型转换为布尔值
        mHasAttachment = (cursor.getInt(HAS_ATTACHMENT_COLUMN)  > 0);
        mModifiedDate = cursor.getLong(MODIFIED_DATE_COLUMN);
        mNotesCount = cursor.getInt(NOTES_COUNT_COLUMN);
        mParentId = cursor.getLong(PARENT_ID_COLUMN);
        // 处理内容摘要，移除复选框标记
        mSnippet = cursor.getString(SNIPPET_COLUMN);
        mSnippet = mSnippet.replace(NoteEditActivity.TAG_CHECKED,  "").replace(
                NoteEditActivity.TAG_UNCHECKED, "");
        mType = cursor.getInt(TYPE_COLUMN);
        mWidgetId = cursor.getInt(WIDGET_ID_COLUMN);
        mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN);

        // 初始化通话记录相关信息
        mPhoneNumber = "";
        if (mParentId == Notes.ID_CALL_RECORD_FOLDER) {
            // 如果是通话记录文件夹中的笔记，获取电话号码
            mPhoneNumber = DataUtils.getCallNumberByNoteId(context.getContentResolver(),  mId);
            if (!TextUtils.isEmpty(mPhoneNumber))  {
                // 根据电话号码获取联系人姓名
                mName = Contact.getContact(context,  mPhoneNumber);
                if (mName == null) {
                    mName = mPhoneNumber;  // 如果没有联系人信息，显示号码
                }
            }
        }

        // 确保姓名不为null
        if (mName == null) {
            mName = "";
        }

        // 检查当前项在列表中的位置状态
        checkPostion(cursor);
    }

    /**
     * 检查当前项在列表中的位置状态
     * @param cursor 数据库游标
     */
    private void checkPostion(Cursor cursor) {
        mIsLastItem = cursor.isLast();      // 是否是最后一项
        mIsFirstItem = cursor.isFirst();    // 是否是第一项
        mIsOnlyOneItem = (cursor.getCount()  == 1);  // 是否是唯一一项
        mIsMultiNotesFollowingFolder = false;
        mIsOneNoteFollowingFolder = false;

        // 如果是笔记类型且不是第一项，检查前一项是否是文件夹
        if (mType == Notes.TYPE_NOTE && !mIsFirstItem) {
            int position = cursor.getPosition();
            if (cursor.moveToPrevious())  {  // 移动到前一项
                int prevType = cursor.getInt(TYPE_COLUMN);
                // 前一项是文件夹或系统文件夹
                if (prevType == Notes.TYPE_FOLDER || prevType == Notes.TYPE_SYSTEM) {
                    // 判断是多个还是一个笔记跟随文件夹
                    if (cursor.getCount()  > (position + 1)) {
                        mIsMultiNotesFollowingFolder = true;
                    } else {
                        mIsOneNoteFollowingFolder = true;
                    }
                }
                // 移动回原来的位置
                if (!cursor.moveToNext())  {
                    throw new IllegalStateException("cursor move to previous but can't move back");
                }
            }
        }
    }

    /* ========== 以下是各种访问方法 ========== */

    public boolean isOneFollowingFolder() {
        return mIsOneNoteFollowingFolder;  // 是否是单个笔记跟随文件夹
    }

    public boolean isMultiFollowingFolder() {
        return mIsMultiNotesFollowingFolder; // 是否是多个笔记跟随文件夹
    }

    public boolean isLast() {
        return mIsLastItem;  // 是否是最后一项
    }

    public String getCallName() {
        return mName;  // 获取联系人姓名
    }

    public boolean isFirst() {
        return mIsFirstItem;  // 是否是第一项
    }

    public boolean isSingle() {
        return mIsOnlyOneItem;  // 是否是唯一一项
    }

    public long getId() {
        return mId;  // 获取笔记ID
    }

    public long getAlertDate() {
        return mAlertDate;  // 获取提醒时间
    }

    public long getCreatedDate() {
        return mCreatedDate;  // 获取创建时间
    }

    public boolean hasAttachment() {
        return mHasAttachment;  // 是否有附件
    }

    public long getModifiedDate() {
        return mModifiedDate;  // 获取修改时间
    }

    public int getBgColorId() {
        return mBgColorId;  // 获取背景颜色ID
    }

    public long getParentId() {
        return mParentId;  // 获取父文件夹ID
    }

    public int getNotesCount() {
        return mNotesCount;  // 获取包含的笔记数量
    }

    public long getFolderId() {
        return mParentId;  // 获取文件夹ID（与getParentId相同）
    }

    public int getType() {
        return mType;  // 获取笔记类型
    }

    public int getWidgetType() {
        return mWidgetType;  // 获取小部件类型
    }

    public int getWidgetId() {
        return mWidgetId;  // 获取小部件ID
    }

    public String getSnippet() {
        return mSnippet;  // 获取内容摘要
    }

    public boolean hasAlert() {
        return (mAlertDate > 0);  // 是否有提醒
    }

    public boolean isCallRecord() {
        // 是否是通话记录（在通话记录文件夹中且有号码）
        return (mParentId == Notes.ID_CALL_RECORD_FOLDER && !TextUtils.isEmpty(mPhoneNumber));
    }

    /**
     * 静态方法：从游标获取笔记类型
     * @param cursor 数据库游标
     * @return 笔记类型
     */
    public static int getNoteType(Cursor cursor) {
        return cursor.getInt(TYPE_COLUMN);
    }
}