/*
 * 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.ui;

// 导入 Android 标准库中的类

import android.app.Activity;  // Activity 类，是所有 Android 应用的基本组件，表示单一屏幕的界面。
import android.app.AlarmManager;  // AlarmManager 类，用于设置定时事件或闹钟。
import android.app.AlertDialog;  // AlertDialog 类，用于显示对话框。
import android.app.PendingIntent;  // PendingIntent 类，表示一个未来的 Intent 操作。
import android.app.SearchManager;  // SearchManager 类，用于实现搜索功能。
import android.appwidget.AppWidgetManager;  // AppWidgetManager 类，用于操作应用小部件。
import android.content.ContentUris;  // ContentUris 类，用于构建和解析内容提供者的 URI。
import android.content.Context;  // Context 类，提供应用环境信息，常用于访问系统服务。
import android.content.DialogInterface;  // DialogInterface 类，处理对话框的交互事件。
import android.content.Intent;  // Intent 类，用于启动活动或发送广播。
import android.content.SharedPreferences;  // SharedPreferences 类，用于存储应用的首选项（键值对数据）。
import android.graphics.Paint;  // Paint 类，用于设置文本或图形的样式和颜色。
import android.os.Bundle;  // Bundle 类，用于在活动之间传递数据。
import android.preference.PreferenceManager;  // PreferenceManager 类，用于访问 SharedPreferences。
import android.text.Spannable;  // Spannable 接口，允许动态改变文本的格式。
import android.text.SpannableString;  // SpannableString 类，实现了 Spannable 接口，用于设置可变的文本。
import android.text.TextUtils;  // TextUtils 类，提供文本处理的工具方法。
import android.text.format.DateUtils;  // DateUtils 类，提供格式化日期和时间的方法。
import android.text.style.BackgroundColorSpan;  // BackgroundColorSpan 类，用于设置文本的背景颜色。
import android.util.Log;  // Log 类，用于输出日志。
import android.view.LayoutInflater;  // LayoutInflater 类，用于加载布局文件。
import android.view.Menu;  // Menu 类，用于创建和处理应用菜单。
import android.view.MenuItem;  // MenuItem 类，用于表示菜单项。
import android.view.MotionEvent;  // MotionEvent 类，用于处理触摸事件。
import android.view.View;  // View 类，所有 UI 组件的基类。
import android.view.View.OnClickListener;  // OnClickListener 接口，用于处理点击事件。
import android.view.WindowManager;  // WindowManager 类，用于管理窗口和显示。
import android.widget.CheckBox;  // CheckBox 类，表示复选框。
import android.widget.CompoundButton;  // CompoundButton 类，是一个开关类的父类，如 CheckBox 和 Switch。
import android.widget.CompoundButton.OnCheckedChangeListener;  // OnCheckedChangeListener 接口，用于处理复选框状态变化事件。
import android.widget.EditText;  // EditText 类，表示一个文本输入框。
import android.widget.ImageView;  // ImageView 类，表示显示图片的控件。
import android.widget.LinearLayout;  // LinearLayout 类，一种常用的布局管理器。
import android.widget.TextView;  // TextView 类，用于显示文本。
import android.widget.Toast;  // Toast 类，用于显示短暂的提示信息。

// 导入应用程序自定义的类

import net.micode.notes.R;  // 应用资源类，用于访问应用中的资源文件。
import net.micode.notes.data.Notes;  // Notes 类，可能用于表示笔记数据。
import net.micode.notes.data.Notes.TextNote;  // TextNote 类，表示文本类型的笔记。
import net.micode.notes.model.WorkingNote;  // WorkingNote 类，处理正在编辑的笔记的数据。
import net.micode.notes.model.WorkingNote.NoteSettingChangedListener;  // NoteSettingChangedListener 接口，用于监听笔记设置的变化。
import net.micode.notes.tool.DataUtils;  // DataUtils 类，提供与数据相关的工具方法。
import net.micode.notes.tool.ResourceParser;  // ResourceParser 类，用于解析资源。
import net.micode.notes.tool.ResourceParser.TextAppearanceResources;  // TextAppearanceResources 类，用于处理文本外观资源。
import net.micode.notes.ui.DateTimePickerDialog.OnDateTimeSetListener;  // DateTimePickerDialog.OnDateTimeSetListener 接口，用于监听日期时间选择器的设置事件。
import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener;  // OnTextViewChangeListener 接口，用于监听文本框内容变化的事件。
import net.micode.notes.widget.NoteWidgetProvider_2x;  // NoteWidgetProvider_2x 类，表示2x大小的笔记小部件。
import net.micode.notes.widget.NoteWidgetProvider_4x;  // NoteWidgetProvider_4x 类，表示4x大小的笔记小部件。

// 导入 Java 标准库中的类

import java.util.HashMap;  // HashMap 类，用于存储键值对。
import java.util.HashSet;  // HashSet 类，用于存储唯一元素的集合。
import java.util.Map;  // Map 接口，表示键值对映射。
import java.util.regex.Matcher;  // Matcher 类，用于处理正则表达式的匹配。
import java.util.regex.Pattern;  // Pattern 类，用于定义正则表达式模式。


// 定义 NoteEditActivity 类，继承自 Activity 类，且实现了三个接口
public class NoteEditActivity extends Activity implements OnClickListener,
        NoteSettingChangedListener, OnTextViewChangeListener {

    // 内部类：HeadViewHolder，用于存放活动页面中头部视图的组件（如修改时间、提醒图标等）
    private class HeadViewHolder {
        public TextView tvModified;  // 显示修改时间的 TextView
        public ImageView ivAlertIcon;  // 显示提醒图标的 ImageView
        public TextView tvAlertDate;  // 显示提醒日期的 TextView
        public ImageView ibSetBgColor;  // 设置背景颜色的 ImageView
    }

    // 静态常量：存储背景颜色选择按钮与颜色资源之间的映射关系
    private static final Map<Integer, Integer> sBgSelectorBtnsMap = new HashMap<Integer, Integer>();
    static {
        // 映射按钮 ID 到颜色资源（如黄色背景对应黄色资源）
        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 之间的映射关系
    private static final Map<Integer, Integer> sBgSelectorSelectionMap = new HashMap<Integer, Integer>();
    static {
        // 映射颜色资源到选中按钮 ID（如黄色背景选中时，显示黄色选中图标）
        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);
    }

    // 静态常量：存储字体大小选择按钮与字体大小资源之间的映射关系
    private static final Map<Integer, Integer> sFontSizeBtnsMap = new HashMap<Integer, Integer>();
    static {
        // 映射字体大小选择按钮 ID 到字体大小资源（如大号字体对应大号字体资源）
        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 之间的映射关系
    private static final Map<Integer, Integer> sFontSelectorSelectionMap = new HashMap<Integer, Integer>();
    static {
        // 映射字体大小资源到选中按钮 ID（如大号字体选中时，显示大号选中图标）
        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);
    }



   // 定义 TAG 常量，用于日志调试时标记当前 Activity
private static final String TAG = "NoteEditActivity";

// 定义一个变量用于存储头部视图的引用
private HeadViewHolder mNoteHeaderHolder;

// 定义一个视图变量，用于存储头部视图面板（例如，包含背景色选择和字体大小选择的区域）
private View mHeadViewPanel;

// 定义一个视图变量，用于存储背景颜色选择器
private View mNoteBgColorSelector;

// 定义一个视图变量，用于存储字体大小选择器
private View mFontSizeSelector;

// 定义一个 EditText 变量，用于存储笔记编辑器的引用，用户输入文本的地方
private EditText mNoteEditor;

// 定义一个视图变量，用于存储编辑器面板（通常是 EditText 的外部容器）
private View mNoteEditorPanel;

// 定义一个 WorkingNote 变量，用于存储当前正在编辑的笔记对象
private WorkingNote mWorkingNote;

// 定义 SharedPreferences 变量，用于存储和获取用户设置的首选项
private SharedPreferences mSharedPrefs;

// 存储当前字体大小 ID，通常是表示字体大小的标识符
private int mFontSizeId;

// 定义一个常量，用于存储字体大小设置的偏好键
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 = String.valueOf('\u221A');

// 定义常量：表示复选框未选中的符号
public static final String TAG_UNCHECKED = String.valueOf('\u25A1');

// 定义一个 LinearLayout 变量，用于存储编辑框列表的布局引用
private LinearLayout mEditTextList;

// 定义一个 String 变量，用于存储用户的查询文本
private String mUserQuery;

// 定义一个 Pattern 变量，用于存储正则表达式模式，用于匹配用户查询中的内容
private Pattern mPattern;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 设置当前 Activity 的布局
    this.setContentView(R.layout.note_edit);

    // 如果没有保存状态且初始化活动状态失败，则结束当前 Activity
    if (savedInstanceState == null && !initActivityState(getIntent())) {
        finish();
        return;
    }
    // 初始化相关资源（如字体大小、背景色等）
    initResources();
}


    /**
     * Current activity may be killed when the memory is low. Once it is killed, for another time
     * user load this activity, we should restore the former state
     */
   @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState); // 调用父类的 onRestoreInstanceState 方法
    if (savedInstanceState != null && savedInstanceState.containsKey(Intent.EXTRA_UID)) {
        // 如果 savedInstanceState 不为空且包含 EXTRA_UID 键
        Intent intent = new Intent(Intent.ACTION_VIEW); // 创建一个 ACTION_VIEW 的 Intent 对象
        intent.putExtra(Intent.EXTRA_UID, savedInstanceState.getLong(Intent.EXTRA_UID)); // 将 EXTRA_UID 从 Bundle 中取出并放入 Intent 中
        if (!initActivityState(intent)) { // 使用 intent 初始化活动的状态
            finish(); // 如果初始化失败，结束当前 Activity
            return; // 退出方法
        }
        Log.d(TAG, "Restoring from killed activity"); // 日志输出，表示从被杀死的 Activity 中恢复
    }
}


    private boolean initActivityState(Intent intent) {
        /**
         * If the user specified the {@link Intent#ACTION_VIEW} but not provided with id,
         * then jump to the NotesListActivity
         */
        mWorkingNote = null;
        if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) {  
            // 获取笔记ID，如果没有提供ID则默认为0
            long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0);
            mUserQuery = "";// 用户的查询字符串

            /**
             * Starting from the searched result
             */
        if (intent.hasExtra(SearchManager.EXTRA_DATA_KEY)) {
                noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
                mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY);
                // 获取用户的查询字符串
            }

             // 检查笔记是否存在于数据库中
        if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) {
            // 如果笔记不存在，跳转到NotesListActivity（笔记列表页面）
            Intent jump = new Intent(this, NotesListActivity.class);
            startActivity(jump);
            showToast(R.string.error_note_not_exist); // 显示笔记不存在的提示
            finish(); // 关闭当前活动
            return false; // 返回false，表示初始化失败
        } else {
            // 如果笔记存在，加载笔记
            mWorkingNote = WorkingNote.load(this, noteId);
            if (mWorkingNote == null) {
                Log.e(TAG, "load note failed with note id" + noteId); // 如果加载失败，记录错误日志
                finish(); // 关闭当前活动
                return false; // 返回false，表示初始化失败
            }
        }
         // 设置输入法的显示方式，隐藏输入法并调整布局
            getWindow().setSoftInputMode(
                    WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
                            | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        } else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) {
            // 如果Intent的action是 ACTION_INSERT_OR_EDIT（插入或编辑）
            // New note
            long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0);
            // 获取小部件ID
            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);
            // 获取背景资源ID
            int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID,
                    ResourceParser.getDefaultBgId(this));

            // Parse call-record note
        String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
        long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0);
        if (callDate != 0 && phoneNumber != null) {
            if (TextUtils.isEmpty(phoneNumber)) {
                Log.w(TAG, "The call record number is null"); // 如果电话号码为空，记录警告日志
            }
            long noteId = 0;
            // 查找是否已有对应的通话记录笔记
            if ((noteId = DataUtils.getNoteIdByPhoneNumberAndCallDate(getContentResolver(),
                    phoneNumber, callDate)) > 0) {
                mWorkingNote = WorkingNote.load(this, noteId);
                if (mWorkingNote == null) {
                    Log.e(TAG, "load call note failed with note id" + noteId); // 如果加载失败，记录错误日志
                    finish(); // 关闭当前活动
                    return false; // 返回false，表示初始化失败
                }
            } 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_ADJUST_RESIZE
                        | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    } else {
        // 如果Intent的action不在预期的类型中，记录错误并关闭活动
        Log.e(TAG, "Intent not specified action, should not support");
        finish(); // 关闭当前活动
        return false; // 返回false，表示初始化失败
    }

    // 设置工作笔记的状态监听器
    mWorkingNote.setOnSettingStatusChangedListener(this);

    // 返回true，表示初始化成功
    return true;
}

