/*
 * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.micode.notes.model;

import android.appwidget.AppWidgetManager;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;

import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.CallNote;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.Notes.TextNote;
import net.micode.notes.tool.ResourceParser.NoteBgResources;


public class WorkingNote {
// 工作笔记的类定义

// 笔记对象
private Note mNote;
// 笔记ID
private long mNoteId;
// 笔记内容
private String mContent;
// 笔记模式
private int mMode;
// 提醒日期
private long mAlertDate;
// 修改日期
private long mModifiedDate;
// 背景颜色ID
private int mBgColorId;
// 小部件ID
private int mWidgetId;
// 小部件类型
private int mWidgetType;
// 文件夹ID
private long mFolderId;
// 上下文
private Context mContext;
// 删除标记
private boolean mIsDeleted;
// 笔记设置变更监听器
private NoteSettingChangedListener mNoteSettingStatusListener;

// 查询字符串数组
public static final String[] DATA_PROJECTION = new String[] {
    DataColumns.ID,
    DataColumns.CONTENT,
    DataColumns.MIME_TYPE,
    DataColumns.DATA1,
    DataColumns.DATA2,
    DataColumns.DATA3,
    DataColumns.DATA4,
};

// 查询字符串数组
public static final String[] NOTE_PROJECTION = new String[] {
    NoteColumns.PARENT_ID,
    NoteColumns.ALERTED_DATE,
    NoteColumns.BG_COLOR_ID,
    NoteColumns.WIDGET_ID,
    NoteColumns.WIDGET_TYPE,
    NoteColumns.MODIFIED_DATE
};

// 数据 ID 列
private static final int DATA_ID_COLUMN = 0;
// 数据内容列
private static final int DATA_CONTENT_COLUMN = 1;
// 数据 MIME 类型列
private static final int DATA_MIME_TYPE_COLUMN = 2;
// 数据模式列
private static final int DATA_MODE_COLUMN = 3;
// 笔记父ID列
private static final int NOTE_PARENT_ID_COLUMN = 0;
// 笔记提醒日期列
private static final int NOTE_ALERTED_DATE_COLUMN = 1;
// 笔记背景颜色ID列
private static final int NOTE_BG_COLOR_ID_COLUMN = 2;
// 笔记小部件ID列
private static final int NOTE_WIDGET_ID_COLUMN = 3;
// 笔记小部件类型列
private static final int NOTE_WIDGET_TYPE_COLUMN = 4;
// 笔记修改日期列
private static final int NOTE_MODIFIED_DATE_COLUMN = 5;

// 新建笔记构造函数
private WorkingNote(Context context, long folderId) {
    mContext = context;
    mAlertDate = 0;
    mModifiedDate = System.currentTimeMillis();
    mFolderId = folderId;
    mNote = new Note();
    mNoteId = 0;
    mIsDeleted = false;
    mMode = 0;
    mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
}

// 已有笔记构造函数
private WorkingNote(Context context, long noteId, long folderId) {
    mContext = context;
    mNoteId = noteId;
    mFolderId = folderId;
    mIsDeleted = false;
    mNote = new Note();
    loadNote();
}

// 载入笔记
private void loadNote() {
    Cursor cursor = mContext.getContentResolver().query(
        ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mNoteId),
        NOTE_PROJECTION,
        null,
        null,
        null);

    if (cursor != null) {
        if (cursor.moveToFirst()) {
            mFolderId = cursor.getLong(NOTE_PARENT_ID_COLUMN);
            mBgColorId = cursor.getInt(NOTE_BG_COLOR_ID_COLUMN);
            mWidgetId = cursor.getInt(NOTE_WIDGET_ID_COLUMN);
            mWidgetType = cursor.getInt(NOTE_WIDGET_TYPE_COLUMN);
            mAlertDate = cursor.getLong(NOTE_ALERTED_DATE_COLUMN);
            mModifiedDate = cursor.getLong(NOTE_MODIFIED_DATE_COLUMN);
        }
        cursor.close();
    } else {
        Log.e(TAG, "No note with id:" + mNoteId);
        throw new IllegalArgumentException("Unable to find note with id " + mNoteId);
    }
    loadNoteData();
}

// 载入笔记的数据
private void loadNoteData() {
    Cursor cursor = mContext.getContentResolver().query(
        Notes.CONTENT_DATA_URI,
        DATA_PROJECTION,
        DataColumns.NOTE_ID + "=?",
        new String[] { String.valueOf(mNoteId) },
        null);

    if (cursor != null) {
        if (cursor.moveToFirst()) {
            do {
                String type = cursor.getString(DATA_MIME_TYPE_COLUMN);
                if (DataConstants.NOTE.equals(type)) {
                    mContent = cursor.getString(DATA_CONTENT_COLUMN);
                    mMode = cursor.getInt(DATA_MODE_COLUMN);
                    mNote.setTextDataId(cursor.getLong(DATA_ID_COLUMN));
                } else if (DataConstants.CALL_NOTE.equals(type)) {
                    mNote.setCallDataId(cursor.getLong(DATA_ID_COLUMN));
                } else {
                    Log.d(TAG, "Wrong note type with type:" + type);
                }
            } while (cursor.moveToNext());
        }
        cursor.close();
    } else {
        Log.e(TAG, "No data with id:" + mNoteId);
        throw new IllegalArgumentException("Unable to find note's data with id " + mNoteId);
    }
}

// 创建空笔记
public static WorkingNote createEmptyNote(
    Context context,
    long folderId,
    int widgetId,
    int widgetType,
    int defaultBgColorId) {
    WorkingNote note = new WorkingNote(context, folderId);
    note.setBgColorId(defaultBgColorId);
    note.setWidgetId(widgetId);
    note.setWidgetType(widgetType);
    return note;
}

// 载入笔记
public static WorkingNote load(Context context, long id) {
    return new WorkingNote(context, id, 0);
}
}    

// 保存笔记
public synchronized boolean saveNote() {
    if (isWorthSaving()) {
        // 新建笔记
        if (!existInDatabase()) {
            if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {
                Log.e(TAG, "Create new note fail with id:" + mNoteId);
                return false;
            }
        }
        // 更新笔记
        mNote.syncNote(mContext, mNoteId);

        /** 
          * 如果笔记可以设置提醒，更新相关的部件
          */
        if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
                && mWidgetType != Notes.TYPE_WIDGET_INVALIDE
                && mNoteSettingStatusListener != null) {
            mNoteSettingStatusListener.onWidgetChanged();
        }
        return true;
    } else {
        return false;
    }
}

