//>>> _using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.Windows;
//<<< _using
using System.Net;
using System.IO;

using System.Threading;
using System.Threading.Tasks;
using System.Collections.Specialized;

namespace Framefield.Core.ID16c25627_0858_4a69_abfe_085e2d9b2a62
{
    public class Class_CSVToList2 : OperatorPart.Function
    {
        //>>> _inputids
        private enum InputId
        {
            CSVText = 0,
            RowsFirst = 1,
            RowsCount = 2,
            ColumnsFirst = 3,
            ColumnsCount = 4,
            SplitCharacter = 5
        }
        //<<< _inputids

        List<List<string>> _tmpList = new List<List<string>>();
        String _csvText;
        List<String> _resultList = new List<String>();
        
        int _rowsFirst;
        int _rowsCount;
        int _columnsFirst;
        int _columnsCount;

        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx) {
            //>>> _params
            var CSVText = inputs[(int)InputId.CSVText].Eval(context).Text;
            var RowsFirst = inputs[(int)InputId.RowsFirst].Eval(context).Value;
            var RowsCount = inputs[(int)InputId.RowsCount].Eval(context).Value;
            var Rows = new Vector2(RowsFirst, RowsCount);
            var ColumnsFirst = inputs[(int)InputId.ColumnsFirst].Eval(context).Value;
            var ColumnsCount = inputs[(int)InputId.ColumnsCount].Eval(context).Value;
            var Columns = new Vector2(ColumnsFirst, ColumnsCount);
            var SplitCharacter = inputs[(int)InputId.SplitCharacter].Eval(context).Text;
            //<<< _params
            
            if( _rowsFirst != (int)RowsFirst 
                ||_rowsCount != (int)RowsCount
                || _columnsFirst != (int)ColumnsFirst
                || _columnsCount != (int)ColumnsCount
            ) {
                Changed = true;
                _rowsFirst = (int)RowsFirst;
                _rowsCount = (int)RowsCount;
                _columnsFirst = (int)ColumnsFirst;
                _columnsCount = (int)ColumnsCount;
            }
            
            if( Changed) {
            

                if(SplitCharacter.Length != 1) {
                    Logger.Warn(this,"Invalid split-character : {0}", SplitCharacter);
                    _splitter = ',';
                }
                else {
                    _splitter= SplitCharacter[0];
                }
            
            
                if( CSVText != _csvText) {            
                    _csvText = CSVText;
                    _tmpList = SplitCSVLine( _csvText);
                }                
                
                
                RowsCount = Math.Max( RowsCount, 1);
                ColumnsCount = Math.Max( ColumnsCount, 1);
                RowsFirst = Math.Max( RowsFirst, 0);
                ColumnsFirst = Math.Max( ColumnsFirst, 1);
                _resultList.Clear();
                
                if(_tmpList.Count > 0) {
                    for(int r = (int)RowsFirst; r < (int)RowsFirst + (int)RowsCount; ++r) {
                        for(int c = (int)ColumnsFirst; c < (int)ColumnsFirst + (int)ColumnsCount; ++c) {
                            if(_tmpList.Count > r && _tmpList[r].Count > c) {
                                _resultList.Add( _tmpList[r][c]);
                            }
                        }
                    }                
                }
                Changed = false;
            }
            
            context.Dynamic = _resultList;
            return context;
        }
        
        char _splitter= ',';
        
        List<List<string>> SplitCSVLine(string lines)
        {
            var line = lines.Replace("<br>\n","");
            bool escapeActive = false;
            bool quoteActive = false;
            List<List<string>> result = new List<List<string>>();
            var lineStrings = new List<string>();
            string token = "";
            foreach (char c in line)
            {
                if (c == '\\') {
                    if (escapeActive) {
                        token += c; 
                    }
                    else {
                        escapeActive = true;
                    }
                } 
                else if (c == '"') {
                    if (escapeActive) {
                        token += c;
                    } else if (quoteActive) {
                        quoteActive = false;
                    } else {
                        quoteActive = true;
                    }
                } else if (c == _splitter) {
                    if (quoteActive) {
                        token += c;
                    } else {
                        lineStrings.Add(token);
                        token = "";
                    }
                }
                else if (c == '\n') {
                    if (quoteActive) {
                        token += c;
                    }
                    else {
                        lineStrings.Add(token);
                        token = String.Empty;
                        result.Add(lineStrings);
                        lineStrings = new List<string>();
                    }
                }
                else {
                    token += c;
                }
            }
            if (!String.IsNullOrEmpty(token)) {
                lineStrings.Add(token);
                result.Add(lineStrings);
            }
            return result;
        }


        Dictionary<string, int> KeysFromHeadline(List<string> headlineStrings) {
            int id = 0;
            Dictionary<string, int> result = new Dictionary<string, int>();
            foreach (var s in headlineStrings) {
                result[s] = id++;
            }
            return result;
        }
/*
        public void UpdateWinnersFromCSV(string csv) {
            return;
            if(csv != _keepCategoriesCSV) {
                InvalidData = false;
                _keepCategoriesCSV = csv;
                Logger.Info(this,"Updateing winners from CSV");

                if (csv != "") {
                    var lineStrings = SplitCSV(csv);
                    var keyIds = KeysFromHeadline(lineStrings[0]);
                    if (!keyIds.ContainsKey("CategoryID") || !keyIds.ContainsKey("WinnerID")) {
                        Logger.Warn(this,"Invalid category csv fileformat. CategoryID or WinnerID not found");
                        InvalidData = true;
                    }
                    else {

                        Dictionary<string, string> categoryWinnerIds = new Dictionary<string, string>();

                        for (int i = 1; i < lineStrings.Count; i++) {
                            var ls = lineStrings[i];
                            string catId = ls[keyIds["CategoryID"]];
                            string winnerId = ls[keyIds["WinnerID"]];
                            categoryWinnerIds[catId] = winnerId;
                        }

                        foreach (var c in CategoriesAndNominees) {
                            if (categoryWinnerIds.ContainsKey(c.FileName)) {
                                int id = 0;
                                foreach (var n in c.Nominees) {
                                    if (n.FileName == categoryWinnerIds[c.FileName]) {
                                        break;
                                    }
                                    else {
                                        id++; 
                                    }
                                }
                                if (id < c.Nominees.Count) {
                                    c.Winner = id;
                                }
                                else {
                                    Logger.Warn(this,String.Format("WinnerID {0} not found in Category {1}", categoryWinnerIds[c.FileName], c.FileName));
                                    InvalidData = true;
                                }
                            }
                        }
                    }
                }
                Logger.Info(this,"...completed");
            }
        }
        
        string _oldURL = ""; 
        string _content ="bla";
        float _lastUpdate = 0;
        */
    }
    
}

