using System;
using System.Text;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using PostCardHitsuji.DataClient.DAO;
using PostCardHitsuji.DataClient.Model;
using Hitsuji.Framework.Thread;
using Hitsuji.Framework.Utils;
using PostCardHitsuji.Global;

namespace PostCardHitsuji.Ui.RowPanel
{
    public partial class MappingLayoutPanel : BaseRowPanel
    {
        public event EventHandler OnLayoutComboDropDownEvent;
        private ToolTip personTip = new ToolTip();
        private ToolTip showDialogTip = new ToolTip();

        public List<IllustLayoutContentModel> LayoutItems
        {
            get{ return layoutItems_; }
            set
            {
                layoutItems_ = value;

                this.comboBoxLayout.DropDown -= new EventHandler(comboBoxLayout_DropDown);
                var selection = comboBoxLayout.SelectedItem;
                List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
                foreach (var layout in layoutItems_)
                    list.Add(new KeyValuePair<string, string>(layout.Id, layout.layoutName));
                comboBoxLayout.DataSource = list;
                if (selection != null && comboBoxLayout.Items.Contains(selection))
                    comboBoxLayout.SelectedItem = selection;
                this.comboBoxLayout.DropDown -= new EventHandler(comboBoxLayout_DropDown);
                this.comboBoxLayout.DropDown += new EventHandler(comboBoxLayout_DropDown);

                settingDisplay();
            }
        }
        private List<IllustLayoutContentModel> layoutItems_ = new List<IllustLayoutContentModel>();

        public MappingLayoutPanel()
        {
            InitializeComponent();
            init();
        }

        public MappingLayoutPanel(MappingLayoutContentModel model)
        {
            InitializeComponent();
            init();

            Model = model;
        }

        private void init()
        {
            comboBoxLayout.ValueMember = "key";
            comboBoxLayout.DisplayMember = "value";

            this.Load += new EventHandler(load);
            this.comboBoxLayout.DropDown += new EventHandler(comboBoxLayout_DropDown);
            this.buttonPrint.Click += new EventHandler(showPrintDialog);
        }

        private void load(object sender, EventArgs ev)
        {
            labelInfo.MouseEnter += new EventHandler(InfoLabel_MouseEnterEvent);
            labelInfo.MouseLeave += new EventHandler(InfoLabel_MouseLeaveEvent);
            comboBoxLayout.SelectedValueChanged += new EventHandler(onLayoutChanged);
        }

        /// <summary>
        /// モデルクラスが更新された時の処理
        /// </summary>
        protected override void notifyModelChanged()
        {
            settingDisplay();
        }

        /// <summary>
        /// ラベル領域に入ったらツールチップ表示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="ev"></param>
        private void InfoLabel_MouseEnterEvent(object sender, EventArgs ev)
        {
            if (model_ as PersonContentModel == null) return;
            var txt = createTipText(model_ as PersonContentModel);
            personTip.Show(txt, labelInfo);
            personTip.Active = true;
        }

        /// <summary>
        /// ラベル領域を外れたらツールチップ非表示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="ev"></param>
        private void InfoLabel_MouseLeaveEvent(object sender, EventArgs ev)
        {
            personTip.Hide(labelInfo);
        }

        /// <summary>
        /// ツールチップの文字列を生成
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private string createTipText(PersonContentModel model)
        {
            var text = new StringBuilder();
            text.AppendLine("[ＩＤ] 　")
                .AppendLine("   " + ValueUtil.tryGetString(model.Id))
                .AppendLine("[グループ] 　")
                .AppendLine("   " + ValueUtil.tryGetString(model.groupName))
                .AppendLine("[名前] 　")
                .AppendLine("   " + ValueUtil.tryGetString(model.name1))
                .AppendLine("   " + ValueUtil.tryGetString(model.name2))
                .AppendLine("   " + ValueUtil.tryGetString(model.name3))
                .AppendLine("   " + ValueUtil.tryGetString(model.name4))
                .AppendLine("[メモ]")
                .AppendLine(ValueUtil.tryGetString(model.memo));
            return text.ToString();
        }

        /// <summary>
        /// パネル表示タイプが更新された時の処理
        /// </summary>
        protected override void notifyPanelTypeChanged()
        {
            
        }

        private void onLayoutChanged(object sender, EventArgs ev)
        {
            var layoutId = ((KeyValuePair<string, string>)comboBoxLayout.SelectedItem).Key;
            System.Diagnostics.Debug.WriteLine(layoutId);
            (this.model_ as PersonContentModel).layoutId = layoutId;
            settingDisplay();

        }

