using System;
using System.Threading;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BTS.Trac;
using BTS.Trac.Forms;
using BTS.Trac.Forms.Helper;
using CookComputing.XmlRpc;

namespace TaskTrayTrac
{
    public partial class FormViewTicket : Form
    {
        /// <summary>
        /// チケット更新
        /// </summary>
        public delegate void UpdateTicketProc();
        public UpdateTicketProc UpdateTicket;

        /// <summary>
        /// チケット一覧
        /// </summary>
        List<Ticket> Tickets = null;

        /// <summary>
        /// オプション
        /// </summary>
        private TaskTrayTracOption Option = null;

        /// <summary>
        /// 閉じるフラグ
        /// </summary>
        private bool IsAppCloseed = false;

        /// <summary>
        /// メニューの表示中
        /// </summary>
        public bool IsMenuShown
        {
            get;
            private set;
        }

        /// <summary>
        /// 選択されたタブのリストを取得する
        /// </summary>
        private ListView SelectedList
        {
            get
            {
                return (tabTicketView.SelectedIndex == 0) ? listTicket : listMyTicket;
            }
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public FormViewTicket()
        {
            InitializeComponent();

            IsMenuShown = false;
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="Tickets"></param>
        /// <param name="Option"></param>
        public FormViewTicket( List<Ticket> Tickets, TaskTrayTracOption Option )
            : this()
        {
            this.Tickets = Tickets;
            this.Option = Option;

            // 表示更新
            UpdateTicketView();
        }

        /// <summary>
        /// モードレスダイアログの表示
        /// </summary>
        /// <param name="Tickets"></param>
        /// <param name="Option"></param>
        public void Show( List<Ticket> Tickets, TaskTrayTracOption Option )
        {
            this.Tickets = Tickets;
            this.Option = Option;

            Show();

            // 表示更新
            UpdateTicketView();
        }

        /// <summary>
        /// チケットの表示更新
        /// </summary>
        /// <param name="Tickets"></param>
        public void UpdateTicketView( List<Ticket> Tickets, TaskTrayTracOption Option )
        {
            this.Tickets = Tickets;
            this.Option = Option;

            UpdateTicketView();
        }

        /// <summary>
        /// 表示更新
        /// </summary>
        private void UpdateTicketView()
        {
            Text = Option.SelectedAccount.ProjectName + " : チケットの一覧";

            listTicket.Clear();
            listMyTicket.Clear();
            foreach ( Ticket ticket in Tickets ) {
                // すべてのチケットをリストする
                listTicket.Add( ticket );

                // 自分が担当のチケットをリストする
                if ( ticket.Owner == Option.SelectedAccount.UserName ) {
                    listMyTicket.Add( ticket );
                }
            }
        }

        /// <summary>
        /// チケットの作成
        /// </summary>
        private void CreateTicket()
        {
            FormTicket formTicket = new FormTicket( Option.SelectedAccount.ProjectName );
            DialogResult ret = formTicket.ShowDialog();
            if ( ret == DialogResult.OK ) {
                UpdateTicket();
            }
        }

        /// <summary>
        /// チケットの編集
        /// </summary>
        private void EditTicket()
        {
            if ( SelectedList.SelectedIndices.Count == 0 ) {
                return;
            }

            // 選択行の2番目(ID)を取得
            int selectedIndex = SelectedList.SelectedIndices[0];
            int id = int.Parse( SelectedList.SelectedItems[0].SubItems[1].Text );
            Ticket selectedTicket = null;
            foreach ( Ticket ticket in Tickets ) {
                if ( ticket.ID == id ) {
                    selectedTicket = ticket;
                    break;
                }
            }

            FormTicket formTicket = new FormTicket( selectedTicket, Option.SelectedAccount.ProjectName );
            DialogResult ret = formTicket.ShowDialog();
            if ( ret == DialogResult.OK ) {
                UpdateTicket();
            }
        }

        #region イベントハンドラ
        /// <summary>
        /// 閉じるボタン
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonClose_Click( object sender, EventArgs e )
        {
            Hide();
        }

        /// <summary>
        /// 削除ボタン
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonDelete_Click( object sender, EventArgs e )
        {
            try {
                if ( SelectedList.CheckedItems.Count != 0 ) {
                    foreach ( ListViewItem item in SelectedList.CheckedItems ) {
                        Ticket.Deleet( int.Parse( item.SubItems[1].Text ) );
                    }

                    UpdateTicket();
                }
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
        }

        /// <summary>
        /// フォームのロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormViewTicket_Load( object sender, EventArgs e )
        {

        }

        /// <summary>
        /// フォームを閉じる
        /// </summary>
        public void FormClose()
        {
            IsAppCloseed = true;
            Close();
        }

        /// <summary>
        /// 更新ボタン
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonUpdate_Click( object sender, EventArgs e )
        {
            try {
                UpdateTicket();
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
        }

        /// <summary>
        /// 編集ボタン
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonEdit_Click( object sender, EventArgs e )
        {
            try {
                EditTicket();
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
        }

        /// <summary>
        /// 作成ボタン
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonCreate_Click( object sender, EventArgs e )
        {
            try {
                IsMenuShown = true;
                CreateTicket();
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
            finally {
                IsMenuShown = false;
            }
        }

        /// <summary>
        /// <summary>
        /// 更新メニュー
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RightClickMenu_Update_Click( object sender, EventArgs e )
        {
            try {
                UpdateTicket();
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
        }

        /// <summary>
        /// 作成メニュー
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RightClickMenu_Create_Click( object sender, EventArgs e )
        {
            try {
                CreateTicket();
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
        }

        /// 編集メニュー
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RightClickMenu_Edit_Click( object sender, EventArgs e )
        {
            try {
                IsMenuShown = true;
                EditTicket();
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
            finally {
                IsMenuShown = false;
            }
        }

        /// <summary>
        /// Trac のサイトへ移動メニュー
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RightClickMenu_TracSite_Click( object sender, EventArgs e )
        {
            try {
                if ( SelectedList.SelectedIndices.Count == 0 ) {
                    return;
                }

                // 選択チケットの URL を開く
                int selectedIndex = SelectedList.SelectedIndices[0];
                Process.Start( Trac.Url + "/ticket/" + Tickets[selectedIndex].ID.ToString() );
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
        }

        /// <summary>
        /// 右クリックメニューが開くときに呼ばれる
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void rightClickMenu_Opening( object sender, CancelEventArgs e )
        {
            try {
                // リストが選択されていなければ選択できないメニュー
                bool visible = SelectedList.SelectedIndices.Count != 0;
                RightClickMenu_TracSite.Visible = visible;
                RightClickMenu_Edit.Visible = visible;
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
        }

        /// <summary>
        /// チェック状態を反転する
        /// </summary>
        private void ChangeCheckState( ListView sender, ColumnClickEventArgs e )
        {
            // いちばん上のチェック状態から反転させる
            if ( (sender.Items.Count != 0) && (e.Column == 0) ) {
                bool isChecked = !sender.Items[0].Checked;
                foreach ( ListViewItem item in sender.Items ) {
                    item.Checked = isChecked;
                }
            }
        }

        /// <summary>
        /// フォームを閉じるときに呼ばれる
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormViewTicket_FormClosing( object sender, FormClosingEventArgs e )
        {
            if ( !IsAppCloseed ) {
                e.Cancel = true;
                Hide();
            }
        }

        /// <summary>
        /// 表示状態の変更
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormViewTicket_VisibleChanged( object sender, EventArgs e )
        {
            try {
                Form form = (Form)sender;
                if ( form.Visible ) {
                    // カラムの更新
                    TicketListView.UpdateTicketColumn();
                }
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
        }
        #endregion

        #region チケットリストビューのイベント
        /// <summary>
        /// リストがダブルクリックされた
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listTicket_MouseDoubleClick( object sender, MouseEventArgs e )
        {
            try {
                EditTicket();
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
        }

        /// <summary>
        /// カラムをクリックしたときに呼ばれる
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listTicket_ColumnClick( object sender, ColumnClickEventArgs e )
        {
            try {
                ChangeCheckState( sender as ListView, e );
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, FormTracTaskTray.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
        }
        #endregion
    }
}