@Override
protected void onResume() {
    super.onResume();
    // 在活动恢复时初始化笔记屏幕
    initNoteScreen();
}


 private void initNoteScreen() {
    // 设置编辑器字体的样式，字体大小由 mFontSizeId 决定
    mNoteEditor.setTextAppearance(this, TextAppearanceResources
            .getTexAppearanceResource(mFontSizeId));
    
    // 检查当前笔记是否是待办事项模式（CheckList 模式）
    if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
        // 如果是待办事项模式，切换到列表模式
        switchToListMode(mWorkingNote.getContent());
    } else {
        // 否则，将笔记内容中的查询结果进行高亮处理并显示
        mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
        // 设置光标定位到文本的末尾
        mNoteEditor.setSelection(mNoteEditor.getText().length());
    }
    
    // 隐藏所有背景选择器的视图
    for (Integer id : sBgSelectorSelectionMap.keySet()) {
        findViewById(sBgSelectorSelectionMap.get(id)).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));
        /**
         * TODO: Add the menu for setting alert. Currently disable it because the DateTimePicker
         * is not ready
         */
        showAlertHeader();
 }   

   // 显示提醒信息的头部内容
private void showAlertHeader() {
    // 检查工作笔记是否有设定提醒
    if (mWorkingNote.hasClockAlert()) {
        // 获取当前系统时间
        long time = System.currentTimeMillis();
        // 如果当前时间已经超过设定的提醒时间，则显示“提醒已过期”
        if (time > mWorkingNote.getAlertDate()) {
            mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired);
        } else {
            // 否则显示相对时间（例如：1分钟之前，3小时之前等）
            mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString(
                    mWorkingNote.getAlertDate(), time, 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);
    }
};