// 判断笔记是否已存在于数据库
public boolean existInDatabase() {
    return mNoteId > 0;
}

// 判断是否需要保存笔记
private boolean isWorthSaving() {
    if (mIsDeleted || (!existInDatabase() && TextUtils.isEmpty(mContent))
            || (existInDatabase() && !mNote.isLocalModified())) {
        return false;
    } else {
        return true;
    }
}

// 设置笔记状态变化的监听器
public void setOnSettingStatusChangedListener(NoteSettingChangedListener l) {
    mNoteSettingStatusListener = l;
}

// 设置提醒日期
public void setAlertDate(long date, boolean set) {
    if (date != mAlertDate) {
        mAlertDate = date;
        mNote.setNoteValue(NoteColumns.ALERTED_DATE, String.valueOf(mAlertDate));
    }
    if (mNoteSettingStatusListener != null) {
        mNoteSettingStatusListener.onClockAlertChanged(date, set);
    }
}

// 对笔记进行标记
public void markDeleted(boolean mark) {
    mIsDeleted = mark;
    if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
            && mWidgetType != Notes.TYPE_WIDGET_INVALIDE && mNoteSettingStatusListener != null) {
        mNoteSettingStatusListener.onWidgetChanged();
    }
}

// 设置背景颜色
public void setBgColorId(int id) {
    if (id != mBgColorId) {
        mBgColorId = id;
        if (mNoteSettingStatusListener != null) {
            mNoteSettingStatusListener.onBackgroundColorChanged();
        }
        mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(id));
    }
}

// 设置检查清单
public void setCheckListMode(int mode) {
    if (mMode != mode) {
        if (mNoteSettingStatusListener != null) {
            mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode);
        }
        mMode = mode;
        mNote.setTextData(TextNote.MODE, String.valueOf(mMode));
    }
}

// 设置部件类型
public void setWidgetType(int type) {
    if (type != mWidgetType) {
        mWidgetType = type;
        mNote.setNoteValue(NoteColumns.WIDGET_TYPE, String.valueOf(mWidgetType));
    }
}

// 设置部件ID
public void setWidgetId(int id) {
    if (id != mWidgetId) {
        mWidgetId = id;
        mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId));
    }
}

// 设置工作文本
public void setWorkingText(String text) {
    if (!TextUtils.equals(mContent, text)) {
        mContent = text;
        mNote.setTextData(DataColumns.CONTENT, mContent);
    }
}

// 转换成通话记录
public void convertToCallNote(String phoneNumber, long callDate) {
    mNote.setCallData(CallNote.CALL_DATE, String.valueOf(callDate));
    mNote.setCallData(CallNote.PHONE_NUMBER, phoneNumber);
    mNote.setNoteValue(NoteColumns.PARENT_ID, String.valueOf(Notes.ID_CALL_RECORD_FOLDER));
}

// 是否包含闹钟提醒
public boolean hasClockAlert() {
    return (mAlertDate > 0 ? true : false);
}

public String getContent() {
    return mContent;
}

public long getAlertDate() {
    return mAlertDate;
}

public long getModifiedDate() {
    return mModifiedDate;
}

public int getBgColorResId() {
    return NoteBgResources.getNoteBgResource(mBgColorId);
}

public int getBgColorId() {
    return mBgColorId;
}

public int getTitleBgResId() {
    return NoteBgResources.getNoteTitleBgResource(mBgColorId);
}

public int getCheckListMode() {
    return mMode;
}

public long getNoteId() {
    return mNoteId;
}

public long getFolderId() {
    return mFolderId;
}

public int getWidgetId() {
    return mWidgetId;
}

public int getWidgetType() {
    return mWidgetType;
}

// 笔记状态监听器接口
public interface NoteSettingChangedListener {
    // 当当前笔记的背景颜色已改变时调用
    void onBackgroundColorChanged();

    // 当用户设置闹钟时调用
    void onClockAlertChanged(long date, boolean set);

    // 当从部件创建笔记时调用
    void onWidgetChanged();

    // 当检查清单模式与普通模式之间切换时调用
    void onCheckListModeChanged(int oldMode, int newMode);
}
}