/*
 * 版权所有 (c) 2010-2011,The MiCode Open Source Community (www.micode.net)
 *
 * 本软件根据 Apache 许可证 2.0 版("许可证")发布;
 * 除非符合许可证,否则不得使用此文件。
 * 您可以在以下网址获取许可证副本:
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * 除非法律要求或书面同意,软件
 * 根据许可证分发的内容按"原样"提供,
 * 不附带任何明示或暗示的保证或条件。
 * 请参阅许可证,了解有关权限和限制的具体语言。
 */

package net.micode.notes.ui;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.SearchManager;
import android.appwidget.AppWidgetManager;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Paint;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.style.BackgroundColorSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.TextNote;
import net.micode.notes.model.WorkingNote;
import net.micode.notes.model.WorkingNote.NoteSettingChangedListener;
import net.micode.notes.tool.DataUtils;
import net.micode.notes.tool.ResourceParser;
import net.micode.notes.tool.ResourceParser.TextAppearanceResources;
import net.micode.notes.ui.DateTimePickerDialog.OnDateTimeSetListener;
import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener;
import net.micode.notes.widget.NoteWidgetProvider_2x;
import net.micode.notes.widget.NoteWidgetProvider_4x;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 笔记编辑活动(核心界面逻辑)
 * 功能:
 * 1. 支持新建/编辑文本笔记、待办事项、通话记录笔记
 * 2. 实现笔记内容编辑、格式设置(背景颜色、字体大小)
 * 3. 处理提醒设置、桌面小部件更新、快捷方式创建
 * 4. 支持列表模式(待办事项)和普通文本模式切换
 * 5. 集成搜索高亮、上下文菜单、多编辑项管理
 */