// 当新 Intent 被传递进来时，重新初始化活动状态
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    // 初始化活动的状态
    initActivityState(intent);
}

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        /**
         * For new note without note id, we should firstly save it to
         * generate a id. If the editing note is not worth saving, there
         * is no id which is equivalent to create new note
         */
        if (!mWorkingNote.existInDatabase()) {
            saveNote();
        }
        outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId());
        Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState");
    }

 @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    // 判断笔记背景色选择器（mNoteBgColorSelector）是否可见，并且触摸事件是否发生在其区域外
    if (mNoteBgColorSelector.getVisibility() == View.VISIBLE
            && !inRangeOfView(mNoteBgColorSelector, ev)) {
        // 如果触摸事件发生在背景色选择器的区域外，则将其隐藏
        mNoteBgColorSelector.setVisibility(View.GONE);
        return true;  // 返回true，表示该事件已经被处理，不再向下传递
    }

    // 判断字体大小选择器（mFontSizeSelector）是否可见，并且触摸事件是否发生在其区域外
    if (mFontSizeSelector.getVisibility() == View.VISIBLE
            && !inRangeOfView(mFontSizeSelector, ev)) {
        // 如果触摸事件发生在字体大小选择器的区域外，则将其隐藏
        mFontSizeSelector.setVisibility(View.GONE);
        return true;  // 返回true，表示该事件已经被处理，不再向下传递
    }

    // 如果上述两个条件都不满足，则交由父类处理触摸事件
    return super.dispatchTouchEvent(ev);
}