        private void settingDisplay()
        {
            if (this.model_ == null) return;
            var mod = model_ as PersonContentModel;

            if (mod == null || ValueUtil.tryGetString(mod.layoutId).Equals("") || 
                layoutItems_ == null || layoutItems_.Count == 0)
            {
                pictureBoxLayout.Image = null;
                return;
            }

            comboBoxLayout.SelectedValueChanged -= new EventHandler(onLayoutChanged);
            comboBoxLayout.SelectedValue = ValueUtil.tryGetString(mod.layoutId);
            comboBoxLayout.SelectedValueChanged += new EventHandler(onLayoutChanged);

            foreach (var layout in layoutItems_)
                if (layout.Id.Equals(ValueUtil.tryGetString(mod.layoutId)))
                {
                    createLayoutWithinContent(mod, layout);
                    break;
                }
        }

        private void comboBoxLayout_DropDown(object sender, EventArgs ev)
        {
            if (OnLayoutComboDropDownEvent != null)
                OnLayoutComboDropDownEvent(this, null);

            var parameter = new IllustLayoutContentModel();
            parameter.Enable = "";
            var paramHash = new System.Collections.Hashtable();
            paramHash.Add("param", parameter);
            paramHash.Add("callback", new Action<object>(callback_Layout));
            ThreadRunner.doProcess(paramHash, doSearchLayout, "layout_search", false);
        }

        private void doSearchLayout(object paramHash)
        {
            var param = (paramHash as System.Collections.Hashtable)["param"] as IllustLayoutContentModel;
            var callback = (paramHash as System.Collections.Hashtable)["callback"] as Action<object>;
            using (var daoFactory = new DaoFactory())
            {
                try
                {
                    var resLayoutDao = (IllustLayoutDao)daoFactory.getDao<IllustLayoutContentModel>(GlobalSettings.illLayoutDao_);
                    resLayoutDao.inModel = param;
                    var resLayoutList = resLayoutDao.selectSimple(null);
                    
                    if (callback != null)
                        callback(resLayoutList);
                }
                catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show(ex.ToString());
                }
            }
        }

        private void callback_Layout(object output)
        {
            var output_ = output as List<IllustLayoutContentModel>;
            output_.Insert(0, new IllustLayoutContentModel());
            LayoutItems = output_;
        }

        private void createLayoutWithinContent(PersonContentModel person, IllustLayoutContentModel layout)
        {
            var paper = new PostCardHitsuji.Ui.Controls.NewPaperLayer2();
            paper.BackColor = Color.WhiteSmoke;
            
            foreach(var msgItem in layout.MsgItemList)
            {
                var msgModel = new MsgItemContentModel();
                msgModel.Name = msgItem.Name;
                msgModel.Enable = msgItem.Enable;
                msgModel.x = msgItem.x;
                msgModel.y = msgItem.y;
                msgModel.width = msgItem.width;
                msgModel.height = msgItem.height;
                msgModel.message = msgToDrawString(msgItem.Name);
                msgModel.isMsgDirectVertical = msgItem.isMsgDirectVertical;
                msgModel.size = msgItem.size;
                msgModel.FontColor = msgItem.FontColor;
                msgModel.fontName = msgItem.fontName;
                //レクタングル色は適当
                paper.addMsgItem(msgItem.Name, msgModel, Color.White);
            }

            paper.DrawType = Ui.Controls.NewPaperLayer2.DrawTypes.RESEIVER_LAYOUT;
            var img = paper.saveImage(true);
            pictureBoxLayout.Image = img;
            pictureBoxLayout.SizeMode = PictureBoxSizeMode.Zoom;
        }

