using System;
using System.Globalization;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Data;
using System.ComponentModel;
using System.Collections.ObjectModel;
using Message;

namespace TMC_Tool
{
  /// <summary>
  /// EditMaterialWindow.xaml の相互作用ロジック
  /// </summary>
  public partial class EditMtrColWindow : Window
  {
    private static Dictionary<string, string> txt = new Dictionary<string, string>();

    private static bool dialogResult;

    private static TMCData tmcData;
    private static TmcTables tmcTables;
    private static MtrColTables mtrColTables;

    private static List<List<TextBox>> tbParamsSets;

    private bool IsActivated = false;

    public EditMtrColWindow()
    {
      InitializeComponent();
      InitParamsInput();

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

      title.Text = txt["editMtrColTitle"];
      btnAdd.Content = txt["Add"];
      btnGet.Content = txt["Get"];
      btnDel.Content = txt["Del"];
      //labelParams.Content = txt["Parameter"];
      labelInfluenceObj.Content = txt["InfluenceObj"];
      btnOk.Content = txt["OK"];
      btnCancel.Content = txt["Cancel"];
    }

    private void InitParamsInput()
    {
      var labelParams = new List<Label>();
      for (int i = 0; i < 13; i++)
      {
        var label = new Label();
        label.Height = 30;
        label.Margin = new Thickness(0, 0, 0, 3);
        labelParams.Add(label);
      }
      labelParams[0].Content = "Ambient";
      labelParams[1].Content = "Diffuse";
      labelParams[2].Content = "Specular";
      labelParams[3].Content = "Unknown";
      labelParams[4].Content = "Unknown";
      labelParams[5].Content = "Unknown";
      labelParams[6].Content = "Glow";
      labelParams[7].Content = "Specular2";
      labelParams[8].Content = "Rim Light";
      labelParams[9].Content = "Diffuse2";
      labelParams[10].Content = "Specular3";
      labelParams[11].Content = "Specular(Wet)";
      labelParams[12].Content = "Unknown";

      foreach (var label in labelParams)
      {
        panelLabel.Children.Add(label);
      }

      tbParamsSets = new List<List<TextBox>>();
      for (int i = 0; i < 13; i++)
      {
        var tbParams = new List<TextBox>();
        for (int j = 0; j < 4; j++)
        {
          var tb = new TextBox();
          tb.Name = "tb_" + i + "_" + j;
          tb.Width = 50;
          tb.Margin = new Thickness(0, 0, 2, 3);
          tb.PreviewKeyDown += tbParam_PreviewKeyDown;
          tb.KeyDown += tbParam_KeyDown;
          tb.LostFocus += tbParam_LostFocus;
          tb.MouseDoubleClick += tb_MouseDoubleClick;
          tbParams.Add(tb);
        }
        tbParamsSets.Add(tbParams);
      }

      foreach (var tbParams in tbParamsSets)
      {
        var panel = new StackPanel();
        panel.Orientation = Orientation.Horizontal;
        foreach (var tb in tbParams)
        {
          panel.Children.Add(tb);
        }
        panelParams.Children.Add(panel);
      }
    }

    public static void lang(Dictionary<string, string> langText)
    {
      txt = langText;
    }

    private void btnOk_Click(object sender, RoutedEventArgs e)
    {
      dialogResult = true;
      this.Close();
    }

    private void btnCancel_Click(object sender, RoutedEventArgs e)
    {
      dialogResult = false;
    }

    private void dgMtrCols_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
      if (!this.IsInitialized) return;

      if (dgMtrCols.SelectedItems.Count > 0)
      {
        listInfluenceObj.Text = "";
        foreach (var obj in tmcTables.ObjData)
        {
          foreach (var item in dgMtrCols.SelectedItems)
          {
            var mtrCol = item as MtrColTables.MtrCol;
            if (obj.MtrCol == mtrCol.OriginalIndex)
            {
              if (listInfluenceObj.Text != "") listInfluenceObj.Text += "\r\n";
              listInfluenceObj.Text += obj.Name;
            }
          }
        }
        if (listInfluenceObj.Text != "")
          listInfluenceObj.IsEnabled = true;
        else
          listInfluenceObj.IsEnabled = false;

        if (dgMtrCols.SelectedItems.Count == 1)
        {
          gridColParams.IsEnabled = true;
          var mtrCol = mtrColTables.MtrCols[dgMtrCols.SelectedIndex];
          //値をセットする
          for (int i = 0; i < mtrCol.Colors.Count; i++)
          {
            for (int j = 0; j < mtrCol.Colors[i].Length; j++)
            {
              tbParamsSets[i][j].Text = mtrCol.Colors[i][j].ToString();
            }
          }

          if (mtrCol.Use == 0)
            btnDel.IsEnabled = true;
          else
            btnDel.IsEnabled = false;
        }
      }
      if (dgMtrCols.SelectedItems.Count != 1)
      {
        gridColParams.IsEnabled = false;
        //値をクリアする
        foreach (var tbParams in tbParamsSets)
        {
          foreach (var tb in tbParams)
          {
            tb.Text = "";
          }
        }
      }
    }

