using DotSpatial.Projections;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SMAT_CE
{

    public partial class frmSelectMonitors : FormBase
    {
        public frmSelectMonitors(List<string> lstMonitorFiles)
        {
            InitializeComponent();

            listBox1.Items.AddRange(lstMonitorFiles.ToArray());
        }

        List<BaseOutput> lstOutputMonitors = new List<BaseOutput>();

        public frmSelectMonitors()
        {
            InitializeComponent();

            lstOutputMonitors = CommonClass.CurrentBaseScenario.lstOutput.Where(p => p.outputType.Contains("Monitor")).Where(p => !p.outputName.Contains("Model")).Where(p => !p.outputName.Contains("Spatial Field")).ToList();
            List<string> lstMonitorFiles = lstOutputMonitors.Select(p => p.outputName).ToList();
            listBox1.Items.AddRange(lstMonitorFiles.ToArray());
        }

        public string selectedFilePath;
        public string selectedColomnName;
        public string currentFile;
        public string currentColomn;
        public List<string> lstLatLong = new List<string>();
        public Dictionary<string, double> dicMonitors = new Dictionary<string, double>();
        #region  方法

        private void ReadAllColumn(out List<string> lstColName, string filePath)
        {
            lstColName = new List<string>();
            DataTable dt = new DataTable();

            try
            {
                //filePath = filePath.Replace("TY", "administrator");

                //foreach (var item in CommonClass.CurrentBaseScenario.lstOutput)
                //{
                //    item.outputFilePath=item.outputFilePath.Replace("TY", "administrator");
                //}

                #region read the first line of data file
                //string dataType = "";
                FileStream fs = null;
                fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader sr = new StreamReader(fs, System.Text.Encoding.UTF8);
                string[] sMatchArray = sr.ReadLine().Split(new char[] { ',' });
                string _dataType = sMatchArray[0];
                fs.Dispose();
                sr.Dispose();
                sr.Close();
                GC.Collect();
                #endregion
                #region read datatable from data file
                bool errorOccur = false;
                if (_dataType.Trim().ToLower() == "quarter")
                {
                    if (filePath.Contains("Daily All Years All Days PM25 Point"))
                    {
                        dt = CommonClass.getDataTableForMapDaily(filePath, CommonClass.CurrentBaseScenario);
                    }
                    else if (filePath.Contains("Daily All Years High Days PM25 Point"))
                    {
                        dt = CommonClass.getDataSetFromCSVAndFirstLine(filePath, ref _dataType, ref errorOccur);
                    }
                    else
                        dt = CommonClass.getDataTableForMap(filePath);
                }
                else if (filePath.Contains("SSIA Source Location"))//SSIA
                {
                    dt = CommonClass.getDataSetFromCSV(filePath).Tables[0];
                }
                else
                {
                    dt = CommonClass.getDataSetFromCSVAndFirstLine(filePath, ref _dataType, ref errorOccur);
                }
                #endregion



                foreach (DataColumn dc in dt.Columns)
                {
                    if (dc.ColumnName.ToLower().Contains("lat")
                        || dc.ColumnName.ToLower().Contains("long")
                        || dc.ColumnName.ToLower().Contains("id")
                        || dc.ColumnName.ToLower().Contains("type")
                        || dc.ColumnName.ToLower().Contains("rrf")
                        || dc.ColumnName.ToLower().Contains("name")
                        )
                    { continue; }
                    else
                    { lstColName.Add(dc.ColumnName); }
                }
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
            }


        }

        public bool UseDefaultFileAndColumn(string MapName, string colName)
        {
            try
            {
                string DefaultFile = "";
                string keyFile = "NOSUCHFILE";
                #region//Select Default Monitor File, 按不同分析类型分类
                switch (CommonClass.CurrentAnalysis)
                {
                    case enumAnalysis.AnnualPM:
                        {
                            if (MapName.Contains("Quarterly"))
                            {
                                keyFile = "quarterly pm25 point";
                            }
                            else if (MapName.Contains("Annual"))
                            {
                                keyFile = "annual pm25 point";
                            }
                            break;
                        }
                    case enumAnalysis.DailyPM:
                        {
                            //keyFile = "";
                            //add by sclong,2017-03-07
                            if (colName.Contains("pm25"))
                            {
                                keyFile = "quarterly peak pm2.5 monitors";
                            }
                            else
                            {
                                keyFile = "quarterly peak speciated monitors";
                            }



                            break;
                        }
                    case enumAnalysis.Ozone:
                        {
                            //keyFile = "- ozone monitors -- temporally adjusted";
                            keyFile = " - ozone monitors -- monitor data, temporally adjusted 2018 ";//modified by sclong,2017-03-07
                            break;
                        }
                    case enumAnalysis.Visibility:
                    case enumAnalysis.SSIADailyPM:
                        {
                            if (MapName.Contains("quarterly"))
                            {
                                keyFile = "quarterly pm point";
                            }
                            else if (MapName.Contains("Daily"))
                            {
                                keyFile = "daily pm point";
                            }
                            break;
                        }
                    case enumAnalysis.SSIAAnnualPM:
                        {
                            if (MapName.Contains("Grid quarterly"))
                            {
                                keyFile = "quarterly pm point";
                            }
                            else if (MapName.Contains("Grid annual"))
                            {
                                keyFile = "annual pm point";
                            }
                            if (MapName.Contains("Dispersion annual"))
                            {
                                keyFile = "dispersion annual pm point";
                            }
                            else if (MapName.Contains("Combined annual"))
                            {
                                keyFile = "combined annual pm point";
                            }
                            break;
                        }
                    case enumAnalysis.SSIAOzone:
                        {
                            keyFile = "ssia ozone point";
                            break;
                        }
                    case enumAnalysis.SSIADeposition: break;

                }





                //lstOutputMonitors = CommonClass.CurrentBaseScenario.lstOutput.Where(p => p.outputType.Contains("Monitor")).Where(p => !p.outputName.Contains("Model")).Where(p => !p.outputName.Contains("Spatial Field")).ToList();
                lstOutputMonitors = new List<BaseOutput>();
                foreach (var item in CommonClass.CurrentBaseScenario.lstOutput)
                {
                    string typeName = item.outputName.Replace(CommonClass.CurrentBaseScenario.configuration.configurationName, "");
                    if (item.outputType.Contains("Monitor")
                        && !typeName.Contains("Spatial Field")
                        && !typeName.Contains("Model"))
                    {
                        lstOutputMonitors.Add(item);
                    }
                }

                foreach (var Optfile in lstOutputMonitors)
                {
                    if (Optfile.outputName.Replace(CommonClass.CurrentBaseScenario.configuration.configurationName, "").ToLower().Contains(keyFile))
                    {
                        DefaultFile = Optfile.outputFilePath;
                        break;
                    }
                }
                #endregion
                if (DefaultFile == "")
                { goto False; }

                string[] sc = colName.ToLower().Split('_');

                string keyCol = "";
                #region//Select Default Column, base or futur, 按不同分析类型分类
                switch (CommonClass.CurrentAnalysis)
                {
                    case enumAnalysis.AnnualPM:
                    case enumAnalysis.DailyPM:
                    case enumAnalysis.Visibility:
                    case enumAnalysis.Ozone:
                        #region
                        if (sc.Contains("b"))
                        {
                            keyCol = "b";
                        }
                        else if (sc.Contains("f"))
                        {
                            keyCol = "f";
                        }
                        else
                        {
                            if (MapName.ToLower().Contains("baseline") || MapName.ToLower().Contains("base"))
                            { keyCol = "b"; }
                            else if (MapName.ToLower().Contains("future") || MapName.ToLower().Contains("forcast"))
                            { keyCol = "f"; }
                            else
                            { keyCol = ""; }
                        }
                        break;
                        #endregion
                    case enumAnalysis.SSIADailyPM:
                        #region
                        if (sc.Contains("alt"))
                        {
                            keyCol = "alt";
                        }
                        else if (sc.Contains("base"))
                        {
                            keyCol = "base";
                        }
                        else
                        {
                            keyCol = "";
                        }
                        break;
                        #endregion
                    case enumAnalysis.SSIAAnnualPM:
                        #region
                        if (sc.Contains("alt"))
                        {
                            keyCol = "alt";
                        }
                        else if (sc.Contains("2ndary"))
                        {
                            keyCol = "base";
                        }
                        else
                        {
                            keyCol = "";
                        }
                        break;
                        #endregion
                    case enumAnalysis.SSIAOzone:
                        #region
                        keyCol = "";
                        break;
                        #endregion
                    case enumAnalysis.SSIADeposition: break;
                }


                #endregion

                string keyQuarter = "";
                #region Select Default Column,quarter
                if (sc.Contains("q1"))
                {
                    keyQuarter += "q1";
                }
                else if (sc.Contains("q2"))
                {
                    keyQuarter += "q2";
                }
                else if (sc.Contains("q3"))
                {
                    keyQuarter += "q3";
                }
                else if (sc.Contains("q4"))
                {
                    keyQuarter += "q4";
                }
                else
                {
                    keyQuarter += "";
                }
                #endregion

                string keySpecies = "";
                #region Select Default Column, Species
                switch (CommonClass.CurrentAnalysis)
                {
                    case enumAnalysis.AnnualPM:
                        #region
                        if (sc.Contains("pm25"))
                        {
                            keySpecies = "pm25";
                        }
                        else if (sc.Contains("blank"))
                        {
                            keySpecies = "blank";
                        }
                        else if (sc.Contains("crustal"))
                        {
                            keySpecies = "crustal";
                        }
                        else if (sc.Contains("oc") || sc.Contains("ocmb") || sc.Contains("ocb"))
                        {
                            keySpecies = "ocmb";
                        }
                        else if (sc.Contains("ec"))
                        {
                            keySpecies = "ec";
                        }
                        else if (sc.Contains("nh4"))
                        {
                            keySpecies = "nh4";
                        }
                        else if (sc.Contains("so4"))
                        {
                            keySpecies = "so4";
                        }
                        else if (sc.Contains("no3") || sc.Contains("no3r"))
                        {
                            keySpecies = "no3";
                        }
                        else if (sc.Contains("salt"))
                        {
                            keySpecies = "salt";
                        }
                        else if (sc.Contains("cm"))
                        {
                            keySpecies = "cm";
                        }
                        else if (sc.Contains("don"))
                        {
                            keySpecies = "don";
                        }
                        else //No monitor data, Stop drawing monitors
                        {
                            keySpecies = "";
                        }
                        break;
                        #endregion
                    case enumAnalysis.DailyPM:

                        if (sc.Contains("pm25"))
                        {
                            keySpecies = "pm25";
                        }
                        else if (sc.Contains("blank"))
                        {
                            keySpecies = "blank";
                        }
                        else if (sc.Contains("crustal"))
                        {
                            keySpecies = "crustal";
                        }
                        else if (sc.Contains("oc") || sc.Contains("ocmb") || sc.Contains("ocb"))
                        {
                            keySpecies = "ocmb";
                        }
                        else if (sc.Contains("ec"))
                        {
                            keySpecies = "ec";
                        }
                        else if (sc.Contains("nh4"))
                        {
                            keySpecies = "nh4";
                        }
                        else if (sc.Contains("so4"))
                        {
                            keySpecies = "so4";
                        }
                        else if (sc.Contains("no3") || sc.Contains("no3r"))
                        {
                            keySpecies = "no3";
                        }
                        else if (sc.Contains("salt"))
                        {
                            keySpecies = "salt";
                        }
                        else if (sc.Contains("cm"))
                        {
                            keySpecies = "cm";
                        }
                        else if (sc.Contains("don"))
                        {
                            keySpecies = "don";
                        }
                        else //No monitor data, Stop drawing monitors
                        {
                            keySpecies = "";
                        }
                        break;
                    case enumAnalysis.Visibility:
                    case enumAnalysis.Ozone:
                        #region
                        if (sc.Contains("o3(vna)") || sc.Contains("o3(evna)") || sc.Contains("o3(ds)") || sc.Contains("o3") || sc.Contains("o3(downscaler)"))
                        {
                            keySpecies = "o3";
                        }
                        else //No monitor data, Stop drawing monitors
                        {
                            keySpecies = "";
                        }
                        break;
                        #endregion
                    case enumAnalysis.SSIADailyPM:
                        #region
                        if (sc.Contains("pm25") || sc.Contains("pm25 (bg"))
                        {
                            keySpecies = "pm25";
                        }
                        else //No monitor data, Stop drawing monitors
                        {
                            keySpecies = "";
                        }
                        break;
                        #endregion
                    case enumAnalysis.SSIAAnnualPM:
                        #region
                        if (sc.Contains("2ndary"))
                        {
                            keySpecies = "2ndary";
                        }
                        else if (sc.Contains("alt"))
                        {
                            keySpecies = "pm25";
                        }
                        else if (sc.Contains("pm25") || sc.Contains("pm25 (bg"))
                        {
                            keySpecies = "pm25 (frm)";
                        }
                        else //No monitor data, Stop drawing monitors
                        {
                            keySpecies = "";
                        }
                        break;
                        #endregion
                    case enumAnalysis.SSIAOzone:
                        #region
                        if (sc.Contains("o3 (bg") || sc.Contains("base"))
                        {
                            keySpecies = "o3 (obs)";
                        }
                        else if (sc.Contains("alt"))
                        {
                            keySpecies = "alt";
                        }
                        else //No monitor data, Stop drawing monitors
                        {
                            keySpecies = "";
                        }
                        break;
                        #endregion
                    case enumAnalysis.SSIADeposition: break;
                }





                #endregion

                string DefaultColumn = "";
                List<string> lstColName;
                ReadAllColumn(out lstColName, DefaultFile);
                foreach (var col in lstColName)
                {
                    string[] c = col.ToLower().Split('_');

                    if ((!c.Contains(keyCol)) && keyCol != "")
                    { continue; }
                    if ((!c.Contains(keyQuarter)) && keyQuarter != "")
                    { continue; }
                    if ((!c.Contains(keySpecies)))
                    //if ((!c.Contains(keySpecies)) && keySpecies != "")
                    { continue; }

                    DefaultColumn = col;
                    break;

                    //if (c.Contains(keyCol) && c.Contains(keyQuarter) && c.Contains(keySpecies))
                    //   // if (c.Contains(keyQuarter) && c.Contains(keySpecies))
                    //{
                    //    DefaultColumn = col;
                    //    break;
                    //}
                }

                if (DefaultColumn == "")
                { goto False; }

                //Read Data
                readMonitorFileAndChangeProjection(DefaultFile, DefaultColumn);
                currentColomn = DefaultColumn;
                currentFile = DefaultFile;
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                goto False;
            }
        False:
            {
                return false;
            }
        }

        #endregion

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            listBox2.Items.Clear();

            int i = listBox1.SelectedIndex;
            List<string> lstColName;
            ReadAllColumn(out lstColName, lstOutputMonitors[i].outputFilePath);

            listBox2.Items.AddRange(lstColName.ToArray());
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                this.DialogResult = DialogResult.OK;

                dicMonitors.Clear();
                selectedFilePath = lstOutputMonitors[listBox1.SelectedIndex].outputFilePath;
                selectedColomnName = listBox2.SelectedItem.ToString();

                readMonitorFileAndChangeProjection(selectedFilePath, selectedColomnName);
                this.Close();
            }
            catch (Exception)
            {

            }


        }

        private void readMonitorFileAndChangeProjection(string file, string column)
        {
            DataTable dt = new DataTable();
            #region read the first line of data file
            //string dataType = "";
            FileStream fs = null;
            fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            StreamReader sr = new StreamReader(fs, System.Text.Encoding.UTF8);
            string[] sMatchArray = sr.ReadLine().Split(new char[] { ',' });
            string _dataType = sMatchArray[0];
            fs.Dispose();
            sr.Dispose();
            sr.Close();
            GC.Collect();
            #endregion
            #region read datatable from data file
            bool errorOccur = false;
            if (_dataType.Trim().ToLower() == "quarter")
            {
                if (file.Contains("Daily All Years All Days PM25 Point"))
                {
                    dt = CommonClass.getDataTableForMapDaily(file, CommonClass.CurrentBaseScenario);
                }
                else if (file.Contains("Daily All Years High Days PM25 Point"))
                {
                    dt = CommonClass.getDataSetFromCSVAndFirstLine(file, ref _dataType, ref errorOccur);
                }
                else
                    dt = CommonClass.getDataTableForMap(file);
            }
            else if (file.Contains("SSIA Source Location"))//SSIA
            {
                dt = CommonClass.getDataSetFromCSV(file).Tables[0];
            }
            else
            {
                dt = CommonClass.getDataSetFromCSVAndFirstLine(file, ref _dataType, ref errorOccur);
            }
            #endregion

            int ilat, ilong, ivalue;
            ilat = ilong = ivalue = -1;
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                if (dt.Columns[i].ColumnName.ToLower().Contains("lat"))
                { ilat = i; }
                if (dt.Columns[i].ColumnName.ToLower().Contains("long"))
                { ilong = i; }
                if (dt.Columns[i].ColumnName.ToLower().Contains(column.ToLower()))
                { ivalue = i; }
            }
            List<double> lstvalue = new List<double>();
            List<double> lstLat = new List<double>();
            List<double> lstLong = new List<double>();
            try
            {

                foreach (DataRow dr in dt.Rows)
                {
                    if (dr[ivalue] is System.DBNull)//有些季度没有数值，所以需要做此判断，对于没有数值的季度，赋值为-1；by sclong
                    {
                        lstvalue.Add(-1);
                    }
                    else
                    {
                        lstvalue.Add(Convert.ToDouble(dr[ivalue]));
                    }
                
                    lstLat.Add(Convert.ToDouble(dr[ilat]));
                    lstLong.Add(Convert.ToDouble(dr[ilong]));
                }
            }
            catch (Exception ex)
            {

                CommonClass.LogError(ex);
            }
            List<double> lstXY = new List<double>();
            for (int i = 0; i < lstLong.Count; i++)
            {
                lstXY.Add(lstLong[i]);
                lstXY.Add(lstLat[i]);
            }
            double[] arrayXY = lstXY.ToArray();


            ProjectionInfo p = new ProjectionInfo();
            if (LanguageOld.IsSMATChina)
            { p = ProjectionInfo.FromProj4String(CommonClass.projChina); }
            else
            { p = ProjectionInfo.FromProj4String(CommonClass.projUSACMAQ); }

            DotSpatial.Projections.Reproject.ReprojectPoints(arrayXY, null, DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984, p, 0, lstLat.Count);

            for (int i = 0; i < lstvalue.Count; i++)
            {
                string k = arrayXY[2 * i].ToString() + "," + arrayXY[2 * i + 1].ToString();
                if (!dicMonitors.ContainsKey(k))
                {
                    dicMonitors.Add(k, lstvalue[i]);
                    lstLatLong.Add(lstLat[i].ToString() + "," + lstLong[i].ToString());
                }

            }
        }


        private void button2_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }
    }
}