/**
 * 判断触摸事件是否发生在指定视图（view）区域内
 * @param view 要判断的视图
 * @param ev 触摸事件
 * @return 如果触摸点在视图内，返回true；否则返回false
 */
private boolean inRangeOfView(View view, MotionEvent ev) {
    // 获取视图在屏幕上的位置
    int[] location = new int[2];
    view.getLocationOnScreen(location);
    int x = location[0];
    int y = location[1];

    // 判断触摸事件的坐标是否在视图的区域内
    if (ev.getX() < x
            || ev.getX() > (x + view.getWidth())
            || ev.getY() < y
            || ev.getY() > (y + view.getHeight())) {
        return false;  // 触摸点在视图外部，返回false
    }
    return true;  // 触摸点在视图内部，返回true
}

private void initResources() {
    // 查找并初始化笔记标题视图
    mHeadViewPanel = findViewById(R.id.note_title);
    mNoteHeaderHolder = new HeadViewHolder();

    // 初始化并绑定各个视图控件
    mNoteHeaderHolder.tvModified = (TextView) findViewById(R.id.tv_modified_date); // 显示修改日期的TextView
    mNoteHeaderHolder.ivAlertIcon = (ImageView) findViewById(R.id.iv_alert_icon); // 显示提醒图标的ImageView
    mNoteHeaderHolder.tvAlertDate = (TextView) findViewById(R.id.tv_alert_date); // 显示提醒日期的TextView
    mNoteHeaderHolder.ibSetBgColor = (ImageView) findViewById(R.id.btn_set_bg_color); // 设置背景色的按钮（ImageView）

    // 为设置背景色的按钮设置点击监听器
    mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this);

    // 初始化笔记编辑区域的控件
    mNoteEditor = (EditText) findViewById(R.id.note_edit_view); // 编辑笔记内容的EditText
    mNoteEditorPanel = findViewById(R.id.sv_note_edit); // 包含笔记编辑区域的滚动视图

    // 初始化背景色选择器视图
    mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector);

    // 遍历背景色选择按钮并为每个按钮设置点击事件监听器
    for (int id : sBgSelectorBtnsMap.keySet()) {
        ImageView iv = (ImageView) findViewById(id);
        iv.setOnClickListener(this);
    }

    // 初始化字体大小选择器视图
    mFontSizeSelector = findViewById(R.id.font_size_selector);

    // 遍历字体大小选择按钮并为每个按钮设置点击事件监听器
    for (int id : sFontSizeBtnsMap.keySet()) {
        View view = findViewById(id);
        view.setOnClickListener(this);
    }

    // 获取默认共享偏好设置
    mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);

    // 获取用户设置的字体大小ID，如果没有设置则使用默认值
    mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE);

        /**
         * HACKME: Fix bug of store the resource id in shared preference.
         * The id may larger than the length of resources, in this case,
         * return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE}
         */
        if (mFontSizeId >= TextAppearanceResources.getResourcesSize()) {
        mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE; // 如果字体ID不合法，则使用默认字体大小
    }

    // 初始化笔记编辑列表视图
    mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list);
}

   // 重写 onPause 方法，在活动暂停时保存笔记并清除设置状态
@Override
protected void onPause() {
    super.onPause();
    // 调用 saveNote() 方法保存笔记内容，若保存成功，输出日志
    if(saveNote()) {
        Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length());
    }
    // 清除设置状态（例如背景色选择器和字体大小选择器等）
    clearSettingState();
}

// 更新小部件的显示内容
private void updateWidget() {
    // 创建一个 Intent 用于通知 AppWidgetManager 更新小部件
    Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
    
    // 根据当前笔记的 widget 类型，选择相应的小部件提供者类
    if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_2X) {
        intent.setClass(this, NoteWidgetProvider_2x.class);
    } else if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_4X) {
        intent.setClass(this, NoteWidgetProvider_4x.class);
    } else {
        // 如果遇到不支持的 widget 类型，输出错误日志并返回
        Log.e(TAG, "Unspported widget type");
        return;
    }

    // 将当前小部件的 ID 传递给小部件更新的 Intent
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {
        mWorkingNote.getWidgetId()
    });

    // 发送广播通知更新小部件
    sendBroadcast(intent);
    // 设置结果为 RESULT_OK
    setResult(RESULT_OK, intent);
}