    private void btnAdd_Click(object sender, RoutedEventArgs e)
    {
      var newMtrCol = new MtrColTables.MtrCol(null, 0);
      newMtrCol.Index = dgMtrCols.Items.Count;
      newMtrCol.OriginalIndex = -1;

      if (dgMtrCols.SelectedItems.Count == 1)
      {
        foreach (var color in mtrColTables.MtrCols[dgMtrCols.SelectedIndex].Colors)
        {
          newMtrCol.Colors.Add(color);
        }
      }
      else
      {
        //初期化カラーを設定
        newMtrCol.Colors.Add(new float[] { 0.3f, 0.3f, 0.3f, 1 });
        newMtrCol.Colors.Add(new float[] { 1, 1, 1, 1 });
        newMtrCol.Colors.Add(new float[] { 1, 1, 1, 0 });
        newMtrCol.Colors.Add(new float[] { 0, 0, 0, 1 });
        newMtrCol.Colors.Add(new float[] { 1, 1, 1, 1 });
        newMtrCol.Colors.Add(new float[] { 1, 1, 1, 1 });
        newMtrCol.Colors.Add(new float[] { 0, 0, 0, 0 });
        newMtrCol.Colors.Add(new float[] { 0, 0, 0, 0 });
        newMtrCol.Colors.Add(new float[] { 0, 0, 0, 1 });
        newMtrCol.Colors.Add(new float[] { 1, 1, 1, 1 });
        newMtrCol.Colors.Add(new float[] { 1, 1, 1, 0 });
        newMtrCol.Colors.Add(new float[] { 1, 1, 0.3f, 1 });
        newMtrCol.Colors.Add(new float[] { 0, 0, 0, 0 });
      }

      mtrColTables.MtrCols.Add(newMtrCol);

      dgMtrCols.SelectedIndex = dgMtrCols.Items.Count - 1;
      dgMtrCols.ScrollIntoView(dgMtrCols.Items[dgMtrCols.SelectedIndex]);

      btnOk.IsEnabled = true;
    }

    private void btnGet_Click(object sender, RoutedEventArgs e)
    {
      MainWindow mainWindow = this.Owner as MainWindow;
      int selIndex = -1;
      if (dgMtrCols.SelectedItems.Count == 1) selIndex = dgMtrCols.SelectedIndex;
      GettingMaterial gettingMat = mainWindow.getMaterial("MtrCol", selIndex);

      if (gettingMat == null || gettingMat.Col == null) return;

      bool result = checkGettingMtrCol(gettingMat);
      this.Owner.IsEnabled = false;
      if (!result) return;

      if (gettingMat.ColAdd)
      {
        gettingMat.Col.ID = mtrColTables.MtrCols.Count;
        var newMtrCol = new MtrColTables.MtrCol(gettingMat.Col, 0);
        newMtrCol.OriginalIndex = -1;
        mtrColTables.MtrCols.Add(newMtrCol);
        dgMtrCols.SelectedIndex = dgMtrCols.Items.Count - 1;
        dgMtrCols.ScrollIntoView(dgMtrCols.Items[dgMtrCols.SelectedIndex]);
      }
      else
      {
        mtrColTables.MtrCols[gettingMat.ColTarget].Colors.Clear();
        foreach (var col in gettingMat.Col.Color)
        {
          mtrColTables.MtrCols[gettingMat.ColTarget].Colors.Add(col);
        }
        if (selIndex != -1)
        {
          dgMtrCols.SelectedIndex = -1;
          dgMtrCols.SelectedIndex = selIndex;
        }
      }
      btnOk.IsEnabled = true;
    }

    private void btnDel_Click(object sender, RoutedEventArgs e)
    {
      List<int> selectedIndices = new List<int>();
      foreach (var item in dgMtrCols.SelectedItems)
      {
        var mtrCol = item as MtrColTables.MtrCol;
        if (mtrCol.Use == 0) selectedIndices.Add(mtrCol.Index);
      }

      selectedIndices.Sort();
      selectedIndices.Reverse();

      foreach (var index in selectedIndices)
      {
        mtrColTables.MtrCols.RemoveAt(index);
      }

      mtrColTables.ResetMtrColIndex();
      btnOk.IsEnabled = true;
    }