        private void showPrintDialog(object sender, EventArgs ev)
        {
            if (comboBoxLayout.SelectedItem == null || ((KeyValuePair<string, string>)comboBoxLayout.SelectedItem).Key.Equals("-1"))
            {
                MessageBox.Show("レイアウトを選択してください。");
                return;
            }

            //印刷ダイアログを表示
            var dialog = new PrintDialog();
            dialog.Document = Global.ResourceHolder.getReseiverLayoutPrintDocument(pd_PrintPage);
            //プレビューするPrintDocumentを設定
            var result = dialog.ShowDialog(this);
            if (result == DialogResult.OK || result == DialogResult.Yes)
                dialog.Document.Print();

            //宛名レイアウトの割り当て更新
            if (MessageBox.Show("この宛先情報に、この宛名レイアウトを登録しますか？", "", MessageBoxButtons.YesNo)
                == DialogResult.Yes)
            {
                System.Diagnostics.Debug.WriteLine("DBに登録しにいく");

                using (var daoFactory = new DaoFactory())
                {
                    try
                    {
                        var updateModel = new PersonContentModel(PersonContentModel.PersonTypes.Ignore);
                        updateModel.Id = (this.model_ as PersonContentModel).Id;
                        updateModel.layoutId = (this.model_ as PersonContentModel).layoutId;

                        var personDao = (PersonDao)daoFactory.getDao<PersonContentModel>(GlobalSettings.personDao_);
                        personDao.inModel = updateModel;
                        var updateCount = personDao.updateLayoutId(null);
                        MessageBox.Show("レイアウト情報 登録完了！" + updateCount + "件");
                    }
                    catch (Exception ex)
                    {
                        System.Windows.Forms.MessageBox.Show(ex.ToString());
                    }
                }
            }
        }

        private void pd_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs ev)
        {
            //画像を描画する
            IllustLayoutContentModel layout = null;
            foreach (var layout_ in layoutItems_)
            {
                if (((KeyValuePair<string, string>)comboBoxLayout.SelectedItem).Key.Equals(layout_.Id))
                    layout = layout_;
            }
            SolidBrush fontBrush = null;
            foreach (var msgItem in layout.MsgItemList)
            {
                if (msgItem.Enable.Equals(false.ToString().ToUpper()))
                    continue;

                fontBrush = new SolidBrush(msgItem.FontColor);
                msgItem.message = msgToDrawString(msgItem.Name);
                ev.Graphics.DrawString(msgItem.isMsgDirectVertical ? msgItem.messageMirror : msgItem.message,
                    msgItem.font, 
                    new SolidBrush(msgItem.FontColor),
                    msgItem.x,
                    msgItem.y,
                    msgItem.msgFormat);
            }
            //次のページがないことを通知する
            ev.HasMorePages = false;
        }

        private string msgToDrawString(string msgItemName)
        {
            var result = "";
            var person = model_ as PersonContentModel;
            result = msgItemName.Equals(Global.GlobalSettings.RESEIVER_PRE1.Key) ? person.pre1 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_PRE2.Key) ? person.pre2 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_PRE3.Key) ? person.pre3 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_POST1.Key) ? person.post1 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_POST2.Key) ? person.post2 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_POST3.Key) ? person.post3 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_POST4.Key) ? person.post4 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_ADDRESS1.Key) ? person.address1 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_ADDRESS2.Key) ? person.address2 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_ADDRESS3.Key) ? person.address3 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_NAME1.Key) ? person.name1 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_NAME2.Key) ? person.name2 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_NAME3.Key) ? person.name3 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_NAME4.Key) ? person.name4 :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_SUFFIX1.Key) ? GlobalSettings.getNameSuffixByKey(person.namePost1) :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_SUFFIX2.Key) ? GlobalSettings.getNameSuffixByKey(person.namePost2) :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_SUFFIX3.Key) ? GlobalSettings.getNameSuffixByKey(person.namePost3) :
                     msgItemName.Equals(Global.GlobalSettings.RESEIVER_SUFFIX4.Key) ? GlobalSettings.getNameSuffixByKey(person.namePost4) :
                     result;

            if (person.Sender == null) return result;
            result = msgItemName.Equals(Global.GlobalSettings.SENDER_PRE1.Key) ? person.Sender.pre1 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_PRE2.Key) ? person.Sender.pre2 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_PRE3.Key) ? person.Sender.pre3 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_POST1.Key) ? person.Sender.post1 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_POST2.Key) ? person.Sender.post2 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_POST3.Key) ? person.Sender.post3 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_POST4.Key) ? person.Sender.post4 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_ADDRESS1.Key) ? person.Sender.address1 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_ADDRESS2.Key) ? person.Sender.address2 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_ADDRESS3.Key) ? person.Sender.address3 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_NAME1.Key) ? person.Sender.name1 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_NAME2.Key) ? person.Sender.name2 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_NAME3.Key) ? person.Sender.name3 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_NAME4.Key) ? person.Sender.name4 :
                     msgItemName.Equals(Global.GlobalSettings.SENDER_TEL.Key) ? person.Sender.tel :
                     result;
            return result;
        }

    }
}