// 处理点击事件，根据不同的按钮 ID 执行不同操作
public void onClick(View v) {
    int id = v.getId();
    
    // 当点击设置背景色按钮时，显示颜色选择器
    if (id == R.id.btn_set_bg_color) {
        mNoteBgColorSelector.setVisibility(View.VISIBLE);
        // 显示当前背景色的选择框
        findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(View.VISIBLE);
    
    // 如果点击的是背景色选择按钮，更新背景色
    } else if (sBgSelectorBtnsMap.containsKey(id)) {
        // 隐藏当前的背景色选择框
        findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(View.GONE);
        // 更新笔记背景色
        mWorkingNote.setBgColorId(sBgSelectorBtnsMap.get(id));
        // 隐藏背景色选择器
        mNoteBgColorSelector.setVisibility(View.GONE);
    
    // 如果点击的是字体大小按钮，更新字体大小
    } else if (sFontSizeBtnsMap.containsKey(id)) {
        // 隐藏当前的字体大小选择框
        findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.GONE);
        // 更新字体大小
        mFontSizeId = sFontSizeBtnsMap.get(id);
        // 保存字体大小设置到 SharedPreferences 中
        mSharedPrefs.edit().putInt(PREFERENCE_FONT_SIZE, mFontSizeId).commit();
        // 显示当前字体大小的选择框
        findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
        
        // 如果当前是待办清单模式，切换到清单模式
        if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
            getWorkingText();
            switchToListMode(mWorkingNote.getContent());
        } else {
            // 否则更新笔记的字体样式
            mNoteEditor.setTextAppearance(this,
                    TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
        }
        // 隐藏字体大小选择器
        mFontSizeSelector.setVisibility(View.GONE);
    }
}

// 重写 onBackPressed 方法，返回之前保存笔记或清除设置
@Override
public void onBackPressed() {
    // 如果清除设置状态成功，则直接返回
    if(clearSettingState()) {
        return;
    }

    // 保存笔记数据
    saveNote();
    // 调用父类的 onBackPressed 方法
    super.onBackPressed();
}

// 清除设置状态的方法，关闭背景色选择器或字体大小选择器
private boolean clearSettingState() {
    // 如果背景色选择器可见，隐藏它并返回 true
    if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) {
        mNoteBgColorSelector.setVisibility(View.GONE);
        return true;
    // 如果字体大小选择器可见，隐藏它并返回 true
    } else if (mFontSizeSelector.getVisibility() == View.VISIBLE) {
        mFontSizeSelector.setVisibility(View.GONE);
        return true;
    }
    // 如果都不可见，返回 false
    return false;
}

// 当背景色发生变化时，更新界面
public void onBackgroundColorChanged() {
    // 显示当前选中的背景色选择框
    findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(View.VISIBLE);
    // 更新笔记编辑面板的背景色
    mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId());
    // 更新标题面板的背景色
    mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
}


   @Override
public boolean onPrepareOptionsMenu(Menu menu) {
    if (isFinishing()) {
        return true;  // 如果 Activity 正在销毁，直接返回不做任何操作
    }

    clearSettingState();  // 清除设置状态（这个方法实现的细节不在代码中）

    menu.clear();  // 清空当前菜单项

    // 根据当前笔记的文件夹 ID 加载不同的菜单
    if (mWorkingNote.getFolderId() == Notes.ID_CALL_RECORD_FOLDER) {
        getMenuInflater().inflate(R.menu.call_note_edit, menu);  // 如果是通话记录文件夹，加载 call_note_edit 菜单
    } else {
        getMenuInflater().inflate(R.menu.note_edit, menu);  // 否则加载普通笔记编辑菜单
    }

    // 根据笔记的检查列表模式设置菜单项的标题
    if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
        menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_normal_mode);  // 设置为普通模式
    } else {
        menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_list_mode);  // 设置为检查列表模式
    }

    // 如果笔记有提醒，隐藏提醒菜单项
    if (mWorkingNote.hasClockAlert()) {
        menu.findItem(R.id.menu_alert).setVisible(false);  // 隐藏提醒设置菜单项
    } else {
        menu.findItem(R.id.menu_delete_remind).setVisible(false);  // 否则隐藏删除提醒菜单项
    }

    return true;  // 返回 true，表示菜单准备完毕
}


   @Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu_new_note:  // 创建新笔记
            createNewNote();
            break;

        case R.id.menu_delete:  // 删除当前笔记
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle(getString(R.string.alert_title_delete));  // 设置弹窗标题
            builder.setIcon(android.R.drawable.ic_dialog_alert);  // 设置弹窗图标
            builder.setMessage(getString(R.string.alert_message_delete_note));  // 设置弹窗消息内容
            builder.setPositiveButton(android.R.string.ok,
                new DialogInterface.OnClickListener() {  // 确定按钮
                    public void onClick(DialogInterface dialog, int which) {
                        deleteCurrentNote();  // 删除当前笔记
                        finish();  // 结束当前 Activity
                    }
                });
            builder.setNegativeButton(android.R.string.cancel, null);  // 取消按钮
            builder.show();  // 显示弹窗
            break;

        case R.id.menu_font_size:  // 显示字体大小选择器
            mFontSizeSelector.setVisibility(View.VISIBLE);  // 显示字体大小选择器
            findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);  // 根据当前字体大小显示对应选项
            break;

        case R.id.menu_list_mode:  // 切换检查列表模式
            mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ?
                TextNote.MODE_CHECK_LIST : 0);  // 切换检查列表模式状态
            break;

        case R.id.menu_share:  // 分享当前笔记内容
            getWorkingText();  // 获取当前笔记内容
            sendTo(this, mWorkingNote.getContent());  // 将内容分享
            break;

        case R.id.menu_send_to_desktop:  // 将笔记发送到桌面
            sendToDesktop();  // 调用发送到桌面的方法
            break;

        case R.id.menu_alert:  // 设置提醒
            setReminder();  // 调用设置提醒的方法
            break;

        case R.id.menu_delete_remind:  // 删除提醒
            mWorkingNote.setAlertDate(0, false);  // 清除提醒日期
            break;

        default:
            break;
    }
    return true;  // 返回 true，表示菜单项被处理
}


   private void setReminder() {
    // 创建一个日期时间选择对话框，默认时间为当前时间
    DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis());
    d.setOnDateTimeSetListener(new OnDateTimeSetListener() {
    public void OnDateTimeSet(AlertDialog dialog, long date) {
            mWorkingNote.setAlertDate(date, true);  // 设置提醒日期
        }
    });
    d.show();  // 显示日期时间选择器对话框
}


    /**
     * Share note to apps that support {@link Intent#ACTION_SEND} action
     * and {@text/plain} type
     */
    private void sendTo(Context context, String info) {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.putExtra(Intent.EXTRA_TEXT, info);
        intent.setType("text/plain");
        context.startActivity(intent);
    }

   private void sendTo(Context context, String info) {
    // 创建一个新的 Intent，动作为发送数据 (ACTION_SEND)
    Intent intent = new Intent(Intent.ACTION_SEND);

    // 将要发送的文本信息放入 Intent 中
    intent.putExtra(Intent.EXTRA_TEXT, info);

    // 设置发送的数据类型为纯文本
    intent.setType("text/plain");

    // 启动一个新的活动，允许用户选择一个可以处理该 Intent 的应用（例如邮件、短信或社交媒体应用等）
    context.startActivity(intent);
}

    // Method to delete the current note from the database or move it to trash if in sync mode