    private void tbParam_PreviewKeyDown(object sender, KeyEventArgs e)
    {
      if (e.Key == Key.Enter || e.Key == Key.Down || e.Key == Key.Up || e.Key == Key.Right || e.Key == Key.Left)
      {
        e.Handled = true;
        TextBox tb = sender as TextBox;

        var n = tb.Name.Split('_');
        int row = Int32.Parse(n[1]);
        int col = Int32.Parse(n[2]);

        if (e.Key == Key.Up)
        {
          if (row < 1) return;
          row--;
        }
        else if (e.Key == Key.Down)
        {
          if (row > 11) return;
          row++;
        }
        else if (e.Key == Key.Left)
        {
          if (tb != null && (tb.SelectionStart != 0 || tb.SelectionLength != 0))
          {
            e.Handled = false;
            return;
          }
          if (col < 1) return;
          col--;
        }
        else if (e.Key == Key.Right)
        {
          if (tb != null && tb.Text != "" && (tb.SelectionStart != tb.Text.Length || tb.SelectionLength != 0))
          {
            e.Handled = false;
            return;
          }
          if (col > 2) return;
          col++;
        }
        else if (e.Key == Key.Enter)
        {
          if (row > 11 && col > 2) return;

          if (col < 3)
          {
            col++;
          }
          else if (row < 12)
          {
            row++;
            col = 0;
          }
        }

        tbParamsSets[row][col].Focus();
        tbParamsSets[row][col].SelectAll();
      }
    }

    private void tbParam_KeyDown(object sender, KeyEventArgs e)
    {
      TextBox tb = sender as TextBox;

      if (e.Key == Key.System || e.Key == Key.Tab)
      {
        e.Handled = false;
      }
      else if ((Key.D0 <= e.Key && e.Key <= Key.D9) || (Key.NumPad0 <= e.Key && e.Key <= Key.NumPad9))
      {
        e.Handled = false;
      }
      else if (e.Key == Key.Decimal || e.Key == Key.OemPeriod)
      {
        if (tb.Text.IndexOf(".") < 0 || tb.SelectedText.IndexOf(".") >= 0)
        {
          e.Handled = false;
        }
        else
        {
          e.Handled = true;
        }
      }
      else
      {
        e.Handled = true;
      }

      btnOk.IsEnabled = true;
    }

    private void tbParam_LostFocus(object sender, RoutedEventArgs e)
    {
      TextBox tb = sender as TextBox;

      var n = tb.Name.Split('_');
      int row = Int32.Parse(n[1]);
      int col = Int32.Parse(n[2]);

      mtrColTables.MtrCols[dgMtrCols.SelectedIndex].Colors[row][col] = Single.Parse(tb.Text);
    }

    private void tb_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
      TextBox target = sender as TextBox;
      if (target == null) return;
      target.SelectAll();
    }



    public MtrColTables Show(Window owner, TMCData data, TmcTables tables, int index)
    {
      this.Owner = owner;
      this.Owner.IsEnabled = false;
      btnOk.IsEnabled = false;

      tmcTables = tables;
      tmcData = data;

      mtrColTables = null;
      mtrColTables = new MtrColTables(tmcData, tmcTables);
      this.DataContext = mtrColTables;

      if (this.ActualHeight != 0)
      {
        this.Top = owner.Top + (owner.ActualHeight / 2) - (this.ActualHeight / 2);
        this.Left = owner.Left + (owner.ActualWidth / 2) - (this.ActualWidth / 2);
      }

      if (index != -1)
      {
        dgMtrCols.SelectedIndex = index;
        dgMtrCols.ScrollIntoView(dgMtrCols.Items[index]);
      }

      IsActivated = false;
      this.ShowDialog();

      this.Owner.IsEnabled = true;
      this.Owner.Focus();

      if (dialogResult)
      {
        return mtrColTables;
      }
      else
      {
        return null;
      }
    }

    public bool checkGettingMtrCol(GettingMaterial gettingMat)
    {
      // 既に同じものがあるかチェック（置換の場合は置換先は除く）
      List<int> equalMtrCol = new List<int>();
      foreach (var mtrCol in mtrColTables.MtrCols)
      {
        if (!gettingMat.ColAdd && mtrCol.Index == gettingMat.ColTarget) continue;
        for (int i = 0; i < mtrCol.Colors.Count; i++)
        {
          for (int j = 0; j < mtrCol.Colors[i].Length; j++)
          {
            if (mtrCol.Colors[i][j] != gettingMat.Col.Color[i][j])
            {
              goto SkipAdd;
            }
          }
        }
        equalMtrCol.Add(mtrCol.Index);

      SkipAdd:;
      }

      // 同じものがあれば追加するか確認
      if (equalMtrCol.Count > 0)
      {
        string str = txt["ConfirmReplace"];
        if (gettingMat.ColAdd) str = txt["ConfirmAdd"];

        string equalMtrColText = "   MtrCol :";
        foreach (var col in equalMtrCol)
        {
          equalMtrColText += " " + col;
        }
        string result = MessageWindow.Show(this, txt["SameMtrCol"] + equalMtrColText + "\r\n" + str, txt["Confirm"], txt["Yes"], txt["No"]);
        if (result == "Cancel")
        {
          return false;
        }
      }
      return true;
    }



    private void Window_Activated(object sender, EventArgs e)
    {
      if (!IsActivated) IsActivated = true;
    }

    private void Window_Closing(object sender, CancelEventArgs e)
    {
      e.Cancel = true;
      IsActivated = false;
      this.Hide();
      if (this.Owner != null) this.Owner.Activate();
    }
  }
}
