using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using nft.util;
using nft.framework;
using nft.controls;
using System.Text;
using System.Diagnostics;

namespace nft.ui.system
{
	/// <summary>
	/// Shows an exception to the user
	/// (and ask for the forgiveness :-)
	/// </summary>
	public sealed class ErrorMessageBox : System.Windows.Forms.Form
	{
		/// <summary>
		/// Displays a dialog box and returns after the dialog is closed.
		/// </summary>
		/// <param name="owner">can be null.</param>
        public static DialogResult Show(IWin32Window owner, string msg, Exception e) {
			using( Form f = new ErrorMessageBox(msg,e) ) {
                DialogResult res = f.ShowDialog(owner);
				return res;
			}
		}

		private System.Windows.Forms.Label msg;
		private UrlLinkLabel linkLabel1;
		private System.Windows.Forms.Button copyButton;
        private System.Windows.Forms.Label note;
        private Button throwButton;
        private Button abortButton;

		private readonly Exception exception;

		private ErrorMessageBox( string _msg, Exception e ) {
			this.exception = e;

			InitializeComponent();
			this.msg.Text = _msg;

			base.Icon =  SystemIcons.Error;
			icon.Image = SystemIcons.Error.ToBitmap();
            StringBuilder sb = new StringBuilder();
            if (_msg.Equals(e.Message)) {
                AppendExceptionInfo(ref sb, e);
            } else {
                sb.AppendLine(_msg);
                AppendExceptionInfo(ref sb, e);
            }
			while(true) 
			{
				e = e.InnerException;
				if(e==null)		break;
                sb.AppendLine("Caused by -->");
                AppendExceptionInfo(ref sb, e);
			}
            sb.AppendLine("-----System Information-----");
            sb.AppendLine(ConfigureService.GetSystemInfo());
            sb.AppendLine("-----PlugIn Information-----");
            if (Main.pluginManager != null) {
                sb.AppendLine(Main.pluginManager.GetInstallInfo());
            } else {
                sb.AppendLine("Plugin manager not initialized.");
            }
            detail.Text = sb.ToString();
            detail.Select(0,0);
		}

        private void AppendExceptionInfo(ref StringBuilder txt, Exception e){
            txt.AppendLine(e.Message);
            txt.AppendLine(e.GetType().Name);
            txt.AppendLine(e.StackTrace);
        }