private void deleteCurrentNote() {
    // Check if the current note exists in the database
    if (mWorkingNote.existInDatabase()) {
        HashSet<Long> ids = new HashSet<Long>();
        long id = mWorkingNote.getNoteId();

        // Check if the note ID is not the root folder ID
        if (id != Notes.ID_ROOT_FOLDER) {
            ids.add(id); // Add the note ID to the set for deletion
        } else {
            Log.d(TAG, "Wrong note id, should not happen");
        }

        // If not in sync mode, delete the note from the database
        if (!isSyncMode()) {
            if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) {
                Log.e(TAG, "Delete Note error");
            }
        } else {
            // If in sync mode, move the note to the trash folder instead of deleting it
            if (!DataUtils.batchMoveToFolder(getContentResolver(), ids, Notes.ID_TRASH_FOLER)) {
                Log.e(TAG, "Move notes to trash folder error, should not happens");
            }
        }
    }
    
    // Mark the note as deleted (whether actually deleted or moved to trash)
    mWorkingNote.markDeleted(true);
}

// Method to check if the app is in sync mode by checking the sync account name
private boolean isSyncMode() {
    return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0;
}

// Method to handle changes to the clock alert for a note
public void onClockAlertChanged(long date, boolean set) {
    // If the note doesn't exist in the database, save it before setting the clock alert
    if (!mWorkingNote.existInDatabase()) {
        saveNote();
    }

    // Ensure the note has a valid ID before setting the clock alert
    if (mWorkingNote.getNoteId() > 0) {
        Intent intent = new Intent(this, AlarmReceiver.class);
        // Set the URI with the note ID to uniquely identify the note
        intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId()));
        
        // Create a PendingIntent to trigger the alarm when it's time
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
        AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE));
        showAlertHeader();

        // If 'set' is true, schedule the alarm; otherwise, cancel the alarm
        if (!set) {
            alarmManager.cancel(pendingIntent);
        } else {
            alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent);
        }
    } else {
        // If the note doesn't have an ID, display an error since the user has not input any content
        Log.e(TAG, "Clock alert setting error");
        showToast(R.string.error_note_empty_for_clock);
    }
}

// Method to handle changes made to the widget, requiring a widget update
public void onWidgetChanged() {
    updateWidget();
}

