using System;
using System.IO;
using System.Globalization;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Data;
using Message;

namespace ___C_File_Editor
{
  /// <summary>
  /// MainWindow.xaml の相互作用ロジック
  /// </summary>
  public partial class MainWindow : Window
  {
    private static CData cData;
    public static CheckBox[] cb = new CheckBox[8];
    public static TextBox[] tb = new TextBox[9];

    private static byte[] bn;

    //private static byte[] tempBn;

    private static string cPath = "";

    private static bool appStarted = false;
    private static bool modified = false;
    private static Dictionary<string, string> txt = new Dictionary<string, string>();
    private static string langType = "Jpn";

    public MainWindow()
    {
      InitializeComponent();

      for (int i = 0; i < 8; i++)
      {
        cb[i] = new CheckBox();
        cb[i].Content = "Type " + ((char)(65 + i)).ToString();
        cb[i].Width = 80;
        cb[i].Height = 15;
        //Binding bind = new Binding();
        //bind.ElementName = "cbType" + ((char)(65 + i)).ToString();
        //bind.Path = new PropertyPath(Slider.ValueProperty);
        //cb[i].SetBinding(CheckBox.IsCheckedProperty, bind);
        panelHairstyles.Children.Add(cb[i]);
      }

      for (int i = 0; i < 9; i++)
      {
        tb[i] = new TextBox();
        //tb[i].Text = ((char)(65 + i)).ToString();
        tb[i].Width = 68;
        tb[i].TextAlignment = TextAlignment.Right;
        tb[i].GotFocus += new RoutedEventHandler(tb_GotFocus);
        tb[i].PreviewMouseLeftButtonDown += new MouseButtonEventHandler(tb_PreMouseLeftDown);
        tb[i].KeyDown += new KeyEventHandler(tbPositiveNum_KeyDown);
        tb[i].Margin = new Thickness(1, 0, 2, 0);
        panelAlpha152.Children.Add(tb[i]);
      }

      this.MouseLeftButtonDown += (sender, e) => this.DragMove();

      MainWindowTitle();
      changeLanguage();
      MessageWindow.lang(txt);

      Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose;
    }

    private void MainWindow_DragDrop(object sender, DragEventArgs e)
    {
      string[] filePaths = (string[])e.Data.GetData(DataFormats.FileDrop, false);
      if (System.IO.Path.GetExtension(filePaths[0]).ToUpper() == ".---C" || System.IO.Path.GetExtension(filePaths[0]).ToUpper() == ".--C")
      {
        OpenFile(filePaths[0]);
      }
    }

    private void OpenFromClipboard()
    {
      var pathText = Clipboard.GetText();
      if (Clipboard.ContainsFileDropList())
      {
        //データを取得する（取得できなかった時はnull）
        System.Collections.Specialized.StringCollection files = Clipboard.GetFileDropList();
        if (files != null) pathText = files[0];
      }
      if (!string.IsNullOrEmpty(pathText) && File.Exists(pathText) && (System.IO.Path.GetExtension(pathText).ToUpper() == ".---C" || System.IO.Path.GetExtension(pathText).ToUpper() == ".--C"))
      {
        var result = MessageWindow.Show(this, pathText + "\r\n\r\n" + txt["ConfirmOpenFile"], txt["Info"], txt["btnOpen"], txt["Cancel"]);
        if (result == "OK")
        {
          OpenFile(pathText);
        }
        Keyboard.Focus(mainWindow);
      }
    }

    private void openCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
      e.CanExecute = true;
    }
    private void openCommand_Executed(object sender, ExecutedRoutedEventArgs e)
    {
      Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
      if (cPath == "")
      {
        dlg.FileName = "";
      }
      else
      {
        dlg.InitialDirectory = Path.GetDirectoryName(cPath);
        dlg.FileName = Path.GetFileName(cPath);
      }
      dlg.DefaultExt = ".---C";
      dlg.Filter = "---C Files|*.---C;*.--C";

      Nullable<bool> result = dlg.ShowDialog();

      if (result == true)
      {
        OpenFile(dlg.FileName);
      }
    }

