using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace CellEdit
{
    public partial class Form1 : Form
    {
        const int PATTERN_TABLE = 0x1f7f;
        const int PATTERN_LEN = 0x1800;
        const int COLOR_TABLE = 0x3f7f;
        const int COLOR_LEN = 0x1800;
        const int SPRITE_TABLE = PATTERN_TABLE + PATTERN_LEN;
        const int SPRITE_LEN = 0x80;

        public Form1()
        {
            InitializeComponent();
        }

        private void buttonRefFileSrc_Click(object sender, EventArgs e)
        {
            var result = openFileDialog1.ShowDialog();
            if(result == DialogResult.OK)
            {
                textBoxFileSrc.Text = openFileDialog1.FileName;
            }
        }

        private void buttonRefFileDst_Click(object sender, EventArgs e)
        {
            var result = openFileDialog2.ShowDialog();
            if (result == DialogResult.OK)
            {
                textBoxFileDst.Text = openFileDialog2.FileName;
            }
        }

        private void checkBoxCopyPart_CheckedChanged(object sender, EventArgs e)
        {
            groupBoxCopyPart.Enabled = checkBoxCopyPart.Checked;
        }

        private void textBoxFileSrc_TextChanged(object sender, EventArgs e)
        {
            CheckEnableExec();
        }

        private void textBoxFileDst_TextChanged(object sender, EventArgs e)
        {
            CheckEnableExec();
        }

        void CheckEnableExec()
        {
            buttonExecCopy.Enabled = textBoxFileSrc.Text.Length > 0 && textBoxFileDst.Text.Length > 0;
        }

        private void buttonExecCopy_Click(object sender, EventArgs e)
        {
            byte[] byte_src = null;
            byte[] byte_dst = null;
            using (var fs_src = new FileStream(textBoxFileSrc.Text, FileMode.Open, FileAccess.Read))
            {
                byte_src = new byte[fs_src.Length];
                fs_src.Read(byte_src, 0, byte_src.Length);
                fs_src.Close();
            }
            using (var fs_dst = new FileStream(textBoxFileDst.Text, FileMode.Open, FileAccess.ReadWrite))
            {
                byte_dst = new byte[fs_dst.Length];
                fs_dst.Read(byte_dst, 0, byte_dst.Length);
                if (checkBoxCopyPart.Checked)
                {
                    // 部分コピー(縦横反転)
                    if (checkBoxReverse.Checked)
                    {
                        int cell_dst = (int)numericUpDownCellDst.Value;
                        int cdw = 0;
                        int cdh = 0;
                        var cd = cell_dst;
                        for (int h = 0; h < numericUpDownCellSrcHeight.Value; h++)
                        {
                            for (int w = 0; w < numericUpDownCellSrcWidth.Value; w++)
                            {
                                int cell_src = (int)numericUpDownCellSrc.Value + w + h * 32;
                                CopyCell(byte_src, cell_src, byte_dst, cd);
                                cd += 32;
                                cdh++;
                                if (cdh >= numericUpDownCellDstHeight.Value)
                                {
                                    cdh = 0;
                                    cdw++;
                                    cd = cell_dst + cdw;
                                }
                            }
                        }
                    }
                    else
                    {
                        // 部分コピー(反転なし)
                        var cell_src = (int)numericUpDownCellSrc.Value;
                        var cell_dst = (int)numericUpDownCellDst.Value;
                        for (int h = 0; h < numericUpDownCellSrcHeight.Value; h++)
                        {
                            for (int w = 0; w < numericUpDownCellSrcWidth.Value; w++)
                            {
                                var offset = w + h * 32;
                                CopyCell(byte_src, cell_src + offset, byte_dst, cell_dst + offset);
                            }
                        }
                    }
                }
                else
                {
                    // 全体コピー
                    Buffer.BlockCopy(byte_src, PATTERN_TABLE, byte_dst, PATTERN_TABLE, PATTERN_LEN);
                    Buffer.BlockCopy(byte_src, COLOR_TABLE, byte_dst, COLOR_TABLE, COLOR_LEN);
                    if(checkBoxCopySprite.Checked)
                    {
                        Buffer.BlockCopy(byte_src, SPRITE_TABLE, byte_dst, SPRITE_TABLE, SPRITE_LEN);
                    }
                }
                fs_dst.Seek(0, SeekOrigin.Begin);
                fs_dst.Write(byte_dst, 0, byte_dst.Length);
                fs_dst.Close();
            }

            MessageBox.Show("処理を完了しました。");
        }

        void CopyCell(byte[] src, int src_cell, byte[] dst, int dst_cell)
        {
            const int c = 8;
            src_cell -= 1;
            dst_cell -= 1;

            var src_p = PATTERN_TABLE + src_cell * c;
            var src_c = COLOR_TABLE + src_cell * c;
            var dst_p = PATTERN_TABLE + dst_cell * c;
            var dst_c = COLOR_TABLE + dst_cell * c;
            for (var i = 0; i < 8; i++)
            {
                dst[dst_p + i] = src[src_p + i];
                dst[dst_c + i] = src[src_c + i];
            }
        }

        private void checkBoxReverse_CheckedChanged(object sender, EventArgs e)
        {
            OnChangereverse();
        }

        void OnChangereverse()
        {
            numericUpDownCellDstHeight.Enabled = checkBoxReverse.Checked;
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            groupBoxCopyPart.Enabled = checkBoxCopyPart.Checked;
        }
    }
}