// Method to handle the deletion of text from the edit text
public void onEditTextDelete(int index, String text) {
    int childCount = mEditTextList.getChildCount();

    // If there is only one child, no need to delete anything
    if (childCount == 1) {
        return;
    }

    // Loop through the remaining child views to adjust their indices
    for (int i = index + 1; i < childCount; i++) {
        // Adjust the index of the text views after the deleted item
        ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text))
                .setIndex(i - 1);
    }

    // Remove the view at the specified index
    mEditTextList.removeViewAt(index);

    // Get the reference to the edit text after deletion
    NoteEditText edit = null;
    if (index == 0) {
        edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById(R.id.et_edit_text);
    } else {
        edit = (NoteEditText) mEditTextList.getChildAt(index - 1).findViewById(R.id.et_edit_text);
    }

    // Append the text to the new edit text and set the cursor position
    int length = edit.length();
    edit.append(text);
    edit.requestFocus();
    edit.setSelection(length);
}


    public void onEditTextEnter(int index, String text) {
        /**
         * Should not happen, check for debug
         */
        if(index > mEditTextList.getChildCount()) {
        Log.e(TAG, "Index out of mEditTextList boundary, should not happen");
    }

    /**
     * 根据输入的文本和索引，获取一个新的视图项
     * getListItem() 方法应该根据索引和文本内容返回一个合适的视图（通常是一个EditText组件）
     */
    View view = getListItem(text, index);

    /**
     * 将新创建的视图添加到 mEditTextList 中，指定其位置为 index
     */
    mEditTextList.addView(view, index);

    /**
     * 获取视图中的 EditText 控件（假设它的 ID 是 et_edit_text）
     * 然后请求焦点，使其成为当前活动的输入框
     */
    NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
    edit.requestFocus();

    /**
     * 设置新获取的 EditText 控件的光标位置为 0（即文本框的最前面）
     */
    edit.setSelection(0);

    /**
     * 遍历当前列表中，索引值大于当前插入位置的所有 EditText 控件
     * 并将它们的索引值更新，确保它们在列表中的顺序正确
     */
    for (int i = index + 1; i < mEditTextList.getChildCount(); i++) {
        ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text))
                .setIndex(i);
    }
}

  // 切换到列表模式的函数
private void switchToListMode(String text) {
    // 清空现有的视图
    mEditTextList.removeAllViews();
    
    // 将输入的文本按行分割成数组
    String[] items = text.split("\n");
    
    // 用于给每个项分配索引
    int index = 0;
    
    // 遍历分割后的每一项，如果该项不为空，则添加到视图中
    for (String item : items) {
        if(!TextUtils.isEmpty(item)) {
            // 添加列表项视图
            mEditTextList.addView(getListItem(item, index));
            index++;  // 索引递增
        }
    }
    
    // 添加一个空白的列表项，通常用于空白行或末尾
    mEditTextList.addView(getListItem("", index));
    
    // 设置焦点到新添加的空白项
    mEditTextList.getChildAt(index).findViewById(R.id.et_edit_text).requestFocus();

    // 隐藏编辑器，显示列表
    mNoteEditor.setVisibility(View.GONE);
    mEditTextList.setVisibility(View.VISIBLE);
}

// 获取高亮显示查询结果的函数
private Spannable getHighlightQueryResult(String fullText, String userQuery) {
    // 创建一个可编辑的字符串，用于高亮显示
    SpannableString spannable = new SpannableString(fullText == null ? "" : fullText);
    
    // 如果查询条件不为空，则进行高亮处理
    if (!TextUtils.isEmpty(userQuery)) {
        // 编译用户的查询模式
        mPattern = Pattern.compile(userQuery);
        Matcher m = mPattern.matcher(fullText);
        int start = 0;
        
        // 查找匹配的文本，逐一进行高亮处理
        while (m.find(start)) {
            spannable.setSpan(
                new BackgroundColorSpan(this.getResources().getColor(R.color.user_query_highlight)), 
                m.start(), m.end(),
                Spannable.SPAN_INCLUSIVE_EXCLUSIVE
            );
            start = m.end();  // 更新查找起始位置
        }
    }
    
    // 返回高亮后的文本
    return spannable;
}

// 获取列表项视图的函数
private View getListItem(String item, int index) {
    // 从布局中加载一个新的列表项视图
    View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null);
    
    // 获取该视图中的编辑框控件
    final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
    // 设置文本样式
    edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
    
    // 获取复选框控件
    CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item));
    cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        // 当复选框的选中状态发生变化时，修改文本的删除线效果
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                // 选中时加上删除线效果
                edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
            } else {
                // 未选中时去掉删除线
                edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
            }
        }
    });

    // 判断列表项的状态，是否为已选中项
    if (item.startsWith(TAG_CHECKED)) {
        // 如果是已选中项，设置复选框为选中，并且加上删除线
        cb.setChecked(true);
        edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
        // 移除标记，获取真实文本内容
        item = item.substring(TAG_CHECKED.length(), item.length()).trim();
    } else if (item.startsWith(TAG_UNCHECKED)) {
        // 如果是未选中项，设置复选框为未选中，并且去除删除线
        cb.setChecked(false);
        edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
        // 移除标记，获取真实文本内容
        item = item.substring(TAG_UNCHECKED.length(), item.length()).trim();
    }

    // 设置编辑框的文本变化监听
    edit.setOnTextViewChangeListener(this);
    // 设置编辑框的索引，用于识别项
    edit.setIndex(index);
    // 设置高亮显示用户查询结果的文本
    edit.setText(getHighlightQueryResult(item, mUserQuery));
    
    // 返回配置好的视图
    return view;
}

   // 当文本内容变化时，更新相应的复选框的可见性