		protected override void Dispose( bool disposing ) {
			if( disposing && components != null)
				components.Dispose();
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		private System.Windows.Forms.PictureBox icon;
		private System.Windows.Forms.TextBox detail;
		private System.Windows.Forms.Button okButton;
		private System.ComponentModel.Container components = null;
		
		private void InitializeComponent()
		{
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ErrorMessageBox));
            this.icon = new System.Windows.Forms.PictureBox();
            this.detail = new System.Windows.Forms.TextBox();
            this.okButton = new System.Windows.Forms.Button();
            this.msg = new System.Windows.Forms.Label();
            this.linkLabel1 = new nft.controls.UrlLinkLabel();
            this.copyButton = new System.Windows.Forms.Button();
            this.note = new System.Windows.Forms.Label();
            this.throwButton = new System.Windows.Forms.Button();
            this.abortButton = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.icon)).BeginInit();
            this.SuspendLayout();
            // 
            // icon
            // 
            this.icon.Location = new System.Drawing.Point(16, 8);
            this.icon.Name = "icon";
            this.icon.Size = new System.Drawing.Size(48, 48);
            this.icon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
            this.icon.TabIndex = 0;
            this.icon.TabStop = false;
            // 
            // detail
            // 
            this.detail.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.detail.Location = new System.Drawing.Point(16, 80);
            this.detail.Multiline = true;
            this.detail.Name = "detail";
            this.detail.ReadOnly = true;
            this.detail.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.detail.Size = new System.Drawing.Size(576, 128);
            this.detail.TabIndex = 2;
            this.detail.Text = "detail";
            // 
            // okButton
            // 
            this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.okButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.okButton.Location = new System.Drawing.Point(408, 219);
            this.okButton.Name = "okButton";
            this.okButton.Size = new System.Drawing.Size(80, 24);
            this.okButton.TabIndex = 3;
            this.okButton.Text = "続行(&C)";
            // 
            // msg
            // 
            this.msg.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.msg.Location = new System.Drawing.Point(72, 8);
            this.msg.Name = "msg";
            this.msg.Size = new System.Drawing.Size(536, 48);
            this.msg.TabIndex = 1;
            this.msg.Text = "エラーが発生しました";
            this.msg.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // linkLabel1
            // 
            this.linkLabel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.linkLabel1.Location = new System.Drawing.Point(480, 56);
            this.linkLabel1.Name = "linkLabel1";
            this.linkLabel1.Size = new System.Drawing.Size(112, 16);
            this.linkLabel1.TabIndex = 4;
            this.linkLabel1.TabStop = true;
            this.linkLabel1.TargetUrl = "https://sourceforge.jp/users/c477/pf/NeoFT.Workshop/ticket/";
            this.linkLabel1.Text = " バグの報告先";
            this.linkLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            // 
            // copyButton
            // 
            this.copyButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.copyButton.Location = new System.Drawing.Point(16, 220);
            this.copyButton.Name = "copyButton";
            this.copyButton.Size = new System.Drawing.Size(168, 23);
            this.copyButton.TabIndex = 5;
            this.copyButton.Text = "内容をクリップボードにコピー";
            this.copyButton.Click += new System.EventHandler(this.copy_Clicked);
            // 
            // note
            // 
            this.note.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.note.BackColor = System.Drawing.SystemColors.Highlight;
            this.note.ForeColor = System.Drawing.SystemColors.HighlightText;
            this.note.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.note.Location = new System.Drawing.Point(84, 56);
            this.note.Name = "note";
            this.note.Size = new System.Drawing.Size(404, 16);
            this.note.TabIndex = 6;
            this.note.Text = " ※ バグ報告の際は以下の内容をコピーしてご報告をお願いします。";
            this.note.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // throwButton
            // 
            this.throwButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.throwButton.DialogResult = System.Windows.Forms.DialogResult.Retry;
            this.throwButton.Location = new System.Drawing.Point(190, 220);
            this.throwButton.Name = "throwButton";
            this.throwButton.Size = new System.Drawing.Size(134, 23);
            this.throwButton.TabIndex = 7;
            this.throwButton.Text = "再throw(開発用)";
            this.throwButton.UseVisualStyleBackColor = true;
            // 
            // abortButton
            // 
            this.abortButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.abortButton.DialogResult = System.Windows.Forms.DialogResult.Abort;
            this.abortButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.abortButton.Location = new System.Drawing.Point(494, 219);
            this.abortButton.Name = "abortButton";
            this.abortButton.Size = new System.Drawing.Size(98, 24);
            this.abortButton.TabIndex = 3;
            this.abortButton.Text = "アプリ終了(&X)";
            // 
            // ErrorMessageBox
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.ClientSize = new System.Drawing.Size(608, 245);
            this.Controls.Add(this.throwButton);
            this.Controls.Add(this.note);
            this.Controls.Add(this.copyButton);
            this.Controls.Add(this.linkLabel1);
            this.Controls.Add(this.abortButton);
            this.Controls.Add(this.okButton);
            this.Controls.Add(this.detail);
            this.Controls.Add(this.msg);
            this.Controls.Add(this.icon);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "ErrorMessageBox";
            this.Text = "エラー";
            ((System.ComponentModel.ISupportInitialize)(this.icon)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

		}
		#endregion

        private void copy_Clicked(object sender, EventArgs e) {
            string text = detail.Text;//.Replace("\n","\r\n");
            Clipboard.SetDataObject(text, true);
        }

        private void throwButton_Click(object sender, EventArgs e) {

        }
	}
}
