using System;
using System.IO;
using System.Windows.Forms;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using ImageConverter;
using BTS.Redmine;

namespace ExcelRedmineAddIn
{
    /// <summary>
    /// アドインクラス
    /// </summary>
    public partial class ThisAddIn
    {
        private enum CulumnIndex
        {
            Subject = 1,   // 題名
            Description,   // 説明
            Tracker,       // トラッカー
            Priority,      // 優先度
            Category,      // カテゴリ
            AttachFile,    // ファイル（フルパス）
        }

        // メニューバー、ボタン
        private const string commandBarName = "ExcelRedmineAddIn";

        private Office.CommandBar menubar = null;
        private Office.CommandBarButton btnCreateNewWookbook = null;
        private Office.CommandBarButton btnUpload = null;
        private Office.CommandBarButton btnOption = null;

        // 設定項目
        Option option = new Option();
        string optionPath = "";

        // セルの表示項目
        private string TextSubject = "題名";
        private string TextDescription = "説明";
        private string TextTracker = "トラッカー";
        private string TextPriority = "優先度";
        private string TextCategory = "カテゴリ";
        private string TextAttachFile = "ファイル";

        /// <summary>
        /// アドイン起動時にコールされる
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ThisAddIn_Startup( object sender, System.EventArgs e )
        {
            #region VSTO で生成されたコード

            this.Application = (Excel.Application)Microsoft.Office.Tools.Excel.ExcelLocale1033Proxy.Wrap(typeof(Excel.Application), this.Application);

            #endregion

            try {
                // メニューバーを追加
                menubar = Application.CommandBars.Add( commandBarName, Microsoft.Office.Core.MsoBarPosition.msoBarTop, null, false );

                // 作成ボタン
                btnCreateNewWookbook = (Office.CommandBarButton)menubar.Controls.Add( 1, missing, missing, missing, missing );
                btnCreateNewWookbook.Style = Office.MsoButtonStyle.msoButtonIcon;
                btnCreateNewWookbook.FaceId = 1;
                btnCreateNewWookbook.Tag = "ExcelRedmineAddIn1";
                btnCreateNewWookbook.Picture = ImageConverter.ImageConverter.getImage( Properties.Resources.file_add );
                btnCreateNewWookbook.TooltipText = "雛形を作成";
                btnCreateNewWookbook.Click += new Office._CommandBarButtonEvents_ClickEventHandler( CommandBarButton_CreateClick );

                // アップロードボタン
                btnUpload = (Office.CommandBarButton)menubar.Controls.Add( 1, missing, missing, missing, missing );
                btnUpload.Style = Office.MsoButtonStyle.msoButtonIcon;
                btnUpload.FaceId = 2;
                btnUpload.Tag = "ExcelRedmineAddIn2";
                btnUpload.Picture = ImageConverter.ImageConverter.getImage( Properties.Resources.upload );
                btnUpload.TooltipText = "チケットの一覧を Redmine へ送信";
                btnUpload.Click += new Office._CommandBarButtonEvents_ClickEventHandler( CommandBarButton_UploadClick );

                // 設定ボタン
                btnOption = (Office.CommandBarButton)menubar.Controls.Add( 1, missing, missing, missing, missing );
                btnOption.Style = Office.MsoButtonStyle.msoButtonIcon;
                btnOption.FaceId = 3;
                btnOption.Tag = "ExcelRedmineAddIn3";
                btnOption.Picture = ImageConverter.ImageConverter.getImage( Properties.Resources.user_edit );
                btnOption.TooltipText = "設定";
                btnOption.Click += new Office._CommandBarButtonEvents_ClickEventHandler( CommandBarButton_OptionClick );

                // 設定データを復元する
                optionPath = Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData ) + "\\Option.xml";
                if ( File.Exists( optionPath ) ) {
                    option.Load( optionPath, ref menubar );
                }
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, "ExcelRedmineAddIn", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
            }
        }

        /// <summary>
        /// アドイン終了時にコールされる
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
            // メニューバー状態を保存
            option.Save( optionPath, menubar );