public void onTextChange(int index, boolean hasText) {
    if (index >= mEditTextList.getChildCount()) {
        Log.e(TAG, "Wrong index, should not happen"); // 错误日志，如果索引超出范围
        return;
    }
    // 如果有文本，显示复选框；如果没有文本，隐藏复选框
    if (hasText) {
        mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.VISIBLE);
    } else {
        mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE);
    }
}

// 处理检查列表模式的变化
public void onCheckListModeChanged(int oldMode, int newMode) {
    // 如果切换到检查列表模式
    if (newMode == TextNote.MODE_CHECK_LIST) {
        switchToListMode(mNoteEditor.getText().toString()); // 切换到列表模式
    } else {
        // 如果当前文本不为空，清除未选中的项
        if (!getWorkingText()) {
            mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ", ""));
        }
        // 设置编辑器文本为高亮显示的查询结果
        mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
        mEditTextList.setVisibility(View.GONE); // 隐藏列表视图
        mNoteEditor.setVisibility(View.VISIBLE); // 显示编辑器视图
    }
}

// 获取当前工作文本，检查是否有选中的项，并构建工作文本
private boolean getWorkingText() {
    boolean hasChecked = false; // 标记是否有选中的项
    if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
        StringBuilder sb = new StringBuilder(); // 用于构建工作文本
        for (int i = 0; i < mEditTextList.getChildCount(); i++) {
            View view = mEditTextList.getChildAt(i);
            NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); // 获取编辑框文本
            if (!TextUtils.isEmpty(edit.getText())) {
                // 如果复选框选中，标记为已检查，否则为未检查
                if (((CheckBox) view.findViewById(R.id.cb_edit_item)).isChecked()) {
                    sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n");
                    hasChecked = true; // 有选中的项
                } else {
                    sb.append(TAG_UNCHECKED).append(" ").append(edit.getText()).append("\n");
                }
            }
        }
        mWorkingNote.setWorkingText(sb.toString()); // 更新工作文本
    } else {
        mWorkingNote.setWorkingText(mNoteEditor.getText().toString()); // 设置为普通文本
    }
    return hasChecked; // 返回是否有选中的项
}

    private boolean saveNote() {
        getWorkingText();
        boolean saved = mWorkingNote.saveNote();
        if (saved) {
            /**
             * There are two modes from List view to edit view, open one note,
             * create/edit a node. Opening node requires to the original
             * position in the list when back from edit view, while creating a
             * new node requires to the top of the list. This code
             * {@link #RESULT_OK} is used to identify the create/edit state
             */
            setResult(RESULT_OK);
        }
        return saved;
    }

  private void sendToDesktop() {
    /**
     * 在发送消息到桌面之前，我们需要确保当前正在编辑的笔记已存在于数据库中。
     * 对于新笔记，首先需要保存它。
     */
    if (!mWorkingNote.existInDatabase()) {
        saveNote();  // 如果笔记不存在于数据库中，先保存笔记
    }

    // 确保笔记ID有效
    if (mWorkingNote.getNoteId() > 0) {
        Intent sender = new Intent();  // 创建一个Intent对象用于发送广播
        Intent shortcutIntent = new Intent(this, NoteEditActivity.class);  // 创建指向NoteEditActivity的Intent
        shortcutIntent.setAction(Intent.ACTION_VIEW);  // 设置Intent的动作为查看
        shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId());  // 将当前笔记的ID传递给Intent
        sender.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);  // 将shortcutIntent作为快捷方式的Intent
        sender.putExtra(Intent.EXTRA_SHORTCUT_NAME,  // 设置快捷方式的名称为笔记的内容（经过处理）
                makeShortcutIconTitle(mWorkingNote.getContent()));
        sender.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,  // 设置快捷方式的图标资源
                Intent.ShortcutIconResource.fromContext(this, R.drawable.icon_app));
        sender.putExtra("duplicate", true);  // 设置为可以创建重复的快捷方式
        sender.setAction("com.android.launcher.action.INSTALL_SHORTCUT");  // 设置广播的action为安装快捷方式
        showToast(R.string.info_note_enter_desktop);  // 显示快捷方式添加到桌面的提示
        sendBroadcast(sender);  // 发送广播，通知系统添加快捷方式
    } else {
        /**
         * 如果笔记为空，即用户没有输入任何内容，无法生成有效的笔记ID，提醒用户
         * 输入有效的内容以便创建快捷方式。
         */
        Log.e(TAG, "Send to desktop error");  // 输出日志，说明发送快捷方式失败
        showToast(R.string.error_note_empty_for_send_to_desktop);  // 显示错误信息
    }
}

private String makeShortcutIconTitle(String content) {
    content = content.replace(TAG_CHECKED, "");  // 删除已检查标记
    content = content.replace(TAG_UNCHECKED, "");  // 删除未检查标记
    // 如果笔记内容超过最大长度，则截取内容到最大长度
    return content.length() > SHORTCUT_ICON_TITLE_MAX_LEN ? content.substring(0,
            SHORTCUT_ICON_TITLE_MAX_LEN) : content;
}

private void showToast(int resId) {
    showToast(resId, Toast.LENGTH_SHORT);  // 简化的showToast调用，使用短时间显示
}

private void showToast(int resId, int duration) {
    Toast.makeText(this, resId, duration).show();  // 显示指定资源ID的Toast消息
}
}
