using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace DM2CompressPic
{
	/// <summary>
	/// Form2 の概要の説明です。
	/// </summary>
	public class Form2 : System.Windows.Forms.Form
	{
		/// <summary>
		/// 必要なデザイナ変数です。
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form2()
		{
			//
			// Windows フォーム デザイナ サポートに必要です。
			//
			InitializeComponent();

			//
			// TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
			//
		}

		/// <summary>
		/// 使用されているリソースに後処理を実行します。
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
		/// コード エディタで変更しないでください。
		/// </summary>
		private void InitializeComponent()
		{
			this.label1 = new System.Windows.Forms.Label();
			this.buttonRecompile = new System.Windows.Forms.Button();
			this.SuspendLayout();
			// 
			// label1
			// 
			this.label1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			this.label1.Location = new System.Drawing.Point(8, 8);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(24, 24);
			this.label1.TabIndex = 0;
			this.label1.Text = "?";
			this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			this.label1.Visible = false;
			// 
			// buttonRecompile
			// 
			this.buttonRecompile.Location = new System.Drawing.Point(8, 40);
			this.buttonRecompile.Name = "buttonRecompile";
			this.buttonRecompile.Size = new System.Drawing.Size(75, 24);
			this.buttonRecompile.TabIndex = 1;
			this.buttonRecompile.Text = "Recompile";
			this.buttonRecompile.Click += new System.EventHandler(this.buttonRecompile_Click);
			// 
			// Form2
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
			this.ClientSize = new System.Drawing.Size(544, 85);
			this.Controls.AddRange(new System.Windows.Forms.Control[] {
																		  this.buttonRecompile,
																		  this.label1});
			this.Name = "Form2";
			this.Text = "DM2CompressPic - Palette";
			this.Load += new System.EventHandler(this.Form2_Load);
			this.ResumeLayout(false);

		}
		#endregion

		System.Windows.Forms.Label[] m_pLabelz = null;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Button buttonRecompile;
		System.Byte[] m_pSelPal = new System.Byte[16];
		ICommitRecompile m_pForm1;
		bool m_fLittleEndian = true;
		CGDR.Draw8bppImg m_pDrawEntity;
		int[] m_pPalIdx6 = new int[6];

		public void Init(
			ICommitRecompile pForm1,
			System.Byte[] pSelPal,
			bool fLittleEndian,
			CGDR.Draw8bppImg pDrawEntity
			)
		{
			m_pForm1 = pForm1;
			pSelPal.CopyTo(m_pSelPal, 0);
			m_fLittleEndian = fLittleEndian;
			m_pDrawEntity = pDrawEntity;
			for (int i = 0; i < 6; i++) m_pPalIdx6[i] = 8 + i;

			UpdateLabelz();
		}

		static System.Drawing.Color InverseForForeColor(
			System.Drawing.Color p
			)
		{
			int z = 0
				+ System.Math.Abs(0x80 - p.R)
				+ System.Math.Abs(0x80 - p.G)
				+ System.Math.Abs(0x80 - p.B)
				;
			return System.Drawing.Color.FromArgb(p.R ^ 0xFF, p.G ^ 0xFF, p.B ^ 0xFF);
		}

		static void Swap(ref byte v1, ref byte v2) { byte v3 = v1; v1 = v2; v2 = v3; }
		static void Swap(ref int v1, ref int v2) { int v3 = v1; v1 = v2; v2 = v3; }

		void UpdateLabelz()
		{
			int i;
			for (i = 0; i < 16; i++)
			{
				int iAbsPal = m_pSelPal[i];
				System.Drawing.Color p = CGDR.DM2Pal[iAbsPal];
				m_pLabelz[i].BackColor = p;
				m_pLabelz[i].ForeColor = InverseForForeColor(p);
				m_pLabelz[i].Text = iAbsPal.ToString("X2");
			}
			for (i = 0; i < 6; i++)
			{
				int iAltIdx = m_pPalIdx6[i];
				int iAbsPal = m_pSelPal[iAltIdx];
				System.Drawing.Color p = CGDR.DM2Pal[iAbsPal];
				m_pLabelz[16 + i].BackColor = p;
				m_pLabelz[16 + i].ForeColor = InverseForForeColor(p);
				m_pLabelz[16 + i].Text = iAltIdx.ToString("X");
			}
		}

		void SwapSelPal(int iIdx1, int iIdx2, bool fRedraw)
		{
			Swap(
				ref m_pSelPal[iIdx1],
				ref m_pSelPal[iIdx2]
				);
			if (fRedraw) UpdateLabelz();
		}

		void SwapPalIdx6(int iWide, int iNarrow, bool fRedraw)
		{
			int i = System.Array.IndexOf(m_pPalIdx6, iWide);
			if (i < 0)
			{
				m_pPalIdx6[iNarrow] = iWide;
			}
			else
			{
				Swap(
					ref m_pPalIdx6[i],
					ref m_pPalIdx6[iNarrow]
					);
			}
			if (fRedraw) UpdateLabelz();
		}

		int MakePalIdx6Exchanger()
		{
			int x = 0;
			int i;
			for (i = 0; i < 6; i++)
			{
				x = (x << 4)|(m_pPalIdx6[i] & 0x0F);
			}
			return x;
		}

		bool CheckPaletteIntegrity()
		{
			System.Byte[] pOrgIdx16 = m_pSelPal;
			System.Byte[] pAltIdx16 = new System.Byte[16];
			pOrgIdx16.CopyTo(pAltIdx16, 0);
			int i;
			for (i = 0; i < 6; i++)
			{
				pAltIdx16[8 + i] = pOrgIdx16[m_pPalIdx6[i]];
			}
			string sVanished = "";
			for (i = 0; i < 16; i++)
			{
				int f = System.Array.IndexOf(pAltIdx16, pOrgIdx16[i]);
				if (f < 0)
				{
					if (sVanished.Length > 0)
						sVanished += " ";
					sVanished += pOrgIdx16[i].ToString("X2");
				}
			}
			if (sVanished.Length < 1)
				return true;
			switch (System.Windows.Forms.MessageBox.Show(""
				+ "Your modify will lose the color(s) '"+ sVanished +"'.\n"
				+ "It causes that incorrect color mapping will be proceeded.\n"
				+ "\n"
				+ "Would you retry?",
				this.Text,
				System.Windows.Forms.MessageBoxButtons.RetryCancel,
				System.Windows.Forms.MessageBoxIcon.Exclamation
				)
			) {
				case System.Windows.Forms.DialogResult.Retry:
					return true;
			}
			return false;
		}

		void labelP_DragEnter(object sender, DragEventArgs e)
		{
			if (e.Data.GetDataPresent(System.Windows.Forms.DataFormats.Text))
			{
				string sText = e.Data.GetData(System.Windows.Forms.DataFormats.Text) as string;
				switch (sText)
				{
					case "0":
					case "1":
					case "2":
					case "3":
					case "4":
					case "5":
					case "6":
					case "7":
					case "8":
					case "9":
					case "A":
					case "B":
					case "C":
					case "D":
					case "E":
					case "F":
						e.Effect = System.Windows.Forms.DragDropEffects.Copy;
						return;
				}
			}
			e.Effect = System.Windows.Forms.DragDropEffects.None;
		}

		void labelP_DragDrop(object sender, DragEventArgs e)
		{
			string sText = e.Data.GetData(System.Windows.Forms.DataFormats.Text) as string;
			System.Windows.Forms.Label pMe = sender as System.Windows.Forms.Label;
			int iFrom = int.Parse(sText, System.Globalization.NumberStyles.HexNumber);
			int iTo = int.Parse(pMe.Tag as string, System.Globalization.NumberStyles.HexNumber);
			SwapSelPal(iFrom, iTo, true);
		}

		void labelP_MouseDown(object sender, MouseEventArgs e)
		{
			switch (e.Button)
			{
				case System.Windows.Forms.MouseButtons.Left:
					System.Windows.Forms.Label pMe = sender as System.Windows.Forms.Label;
					pMe.DoDragDrop(pMe.Tag as string, System.Windows.Forms.DragDropEffects.Copy);
					break;
			}
		}

		void labelMUC_DragEnter(object sender, DragEventArgs e)
		{
			if (e.Data.GetDataPresent(System.Windows.Forms.DataFormats.Text))
			{
				string sText = e.Data.GetData(System.Windows.Forms.DataFormats.Text) as string;
				switch (sText)
				{
					case "0":
					case "1":
					case "2":
					case "3":
					case "4":
					case "5":
					case "6":
					case "7":
					case "8":
					case "9":
					case "A":
					case "B":
					case "C":
					case "D":
					case "E":
					case "F":
						e.Effect = System.Windows.Forms.DragDropEffects.Copy;
						return;
				}
			}
			e.Effect = System.Windows.Forms.DragDropEffects.None;
		}

		void labelMUC_DragDrop(object sender, DragEventArgs e)
		{
			string sText = e.Data.GetData(System.Windows.Forms.DataFormats.Text) as string;
			System.Windows.Forms.Label pMe = sender as System.Windows.Forms.Label;
			int iWide = int.Parse(sText, System.Globalization.NumberStyles.HexNumber);
			int iNarrow = int.Parse(pMe.Tag as string, System.Globalization.NumberStyles.HexNumber);
			SwapPalIdx6(iWide, iNarrow, true);
		}

		private void Form2_Load(object sender, System.EventArgs e)
		{
			m_pLabelz = new System.Windows.Forms.Label[22];
			for (int i = 0; i < 16; i++)
			{
				this.Controls.Add(m_pLabelz[i] = new System.Windows.Forms.Label());

				m_pLabelz[i].Location = new System.Drawing.Point(8 + 32 * i, 8);
				m_pLabelz[i].Size = new System.Drawing.Size(24, 24);
				m_pLabelz[i].BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
				m_pLabelz[i].TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
				m_pLabelz[i].AllowDrop = true;
				m_pLabelz[i].Tag = i.ToString("X");

				m_pLabelz[i].DragEnter += new System.Windows.Forms.DragEventHandler(labelP_DragEnter);
				m_pLabelz[i].DragDrop += new System.Windows.Forms.DragEventHandler(labelP_DragDrop);
				m_pLabelz[i].MouseDown += new System.Windows.Forms.MouseEventHandler(labelP_MouseDown);
			}
			for (int i = 16; i < 22; i++)
			{
				this.Controls.Add(m_pLabelz[i] = new System.Windows.Forms.Label());

				m_pLabelz[i].Location = new System.Drawing.Point(8 + 32 * (-16 + 8 + i), 40);
				m_pLabelz[i].Size = new System.Drawing.Size(24, 24);
				m_pLabelz[i].BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
				m_pLabelz[i].TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
				m_pLabelz[i].AllowDrop = true;
				m_pLabelz[i].Tag = (i - 16).ToString("X");

				m_pLabelz[i].DragEnter += new System.Windows.Forms.DragEventHandler(labelMUC_DragEnter);
				m_pLabelz[i].DragDrop += new System.Windows.Forms.DragEventHandler(labelMUC_DragDrop);
			}
		}

		private void buttonRecompile_Click(object sender, System.EventArgs e)
		{
			//if (!CheckPaletteIntegrity()) return;

			DM2DE pDE = DM2IC.CreateDrawEntity(m_pDrawEntity, m_pSelPal);
			System.IO.MemoryStream pFileInto = new System.IO.MemoryStream(10000);
			DM2IC.Compress(pDE, pFileInto, m_fLittleEndian, MakePalIdx6Exchanger());
			m_pForm1.SetCompressionResultBasis(new DM2CompressionResultBasis(pDE, pFileInto.ToArray()));
		}
	}
}