public class NoteEditActivity extends Activity implements OnClickListener,
        NoteSettingChangedListener, OnTextViewChangeListener {

    // 头部视图ViewHolder(优化UI组件访问)
    private class HeadViewHolder {
        public TextView tvModified;    // 最后修改时间
        public ImageView ivAlertIcon;  // 提醒图标
        public TextView tvAlertDate;   // 提醒时间
        public ImageView ibSetBgColor; // 设置背景颜色按钮
    }

    // 背景颜色选择按钮映射(视图ID -> 资源ID)
    private static final Map<Integer, Integer> sBgSelectorBtnsMap = new HashMap<>();
    static {
        sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW);
        sBgSelectorBtnsMap.put(R.id.iv_bg_red, ResourceParser.RED);
        sBgSelectorBtnsMap.put(R.id.iv_bg_blue, ResourceParser.BLUE);
        sBgSelectorBtnsMap.put(R.id.iv_bg_green, ResourceParser.GREEN);
        sBgSelectorBtnsMap.put(R.id.iv_bg_white, ResourceParser.WHITE);
    }

    // 背景颜色选中状态映射(资源ID -> 选中视图ID)
    private static final Map<Integer, Integer> sBgSelectorSelectionMap = new HashMap<>();
    static {
        sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select);
        sBgSelectorSelectionMap.put(ResourceParser.RED, R.id.iv_bg_red_select);
        sBgSelectorSelectionMap.put(ResourceParser.BLUE, R.id.iv_bg_blue_select);
        sBgSelectorSelectionMap.put(ResourceParser.GREEN, R.id.iv_bg_green_select);
        sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select);
    }

    // 字体大小按钮映射(视图ID -> 资源ID)
    private static final Map<Integer, Integer> sFontSizeBtnsMap = new HashMap<>();
    static {
        sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE);
        sFontSizeBtnsMap.put(R.id.ll_font_small, ResourceParser.TEXT_SMALL);
        sFontSizeBtnsMap.put(R.id.ll_font_normal, ResourceParser.TEXT_MEDIUM);
        sFontSizeBtnsMap.put(R.id.ll_font_super, ResourceParser.TEXT_SUPER);
    }

    // 字体大小选中状态映射(资源ID -> 选中视图ID)
    private static final Map<Integer, Integer> sFontSelectorSelectionMap = new HashMap<>();
    static {
        sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select);
        sFontSelectorSelectionMap.put(ResourceParser.TEXT_SMALL, R.id.iv_small_select);
        sFontSelectorSelectionMap.put(ResourceParser.TEXT_MEDIUM, R.id.iv_medium_select);
        sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select);
    }

    private static final String TAG = "NoteEditActivity";
    private HeadViewHolder mNoteHeaderHolder;         // 头部视图持有者
    private View mHeadViewPanel;                      // 头部布局
    private View mNoteBgColorSelector;                // 背景颜色选择面板
    private View mFontSizeSelector;                   // 字体大小选择面板
    private EditText mNoteEditor;                     // 普通文本编辑框
    private View mNoteEditorPanel;                    // 文本编辑背景面板
    private WorkingNote mWorkingNote;                 // 笔记数据模型
    private SharedPreferences mSharedPrefs;           // 共享偏好(存储字体大小等设置)
    private int mFontSizeId;                          // 当前字体大小资源ID
    private static final String PREFERENCE_FONT_SIZE = "pref_font_size"; // 字体大小偏好键
    private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10; // 快捷方式标题最大长度
    public static final String TAG_CHECKED = "\u221A"; // 待办事项选中标记
    public static final String TAG_UNCHECKED = "\u25A1"; // 待办事项未选中标记
    private LinearLayout mEditTextList;               // 列表模式下的编辑项容器
    private String mUserQuery;                        // 搜索查询词(用于高亮显示)
    private Pattern mPattern;                         // 搜索匹配模式

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.note_edit); // 加载编辑界面布局

        // 恢复因内存不足被销毁的活动状态
        if (savedInstanceState == null && !initActivityState(getIntent())) {
            finish();
            return;
        }
        initResources(); // 初始化UI组件和资源
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        if (savedInstanceState != null && savedInstanceState.containsKey(Intent.EXTRA_UID)) {
            // 从已保存的状态中恢复笔记ID
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.putExtra(Intent.EXTRA_UID, savedInstanceState.getLong(Intent.EXTRA_UID));
            if (!initActivityState(intent)) {
                finish();
            }
        }
    }

    /**
     * 初始化活动状态(处理打开/新建笔记逻辑)
     * @param intent 启动意图
     * @return 是否初始化成功
     */
    private boolean initActivityState(Intent intent) {
        mWorkingNote = null;
        if (TextUtils.equals(intent.getAction(), Intent.ACTION_VIEW)) {
            // 打开已有笔记
            long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0);
            mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY); // 处理搜索结果跳转

            // 检查笔记是否存在且可见
            if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) {
                showToast(R.string.error_note_not_exist);
                startActivity(new Intent(this, NotesListActivity.class));
                finish();
                return false;
            }
            mWorkingNote = WorkingNote.load(this, noteId); // 加载笔记数据
            if (mWorkingNote == null) {
                Log.e(TAG, "加载笔记失败:" + noteId);
                finish();
                return false;
            }
            // 隐藏软键盘(查看模式)
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
        } else if (TextUtils.equals(intent.getAction(), Intent.ACTION_INSERT_OR_EDIT)) {
            // 新建笔记
            long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0);
            int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
            int widgetType = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, Notes.TYPE_WIDGET_INVALIDE);
            int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, ResourceParser.getDefaultBgId(this));

            // 处理通话记录笔记(特殊类型)
            String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
            long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0);
            if (callDate != 0 && phoneNumber != null) {
                long noteId = DataUtils.getNoteIdByPhoneNumberAndCallDate(getContentResolver(), phoneNumber, callDate);
                if (noteId > 0) {
                    mWorkingNote = WorkingNote.load(this, noteId); // 加载已有通话记录笔记
                } else {
                    // 创建新的通话记录笔记
                    mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, bgResId);
                    mWorkingNote.convertToCallNote(phoneNumber, callDate);
                }
            } else {
                // 创建普通空笔记
                mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, bgResId);
            }
            // 显示软键盘(编辑模式)
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
        } else {
            Log.e(TAG, "不支持的意图操作");
            finish();
            return false;
        }
        // 注册笔记设置变化监听器
        mWorkingNote.setOnSettingStatusChangedListener(this);
        return true;
    }

    @Override
    protected void onResume() {
        super.onResume();
        initNoteScreen(); // 初始化界面显示
    }

    /**
     * 初始化界面显示(加载笔记内容和设置)
     */
    private void initNoteScreen() {
        // 应用字体大小设置
        mNoteEditor.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
        // 根据笔记类型切换显示模式
        if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
            switchToListMode(mWorkingNote.getContent()); // 列表模式(待办事项)
        } else {
            // 普通文本模式,高亮搜索词
            mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
            mNoteEditor.setSelection(mNoteEditor.getText().length()); // 光标移至末尾
        }
        // 更新背景颜色显示
        for (Integer bgId : sBgSelectorSelectionMap.keySet()) {
            findViewById(sBgSelectorSelectionMap.get(bgId)).setVisibility(View.GONE);
        }
        mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
        mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId());
        // 更新修改时间和提醒状态
        mNoteHeaderHolder.tvModified.setText(DateUtils.formatDateTime(this,
                mWorkingNote.getModifiedDate(),
                DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NUMERIC_DATE |
                        DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR));
        showAlertHeader(); // 显示提醒时间
    }

    /**
     * 显示提醒时间和图标
     */
    private void showAlertHeader() {
        if (mWorkingNote.hasClockAlert()) {
            long currentTime = System.currentTimeMillis();
            if (currentTime > mWorkingNote.getAlertDate()) {
                mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired); // 提醒已过期
            } else {
                // 显示相对时间(如“10分钟后”)
                mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString(
                        mWorkingNote.getAlertDate(), currentTime, DateUtils.MINUTE_IN_MILLIS));
            }
            mNoteHeaderHolder.tvAlertDate.setVisibility(View.VISIBLE);
            mNoteHeaderHolder.ivAlertIcon.setVisibility(View.VISIBLE);
        } else {
            mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE);
            mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE);
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        initActivityState(intent); // 处理新的启动意图(如从搜索结果重新打开)
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // 保存未存入数据库的新笔记(生成ID)
        if (!mWorkingNote.existInDatabase()) {
            saveNote();
        }
        outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId()); // 保存笔记ID
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // 点击外部区域隐藏颜色/字体选择面板
        if ((mNoteBgColorSelector.getVisibility() == View.VISIBLE || mFontSizeSelector.getVisibility() == View.VISIBLE) &&
                !inRangeOfView(mNoteBgColorSelector, ev) && !inRangeOfView(mFontSizeSelector, ev)) {
            mNoteBgColorSelector.setVisibility(View.GONE);
            mFontSizeSelector.setVisibility(View.GONE);
            return true;
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 判断触摸点是否在指定视图范围内
     * @param view 目标视图
     * @param ev 触摸事件
     * @return 是否在范围内
     */
    private boolean inRangeOfView(View view, MotionEvent ev) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        int x = location[0], y = location[1];
        return ev.getX() >= x && ev.getX() <= x + view.getWidth() &&
                ev.getY() >= y && ev.getY() <= y + view.getHeight();
    }

    /**
     * 初始化UI组件和资源
     */
    private void initResources() {
        // 头部视图组件初始化
        mHeadViewPanel = findViewById(R.id.note_title);
        mNoteHeaderHolder = new HeadViewHolder();
        mNoteHeaderHolder.tvModified = findViewById(R.id.tv_modified_date);
        mNoteHeaderHolder.ivAlertIcon = findViewById(R.id.iv_alert_icon);
        mNoteHeaderHolder.tvAlertDate = findViewById(R.id.tv_alert_date);
        mNoteHeaderHolder.ibSetBgColor = findViewById(R.id.btn_set_bg_color);
        mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this); // 设置背景颜色按钮点击监听

        // 文本编辑组件初始化
        mNoteEditor = findViewById(R.id.note_edit_view);
        mNoteEditorPanel = findViewById(R.id.sv_note_edit);
        mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector);
        // 注册背景颜色选择按钮点击监听
        for (int btnId : sBgSelectorBtnsMap.keySet()) {
            findViewById(btnId).setOnClickListener(this);
        }

        // 字体大小选择面板初始化
        mFontSizeSelector = findViewById(R.id.font_size_selector);
        for (int sizeId : sFontSizeBtnsMap.keySet()) {
            findViewById(sizeId).setOnClickListener(this);
        }
        // 加载字体大小偏好设置
        mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
        mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE);
        //