    private void saveCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
      //if (cData != null && cPath != "" && modified)
      if (cData != null && cPath != "")
        e.CanExecute = true;
      else
        e.CanExecute = false;
    }
    private void saveCommand_Executed(object sender, ExecutedRoutedEventArgs e)
    {
      string result = MessageWindow.Show(this, txt["Overwrite"], txt["Confirm"], txt["OverwriteYes"], txt["Cancel"]);
      if (result == "OK")
      {
        SaveFile(cPath);
      }
    }

    private void saveAsCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
      if (cData != null)
        e.CanExecute = true;
      else
        e.CanExecute = false;
    }
    private void saveAsCommand_Executed(object sender, ExecutedRoutedEventArgs e)
    {
      Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
      dlg.InitialDirectory = Path.GetDirectoryName(cPath);
      dlg.FileName = Path.GetFileName(cPath);
      dlg.DefaultExt = ".---C";
      dlg.Filter = "---C Files|*.---C;*.--C";

      Nullable<bool> result = dlg.ShowDialog();

      if (result == true)
      {
        SaveFile(dlg.FileName);
      }
    }

    private void cbAlpha152_Checked(object sender, RoutedEventArgs e)
    {
      Show_Aplha152Param();
    }

    private void cbAlpha152_Unchecked(object sender, RoutedEventArgs e)
    {
      Hide_Aplha152Param();
    }

    private void Show_Aplha152Param()
    {
      this.Height = this.MinHeight = this.MaxHeight = 292;
      gbAlpha152.Visibility = Visibility.Visible;
    }

    private void Hide_Aplha152Param()
    {
      this.Height = this.MinHeight = this.MaxHeight = 222;
      gbAlpha152.Visibility = Visibility.Collapsed;
    }



    private void OpenFile(string filePath)
    {
      try
      {
        btnSave.IsEnabled = false;
        btnSaveAs.IsEnabled = false;
        gbVisibleFlag.IsEnabled = false;
        gbAlpha152.IsEnabled = false;
        cbHideGlasses.IsChecked = false;
        Hide_Aplha152Param();
        foreach (TextBox tbox in tb)
        {
          tbox.Text = "";
        }
        textStatus.Path = txt["textStatus"];
        foreach (CheckBox cbox in cb)
        {
          cbox.IsChecked = false;
        }

        bn = System.IO.File.ReadAllBytes(filePath);
        char[] charsToTrim = { '\0' };
        string Name = Encoding.ASCII.GetString(bn, 0, 8).TrimEnd(charsToTrim);
        if (Name != "texch")
        {
          MessageWindow.Show(this, txt["NotC"] + " / " + this.Name, txt["Error"]);
        }
        uint Flg1 = BitConverter.ToUInt32(bn, 0x08);
        if (Flg1 != 16842752)
        {
          MessageWindow.Show(this, txt["UnsupportedC"], txt["Error"]);
          return;
        }
        HeaderData cH = new HeaderData(0, bn);
        if (cH.Count1 != 1)
        {
          MessageWindow.Show(this, txt["UnsupportedC"], txt["Error"]);
          return;
        }

        cData = new CData(cH, bn, cb);
        if (cData.Unknown)
        {
          MessageWindow.Show(this, txt["UnsupportedC"], txt["Error"]);
          return;
        }

        if (cData != null)
        {
          if (cData.Alpha152.Length > 0)
          {
            gbAlpha152.IsEnabled = true;
            Show_Aplha152Param();
            for (int i = 0; i < cData.Alpha152.Length; i++)
            {
              tb[i].Text = cData.Alpha152[i].ToString();
            }
          }
          if (cData.hideGlasses)
          {
            cbHideGlasses.IsChecked = true;
          }

          btnSave.IsEnabled = true;
          btnSaveAs.IsEnabled = true;
          gbVisibleFlag.IsEnabled = true;
          if (cData.Alpha152.Length == 0) gbOtherFlag.IsEnabled = true;
          textStatus.Path = filePath;
          cPath = filePath;
        }
      }
      catch (Exception e)
      {
        MessageWindow.Show(this, e.Message + "\r\n\r\n" + e.StackTrace, txt["Error"]);
      }
    }

    private void SaveFile(string filePath)
    {
      try
      {
        List<byte> newBn = new List<byte>();

        int count = 0;
        for (int i = 0; i < cb.Length; i++)
        {
          if (cb[i].IsChecked == true)
          {
            newBn.AddRange(new byte[8] { 1, 0, 0, 0, (byte)i, 0, 0, 0 });
            count++;
          }
        }
        if (cbHideGlasses.IsChecked == true)
        {
          newBn.AddRange(new byte[8] { 10, 0, 0, 0, 0, 0, 0, 0 });
          count++;
        }

        if (cData.Alpha152.Length != 0)
        {
          newBn.InsertRange(0, BitConverter.GetBytes((int)4));
          newBn.AddRange(BitConverter.GetBytes((int)5));
          for (int i = 0; i < cData.Alpha152.Length; i++)
          {
            newBn.AddRange(BitConverter.GetBytes(Single.Parse(tb[i].Text)));
          }
          if (newBn.Count <= 0x30)
          {
            newBn.AddRange(new byte[16]);
          }
        }

        if (newBn.Count == 0)
        {
          newBn.AddRange(new byte[16]);
        }
        else if (newBn.Count % 16 != 0)
        {
          newBn.AddRange(new byte[16 - (newBn.Count % 16)]);
        }

        newBn.InsertRange(0, bn.Take(0x40));
        int size = newBn.Count;
        newBn.RemoveRange(0x10, 4);
        newBn.InsertRange(0x10, BitConverter.GetBytes(size));

        byte[] saveBn = newBn.ToArray();
        // 保存
        System.IO.File.WriteAllBytes(filePath, saveBn);
        textStatus.Path = filePath;
        cPath = filePath;

        MessageWindow.Show(this, txt["Saved"], txt["Info"]);

      }
      catch (Exception e)
      {
        MessageWindow.Show(this, e.Message + "\r\n\r\n" + e.StackTrace, txt["Error"]);
      }
    }

  }
}
