// 下水データ管理システム
// Copyright (C) 2018 公益財団法人とちぎ建設技術センター(https://www.tochigictc.or.jp/)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.If not, see<http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;

namespace WindowsFormsApplication1 {
    public partial class Form8SettingForSyorijou : Form {
        public Form8SettingForSyorijou() {
            InitializeComponent();
        }


        Color validationOK = Color.FromArgb(225, 225, 225);

        string zeroSTR = "0";

        public string kanrisya { get; set; }
        public string syorijou { get; set; }
        public bool changed { get; set; }




        //ロード時イベント
        private void Form8SettingSeitenJudge_Load(object sender, System.EventArgs e) {
            this.SuspendLayout();

            changed = false;

            makeInputForm();
            dataGridViewInitialize();
            writeReference();
            setInputForm();

            this.ActiveControl = button2;

            this.ResumeLayout();
        }




        //入力フォーム生成
        private void makeInputForm() {
            //コントロール配置
            makeLabel("labelKanrisya", 5, 50, "対象の管理者：" + kanrisya);
            makeLabel("labelSyorijou", 5, 77, "対象の処理場：" + syorijou);
            makeLabel("labelSeiten", 5, 104, "【晴天日判定雨量】");

            int pitchY = 27;
            int offsetY = 128;

            for(int i = 0; i < 3; i++) {
                Label newLabel = new Label();
                newLabel.Name = "tl_d" + i.ToString();

                string dayName;

                if(i == 0) {
                    dayName = "当日";
                }
                else {
                    dayName = i.ToString() + "日前";
                }

                makeLabel("l_UT" + i.ToString(), 5, i * pitchY + offsetY + 3, "これ以上の場合は雨天とする雨量[mm](" + dayName + ")");

                NumericUpDownEx newNumericUpDown = new NumericUpDownEx();
                newNumericUpDown.Name = "nud_d" + i.ToString();
                newNumericUpDown.Font = new Font("Meiryo UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(128)));
                newNumericUpDown.Size = new Size(65, 21);
                newNumericUpDown.Location = new Point(259, i * pitchY + offsetY + 3);
                newNumericUpDown.BorderStyle = BorderStyle.None;
                newNumericUpDown.BackColor = Color.White;
                newNumericUpDown.TextAlign = HorizontalAlignment.Right;

                string ccFormat = ColumnsConfigSet.nameToFormat("uryou");

                if(ccFormat == "N0") {
                    newNumericUpDown.DecimalPlaces = 0;
                    newNumericUpDown.Increment = 1M;
                    zeroSTR = "0";
                }
                else if(ccFormat == "N1") {
                    newNumericUpDown.DecimalPlaces = 1;
                    newNumericUpDown.Increment = 0.1M;
                    zeroSTR = "0.0";
                }
                else if(ccFormat == "N2") {
                    newNumericUpDown.DecimalPlaces = 2;
                    newNumericUpDown.Increment = 0.01M;
                    zeroSTR = "0.00";
                }
                else if(ccFormat == "N3") {
                    newNumericUpDown.DecimalPlaces = 3;
                    newNumericUpDown.Increment = 0.001M;
                    zeroSTR = "0.000";
                }
                else if(ccFormat == "N4") {
                    newNumericUpDown.DecimalPlaces = 4;
                    newNumericUpDown.Increment = 0.0001M;
                    zeroSTR = "0.0000";
                }
                else if(ccFormat == "N5") {
                    newNumericUpDown.DecimalPlaces = 5;
                    newNumericUpDown.Increment = 0.00001M;
                    zeroSTR = "0.00000";
                }

                newNumericUpDown.Maximum = ColumnsConfigSet.getSet[ColumnsConfigSet.nameToIndex("uryou")].Maximum;
                newNumericUpDown.Minimum = ColumnsConfigSet.getSet[ColumnsConfigSet.nameToIndex("uryou")].Minimum;

                ((TextBox)newNumericUpDown.Controls[1]).Text = null;

                newNumericUpDown.Click += new EventHandler(numericUpDownAllFocus);
                newNumericUpDown.GotFocus += new EventHandler(numericUpDownAllFocus);
                newNumericUpDown.ValueChanged += new EventHandler((sender, args) => numericUpDownChanged(ccFormat, sender, args));
                newNumericUpDown.Leave += new EventHandler((sender, args) => numericUpDownChanged(ccFormat, sender, args));

                this.Controls.Add(newNumericUpDown);

                Label newValidationLabel = new Label();
                newValidationLabel.Name = "vl_d" + i.ToString();
                newValidationLabel.Size = new Size(6, 21);
                newValidationLabel.Location = new Point(323, i * pitchY + offsetY + 1);
                newValidationLabel.Padding = new Padding(0, 0, 0, 0);
                newValidationLabel.BackColor = validationOK;
                newValidationLabel.Text = "";
                this.Controls.Add(newValidationLabel);

                Label borderLabel = new Label();
                borderLabel.Name = "bl_d" + i.ToString();
                borderLabel.Size = new Size(72, 23);
                borderLabel.Location = new Point(newNumericUpDown.Location.X - 1, newNumericUpDown.Location.Y - 3);
                borderLabel.BorderStyle = BorderStyle.FixedSingle;
                borderLabel.BackColor = Color.White;
                this.Controls.Add(borderLabel);
            }

            makeLabel("labelCalcSource", 5, 212, "【各計算に使用する数値】");

            List<string> tCSLList = SyorijouConfigSelectList.getCalcSourceLList();
            int pNun = tCSLList.Count;

            for(int i = 1; i <= pNun; i++) {
                int x = 5;

                if(i % 2 == 0) {
                    x += 300;
                }

                int y = 239 + 27 * (int)Math.Floor((i - 1) / 2d);

                makeLabel("l_CS" + i.ToString(), x, y, tCSLList[i - 1]);
                makeComboBox("cb_CS" + i.ToString(), x + 140, y - 3, SyorijouConfigSelectList.getCalcSourceList(i).ToArray());
            }


            //【ローカル関数】ラベル作成
            void makeLabel(string name, int x, int y, string text) {
                Label newLabel = new Label();
                newLabel.Name = name;
                newLabel.Text = text;
                newLabel.Font = new Font("Meiryo UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(128)));
                newLabel.AutoSize = true;
                newLabel.Location = new Point(x, y);
                newLabel.TextAlign = ContentAlignment.MiddleLeft;
                this.Controls.Add(newLabel);
            }


            //【ローカル関数】コンボボックス作成
            void makeComboBox(string name,int x, int y, string[] item, string selectedItem = null) {
                ComboBoxEx newComboBox = new ComboBoxEx();
                newComboBox.Name = name;
                newComboBox.Font = new Font("Meiryo UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(128)));
                newComboBox.Size = new Size(100, 23);
                newComboBox.Location = new Point(x, y);
                newComboBox.FlatStyle = FlatStyle.Flat;
                newComboBox.BackColor = Color.White;
                newComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                newComboBox.Items.AddRange(item);
                newComboBox.FormattingEnabled = true;
                newComboBox.SelectedIndex = 0;
                newComboBox.ImeMode = ImeMode.Disable;
                this.Controls.Add(newComboBox);

                Label borderLabel = new Label();
                borderLabel.Name = "bl_" + name;
                borderLabel.Size = new Size(102, 25);
                borderLabel.Location = new Point(newComboBox.Location.X - 1, newComboBox.Location.Y - 1);
                borderLabel.BorderStyle = BorderStyle.FixedSingle;
                borderLabel.BackColor = Color.White;
                this.Controls.Add(borderLabel);
            }
        }




        //dataGridView1準備
        private void dataGridViewInitialize() {
            //DataGirdViewのプロパティDoubleBufferedをtrueに設定
            Type dataGridViewType = typeof(DataGridView);
            PropertyInfo dataGridViewProperty = dataGridViewType.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            dataGridViewProperty.SetValue(dataGridView1, true, null);
            dataGridView1.EnableHeadersVisualStyles = false;

            //列作成
            dataGridView1.Columns.Add(makeColumn("kanrisya", "管理者", 80, DataGridViewContentAlignment.MiddleLeft));
            dataGridView1.Columns.Add(makeColumn("syorijou", "処理場", 140, DataGridViewContentAlignment.MiddleLeft));

            for(int i = 0; i < 3; i++) {
                string dayName;

                if(i == 0) {
                    dayName = "当日";
                }
                else {
                    dayName = i.ToString() + "日前";
                }

                dataGridView1.Columns.Add(makeColumn("lluryouDay" + i.ToString(), "雨天条件\r\n(" + dayName + ")", 60, DataGridViewContentAlignment.MiddleRight));
            }

            List<string> tCSLList = SyorijouConfigSelectList.getCalcSourceLList();

            int C = 0;
            foreach(string tCSL in tCSLList) {
                C++;
                dataGridView1.Columns.Add(makeColumn("calcSource" + C.ToString(), tCSL, 80, DataGridViewContentAlignment.MiddleLeft));
            }

            dataGridView1.Columns[1].Frozen = true;


            //【ローカル関数】カラム作成
            DataGridViewTextBoxColumn makeColumn(string name, string text, int width, DataGridViewContentAlignment defCSA) {
                DataGridViewTextBoxColumn newColumn = new DataGridViewTextBoxColumn();
                newColumn = new DataGridViewTextBoxColumn();
                newColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
                newColumn.Resizable = DataGridViewTriState.False;
                newColumn.ReadOnly = true;
                newColumn.HeaderText = text;
                newColumn.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
                newColumn.HeaderCell.Style.Font = new Font("Meiryo UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(128)));
                newColumn.Name = name;
                newColumn.SortMode = DataGridViewColumnSortMode.NotSortable;
                newColumn.DefaultCellStyle.Alignment = defCSA;
                newColumn.DefaultCellStyle.NullValue = null;
                newColumn.DefaultCellStyle.Font = new Font("Meiryo UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(128)));
                newColumn.Width = width;
                return newColumn;
            }
        }




        //参考欄の記入
        private void writeReference() {
            dataGridView1.SuspendLayout();

            SyorijouConfig scd = new SyorijouConfig();

            dataGridView1.Rows.Add(new string[] { scd.kanrisya, scd.syorijou, scd.utenLLUryouDay0.ToString(), scd.utenLLUryouDay1.ToString(), scd.utenLLUryouDay2.ToString(), scd.calcSource1, scd.calcSource2, scd.calcSource3, scd.calcSource4, scd.calcSource5, scd.calcSource6 });

            foreach(SyorijouConfig sc in SyorijouConfigSet.getSet) {
                dataGridView1.Rows.Add(new string[] { sc.kanrisya, sc.syorijou, sc.utenLLUryouDay0.ToString(), sc.utenLLUryouDay1.ToString(), sc.utenLLUryouDay2.ToString(), sc.calcSource1, sc.calcSource2, sc.calcSource3, sc.calcSource4, sc.calcSource5, sc.calcSource6 });
            }

            dataGridView1.ResumeLayout();
        }




        //入力フォーム状態セット
        private void setInputForm() {
            //晴天日
            if(SyorijouConfigSet.getUtenLLUryouDay0(kanrisya, syorijou) != null) {
                if((decimal)SyorijouConfigSet.getUtenLLUryouDay0(kanrisya, syorijou) == 0) {
                    ((TextBox)this.Controls["nud_d0"].Controls[1]).Text = zeroSTR;
                }
                else {
                    ((NumericUpDownEx)this.Controls["nud_d0"]).Value = (decimal)SyorijouConfigSet.getUtenLLUryouDay0(kanrisya, syorijou);
                }
            }
            else {
                ((TextBox)this.Controls["nud_d0"].Controls[1]).Text = null;
            }

            if(SyorijouConfigSet.getUtenLLUryouDay1(kanrisya, syorijou) != null) {
                if((decimal)SyorijouConfigSet.getUtenLLUryouDay1(kanrisya, syorijou) == 0) {
                    ((TextBox)this.Controls["nud_d1"].Controls[1]).Text = zeroSTR;
                }
                else {
                    ((NumericUpDownEx)this.Controls["nud_d1"]).Value = (decimal)SyorijouConfigSet.getUtenLLUryouDay1(kanrisya, syorijou);
                }
            }
            else {
                ((TextBox)this.Controls["nud_d1"].Controls[1]).Text = null;
            }

            if(SyorijouConfigSet.getUtenLLUryouDay2(kanrisya, syorijou) != null) {
                if((decimal)SyorijouConfigSet.getUtenLLUryouDay2(kanrisya, syorijou) == 0) {
                    ((TextBox)this.Controls["nud_d2"].Controls[1]).Text = zeroSTR;
                }
                else {
                    ((NumericUpDownEx)this.Controls["nud_d2"]).Value = (decimal)SyorijouConfigSet.getUtenLLUryouDay2(kanrisya, syorijou);
                }
            }
            else {
                ((TextBox)this.Controls["nud_d2"].Controls[1]).Text = null;
            }

            //計算条件
            int pNun = SyorijouConfigSelectList.getCalcSourceLList().Count;

            for(int i = 1; i <= pNun; i++) {
                if(SyorijouConfigSet.getConfigString(kanrisya, syorijou, i) != null) {
                    ((ComboBox)this.Controls["cb_CS" + i.ToString()]).SelectedItem = SyorijouConfigSet.getConfigString(kanrisya, syorijou, i);
                }
                else {
                    ((ComboBox)this.Controls["cb_CS" + i.ToString()]).SelectedIndex = 0;
                }
            }
        }




        //NumericUpDownフォーカス時に数字を選択状態にする
        private void numericUpDownAllFocus(object sender, EventArgs e) {
            NumericUpDown n = (NumericUpDown)sender;
            int NumberLength = ((TextBox)n.Controls[1]).TextLength;
            ((TextBox)n.Controls[1]).Select(0, NumberLength);
        }




        //選択された場合に選択状態を解除する
        private void dataGridView1_SelectionChanged(object sender, EventArgs e) {
            dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Selected = false;
        }




        //NumericUpDown値変更時のイベント
        private void numericUpDownChanged(string format, object sender, EventArgs e) {
            //データごとの規定の小数点以下桁数に切捨て
            NumericUpDown n = (NumericUpDownEx)sender;

            if(format == "N0") {
                n.Value = Math.Truncate(n.Value);
            }
            else if(format == "N1") {
                n.Value = Math.Truncate(n.Value * 10) / 10;
            }
            else if(format == "N2") {
                n.Value = Math.Truncate(n.Value * 100) / 100;
            }
            else if(format == "N3") {
                n.Value = Math.Truncate(n.Value * 1000) / 1000;
            }
            else if(format == "N4") {
                n.Value = Math.Truncate(n.Value * 10000) / 10000;
            }
            else if(format == "N5") {
                n.Value = Math.Truncate(n.Value * 100000) / 100000;
            }
        }




        //設定するボタンクリックイベント
        private void button1_Click(object sender, EventArgs e) {
            if(MessageBox.Show("処理場ごとの計算条件設定を変更してよろしいですか\nこの処理場の晴天日は、過去も含めて全て新設定値で再判定されます\n計算値は過去も含めて全て再計算されます", "", MessageBoxButtons.OKCancel) == DialogResult.Cancel) {
                return;
            }
            
            //晴天日
            string ccFormat = ColumnsConfigSet.nameToFormat("uryou");

            NumericUpDown settedNumericUpDown0 = (NumericUpDownEx)this.Controls["nud_d0"];
            decimal? uten_ll_uryou_day0 = null;

            if(!String.IsNullOrEmpty(((TextBox)settedNumericUpDown0.Controls[1]).Text)) {
                uten_ll_uryou_day0 = FunctionForDatabase.decConvForDB(settedNumericUpDown0.Value, ccFormat);
            }

            NumericUpDown settedNumericUpDown1 = (NumericUpDownEx)this.Controls["nud_d1"];
            decimal? uten_ll_uryou_day1 = null;

            if(!String.IsNullOrEmpty(((TextBox)settedNumericUpDown1.Controls[1]).Text)) {
                uten_ll_uryou_day1 = FunctionForDatabase.decConvForDB(settedNumericUpDown1.Value, ccFormat);
            }

            NumericUpDown settedNumericUpDown2 = (NumericUpDownEx)this.Controls["nud_d2"];
            decimal? uten_ll_uryou_day2 = null;

            if(!String.IsNullOrEmpty(((TextBox)settedNumericUpDown2.Controls[1]).Text)) {
                uten_ll_uryou_day2 = FunctionForDatabase.decConvForDB(settedNumericUpDown2.Value, ccFormat);
            }

            //計算条件
            int pNun = SyorijouConfigSelectList.getCalcSourceLList().Count;
            string[] calcSource = new string[pNun + 1];

            for(int i = 1; i <= pNun; i++) {
                calcSource[i] = ((ComboBox)this.Controls["cb_CS" + i.ToString()]).SelectedItem.ToString();
            }

            int changedColumnNo = 0;

            using(var con = new SQLiteConnection(DataBaseConfig.ConnectionString)) {
                con.Open();

                //最初にUPDATEを試行
                try {
                    using(var cmd = con.CreateCommand()) {
                        string sql1 = "UPDATE uten_judge_uryou_setting SET ";
                        string sql2 = "uten_ll_uryou_day0 = @uten_ll_uryou_day0, uten_ll_uryou_day1 = @uten_ll_uryou_day1, uten_ll_uryou_day2 = @uten_ll_uryou_day2";
                        string sql3 = "";

                        for(int i = 1; i <= pNun; i++) {
                            sql3 += ", calc_source" + i.ToString() + " = @calc_source" + i.ToString();
                        }

                        string sql4 = " WHERE kanrisya = @kanrisya AND syorijou = @syorijou;";

                        cmd.CommandText = sql1 + sql2 + sql3 + sql4;

                        cmd.Parameters.Add(new SQLiteParameter("@kanrisya", kanrisya));
                        cmd.Parameters.Add(new SQLiteParameter("@syorijou", syorijou));
                        cmd.Parameters.Add(new SQLiteParameter("@uten_ll_uryou_day0", uten_ll_uryou_day0));
                        cmd.Parameters.Add(new SQLiteParameter("@uten_ll_uryou_day1", uten_ll_uryou_day1));
                        cmd.Parameters.Add(new SQLiteParameter("@uten_ll_uryou_day2", uten_ll_uryou_day2));

                        for(int i = 1; i <= pNun; i++) {
                            cmd.Parameters.Add(new SQLiteParameter("@calc_source" + i.ToString(), calcSource[i]));
                        }

                        cmd.ExecuteNonQuery();
                    }

                    using(var cmd = con.CreateCommand()) {
                        cmd.CommandText = "SELECT CHANGES();";

                        using(var reader = cmd.ExecuteReader()) {
                            while(reader.Read()) {
                                changedColumnNo = reader.GetInt32(0);
                            }
                        }
                    }
                }
                catch(Exception ex) {
                    MessageBox.Show(ex.Message);
                }

                if(changedColumnNo == 0) {
                    //UPDATEで更新件数が0の場合INSERT
                    try {
                        using(var cmd = con.CreateCommand()) {
                            string sql1 = "INSERT INTO uten_judge_uryou_setting(";
                            string sql2 = "kanrisya, syorijou, uten_ll_uryou_day0, uten_ll_uryou_day1, uten_ll_uryou_day2";
                            string sql3 = "";

                            for(int i = 1; i <= pNun; i++) {
                                sql3 += ", calc_source" + i.ToString();
                            }

                            string sql4 = ") VALUES(";
                            string sql5 = "@kanrisya, @syorijou, @uten_ll_uryou_day0, @uten_ll_uryou_day1, @uten_ll_uryou_day2";
                            string sql6 = "";

                            for(int i = 1; i <= pNun; i++) {
                                sql6 += ", @calc_source" + i.ToString();
                            }
                            string sql7 = ");";

                            cmd.CommandText = sql1 + sql2 + sql3 + sql4 + sql5 + sql6 + sql7;

                            cmd.Parameters.Add(new SQLiteParameter("@kanrisya", kanrisya));
                            cmd.Parameters.Add(new SQLiteParameter("@syorijou", syorijou));
                            cmd.Parameters.Add(new SQLiteParameter("@uten_ll_uryou_day0", uten_ll_uryou_day0));
                            cmd.Parameters.Add(new SQLiteParameter("@uten_ll_uryou_day1", uten_ll_uryou_day1));
                            cmd.Parameters.Add(new SQLiteParameter("@uten_ll_uryou_day2", uten_ll_uryou_day2));

                            for(int i = 1; i <= pNun; i++) {
                                cmd.Parameters.Add(new SQLiteParameter("@calc_source" + i.ToString(), calcSource[i]));
                            }

                            cmd.ExecuteNonQuery();
                        }
                    }
                    catch(Exception ex) {
                        MessageBox.Show(ex.Message);
                    }
                }

                con.Close();
            }

            //処理場ごとの計算条件設定用リストのリフレッシュ
            SyorijouConfigSet.presetSyorijouConfigSet();

            changed = true;

            this.Close();
        }




        //削除ボタンクリックイベント
        private void button3_Click(object sender, EventArgs e) {
            if(MessageBox.Show("処理場ごとの計算条件設定を削除してよろしいですか\n削除した場合、晴天日は過去も含めて全て標準値で再判定されます\n計算値は過去も含めて全て標準計算条件で再計算されます", "", MessageBoxButtons.OKCancel) == DialogResult.Cancel) {
                return;
            }

            using(var con = new SQLiteConnection(DataBaseConfig.ConnectionString)) {
                con.Open();

                try {
                    using(var cmd = con.CreateCommand()) {
                        string sql1 = "DELETE FROM uten_judge_uryou_setting WHERE kanrisya = @kanrisya AND syorijou = @syorijou;";

                        cmd.CommandText = sql1;

                        cmd.Parameters.Add(new SQLiteParameter("@kanrisya", kanrisya));
                        cmd.Parameters.Add(new SQLiteParameter("@syorijou", syorijou));

                        cmd.ExecuteNonQuery();
                    }
                }
                catch(Exception ex) {
                    MessageBox.Show(ex.Message);
                }

                con.Close();
            }

            //処理場ごとの計算条件設定用リストのリフレッシュ
            SyorijouConfigSet.presetSyorijouConfigSet();

            changed = true;

            this.Close();
        }




        //キャンセルボタンクリックイベント
        private void button2_Click(object sender, EventArgs e) {
            this.Close();
        }

    }
}