            // メニューバーを削除
            menubar.Delete();
            menubar = null;
        }

        #region VSTO で生成されたコード

        /// <summary>
        /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディタで変更しないでください。
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }
        
        #endregion

        /// <summary>
        /// ひな形の作成
        /// </summary>
        /// <param name="Ctrl"></param>
        /// <param name="CancelDefault"></param>
        void CommandBarButton_CreateClick( Office.CommandBarButton Ctrl, ref bool CancelDefault )
        {
            try {
                // ワークブックの作成
                Excel.Workbook wb = this.Application.Workbooks.Add( Excel.XlWBATemplate.xlWBATWorksheet );
                Excel.Worksheet sheet = (Excel.Worksheet)wb.Sheets[1];
                sheet.Name = "インポートデータ";
                sheet.Cells.Clear();

                sheet.BeforeDoubleClick += new Excel.DocEvents_BeforeDoubleClickEventHandler( Sheet1_BeforeDoubleClick );

                // 入力項目の作成
                sheet.Cells[1, CulumnIndex.Subject] = TextSubject;
                ((Excel.Range)sheet.Cells[1, CulumnIndex.Subject]).ColumnWidth = 30;

                sheet.Cells[1, CulumnIndex.Description] = TextDescription;
                ((Excel.Range)sheet.Cells[1, CulumnIndex.Description]).ColumnWidth = 50;

                sheet.Cells[1, CulumnIndex.Tracker] = TextTracker;
                sheet.Cells[1, CulumnIndex.Priority] = TextPriority;
                sheet.Cells[1, CulumnIndex.Category] = TextCategory;

                sheet.Cells[1, CulumnIndex.AttachFile] = TextAttachFile;
                ((Excel.Range)sheet.Cells[1, CulumnIndex.AttachFile]).ColumnWidth = 100;
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, "ExcelRedmineAddIn", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
            }
        }

        /// <summary>
        /// Redmine への登録
        /// </summary>
        /// <param name="Ctrl"></param>
        /// <param name="CancelDefault"></param>
        void CommandBarButton_UploadClick( Office.CommandBarButton Ctrl, ref bool CancelDefault )
        {
            ProgressDlg progress = new ProgressDlg();

            try {
                // アクティブシートのセルを取得
                Excel.Worksheet sheet = (Excel.Worksheet)this.Application.ActiveSheet;
                if ( ((Excel.Range)sheet.Cells[1, CulumnIndex.Subject]).Text.ToString() != TextSubject ) {
                    throw new Exception( "シートの形式が正しくありません。｢雛形を作成｣ボタンを押してください。" );
                }
                Excel.Range cells = (Excel.Range)sheet.Cells;

                // チケットの登録数を取得
                int count = 0;
                for ( int i = 2; ((Excel.Range)sheet.Cells[i, CulumnIndex.Subject]).Text.ToString() != ""; ++i ) {
                    ++count;
                }
                if ( count == 0 ) {
                    throw new Exception( "チケットが入力されていません。" );
                }

                // Redmine インタフェースの作成
                if ( (option.Url == "") || (option.ApiKey == "") ||
                     (option.MailAddress == "") || (option.Project == "") ) {
                    throw new Exception( "Redmine への設定項目が不足しています。｢設定｣ボタンを押して登録してください。" );
                }

                Redmine redmine = new Redmine( option.Url, option.ApiKey, option.MailAddress );

                // プログレスバーの表示
                progress.Minimum = 0;
                progress.Maximum = count;
                progress.Show();

                // セルに入力されたチケットを Redmine へ登録する
                //  セルの 1 番目は項目なので2番目から。題名が入力されたものを有効なチケットとみなす
                for ( int i = 2; ((Excel.Range)cells[i, CulumnIndex.Subject]).Text.ToString() != ""; ++i ) {
                    progress.Text = "Redmine へ登録中 " + "(" + (i-1).ToString() +"/" + count.ToString() + ")";
                    progress.Value = progress.Value + 1;

                    Issue issue = new Issue();
                    issue.Project = option.Project;
                    issue.Subject = ((Excel.Range)cells[i, CulumnIndex.Subject]).Text.ToString();
                    issue.Description = ((Excel.Range)cells[i, CulumnIndex.Description]).Text.ToString();
                    issue.Tracker = ((Excel.Range)cells[i, CulumnIndex.Tracker]).Text.ToString();
                    issue.Priority = ((Excel.Range)cells[i, CulumnIndex.Priority]).Text.ToString();
                    issue.Category = ((Excel.Range)cells[i, CulumnIndex.Category]).Text.ToString();
                    issue.AttachFile = ((Excel.Range)cells[i, CulumnIndex.AttachFile]).Text.ToString();

                    redmine.PostIssue( issue );
                }

                progress.Close();
                MessageBox.Show( "登録が完了しました", "ExcelRedmineAddIn", MessageBoxButtons.OK, MessageBoxIcon.Information );
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, "ExcelRedmineAddIn", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
            }
            finally {
                progress.Close();
            }
        }

        /// <summary>
        /// ユーザー設定
        /// </summary>
        /// <param name="Ctrl"></param>
        /// <param name="CancelDefault"></param>
        void CommandBarButton_OptionClick( Office.CommandBarButton Ctrl, ref bool CancelDefault )
        {
            try {
                // 設定画面を表示し、変更されたら保存する
                FormOption formOption = new FormOption( option );
                DialogResult ret = formOption.ShowDialog();
                if ( ret == DialogResult.OK ) {
                    option = formOption.Option;
                    option.Save( optionPath, menubar );
                }
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message, "ExcelRedmineAddIn", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
            }
        }

        /// <summary>
        /// セルのダブルクリックイベント（ファイルオープンダイアログを開く）
        /// </summary>
        /// <param name="Target"></param>
        /// <param name="Cancel"></param>
        private void Sheet1_BeforeDoubleClick( Excel.Range Target, ref bool Cancel )
        {
            // アクティブシートのセルを取得
            Excel.Worksheet sheet = (Excel.Worksheet)this.Application.ActiveSheet;

            Excel.Range title = (Excel.Range)sheet.Cells[1, Target.Column];
            // 項目が"ファイル"の場合にダイアログを開いて選択させる
            if ( title.Text.ToString() == TextAttachFile ) {
                OpenFileDialog fdlg = new OpenFileDialog();
                DialogResult ret = fdlg.ShowDialog();
                if ( ret == DialogResult.OK ) {
                    Target.set_Value( null, fdlg.FileName );

                    // セルの入力はさせたくないので、キャンセル扱いにする
                    Cancel = true;
                }
            }
        }
    }
}
