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

// 包声明，表明该类属于 net.micode.notes.ui 包
package net.micode.notes.ui;

// 导入 Java 标准库中的 Calendar 类，用于处理日期和时间
import java.util.Calendar;

// 导入项目中的资源类 R
import net.micode.notes.R;
// 导入自定义的 DateTimePicker 类
import net.micode.notes.ui.DateTimePicker;
// 导入自定义的 DateTimePicker 类中的 OnDateTimeChangedListener 接口
import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener;

// 导入 Android 系统的 AlertDialog 类，用于创建对话框
import android.app.AlertDialog;
// 导入 Android 系统的 Context 类，用于获取应用程序的上下文信息
import android.content.Context;
// 导入 Android 系统的 DialogInterface 类，用于处理对话框的交互事件
import android.content.DialogInterface;
// 导入 DialogInterface 中的 OnClickListener 接口，用于处理点击事件
import android.content.DialogInterface.OnClickListener;
// 导入 Android 系统的 DateFormat 类，用于格式化日期和时间
import android.text.format.DateFormat;
// 导入 Android 系统的 DateUtils 类，用于处理日期和时间的工具类
import android.text.format.DateUtils;

/**
 * DateTimePickerDialog 类继承自 AlertDialog，用于创建一个包含日期和时间选择器的对话框。
 * 该对话框允许用户选择日期和时间，并提供了回调接口 OnDateTimeSetListener 来处理用户选择的结果。
 */
public class DateTimePickerDialog extends AlertDialog implements OnClickListener {

    // 用于存储当前选择的日期和时间
    private Calendar mDate = Calendar.getInstance();
    // 标记是否使用 24 小时制显示时间
    private boolean mIs24HourView;
    // 日期和时间选择完成后的回调接口
    private OnDateTimeSetListener mOnDateTimeSetListener;
    // 自定义的日期和时间选择器视图
    private DateTimePicker mDateTimePicker;

    /**
     * OnDateTimeSetListener 接口定义了一个回调方法 OnDateTimeSet，
     * 当用户在对话框中完成日期和时间的选择并点击确定按钮时，会调用该方法。
     */
    public interface OnDateTimeSetListener {
        /**
         * 当用户选择日期和时间后，调用该方法传递选择的结果。
         * @param dialog 触发该回调的对话框实例
         * @param date 用户选择的日期和时间的毫秒数
         */
        void OnDateTimeSet(AlertDialog dialog, long date);
    }

    /**
     * 构造函数，用于创建 DateTimePickerDialog 实例。
     * @param context 应用程序的上下文信息
     * @param date 初始显示的日期和时间的毫秒数
     */
    public DateTimePickerDialog(Context context, long date) {
        // 调用父类 AlertDialog 的构造函数
        super(context);
        // 创建自定义的 DateTimePicker 实例
        mDateTimePicker = new DateTimePicker(context);
        // 将 DateTimePicker 设置为对话框的视图
        setView(mDateTimePicker);
        // 为 DateTimePicker 设置日期和时间改变的监听器
        mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() {
            /**
             * 当日期和时间发生改变时，调用该方法更新 mDate 对象，并更新对话框的标题。
             * @param view 触发事件的 DateTimePicker 视图
             * @param year 新选择的年份
             * @param month 新选择的月份
             * @param dayOfMonth 新选择的日期
             * @param hourOfDay 新选择的小时
             * @param minute 新选择的分钟
             */
            public void onDateTimeChanged(DateTimePicker view, int year, int month,
                    int dayOfMonth, int hourOfDay, int minute) {
                // 更新 mDate 对象的年份
                mDate.set(Calendar.YEAR, year);
                // 更新 mDate 对象的月份
                mDate.set(Calendar.MONTH, month);
                // 更新 mDate 对象的日期
                mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                // 更新 mDate 对象的小时
                mDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
                // 更新 mDate 对象的分钟
                mDate.set(Calendar.MINUTE, minute);
                // 调用 updateTitle 方法更新对话框的标题
                updateTitle(mDate.getTimeInMillis());
            }
        });
        // 设置 mDate 对象的时间为传入的日期和时间
        mDate.setTimeInMillis(date);
        // 将秒数设置为 0
        mDate.set(Calendar.SECOND, 0);
        // 设置 DateTimePicker 的当前日期和时间
        mDateTimePicker.setCurrentDate(mDate.getTimeInMillis());
        // 设置对话框的确定按钮，并设置点击监听器为当前类实例
        setButton(context.getString(R.string.datetime_dialog_ok), this);
        // 设置对话框的取消按钮，不设置点击监听器
        setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null);
        // 根据系统设置判断是否使用 24 小时制
        set24HourView(DateFormat.is24HourFormat(this.getContext()));
        // 调用 updateTitle 方法更新对话框的标题
        updateTitle(mDate.getTimeInMillis());
    }

    /**
     * 设置是否使用 24 小时制显示时间。
     * @param is24HourView 是否使用 24 小时制的标志
     */
    public void set24HourView(boolean is24HourView) {
        mIs24HourView = is24HourView;
    }

    /**
     * 设置日期和时间选择完成后的回调接口。
     * @param callBack 实现了 OnDateTimeSetListener 接口的回调对象
     */
    public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) {
        mOnDateTimeSetListener = callBack;
    }

    /**
     * 更新对话框的标题，显示当前选择的日期和时间。
     * @param date 当前选择的日期和时间的毫秒数
     */
    private void updateTitle(long date) {
        // 定义日期和时间格式化的标志
        int flag =
            // 显示年份
            DateUtils.FORMAT_SHOW_YEAR |
            // 显示日期
            DateUtils.FORMAT_SHOW_DATE |
            // 显示时间
            DateUtils.FORMAT_SHOW_TIME;
        // 根据是否使用 24 小时制添加相应的标志
        flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR;
        // 使用 DateUtils 格式化日期和时间，并设置为对话框的标题
        setTitle(DateUtils.formatDateTime(this.getContext(), date, flag));
    }

    /**
     * 处理对话框按钮的点击事件。
     * 当用户点击确定按钮时，调用回调接口的 OnDateTimeSet 方法传递选择的结果。
     * @param arg0 触发点击事件的 DialogInterface 实例
     * @param arg1 点击事件的标识符
     */
    public void onClick(DialogInterface arg0, int arg1) {
        // 检查回调接口是否为空
        if (mOnDateTimeSetListener != null) {
            // 调用回调接口的 OnDateTimeSet 方法传递选择的日期和时间
            mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis());
        }
    }

}