using SewerStammGen.Shared.Contracts;
using SewerStammGen.Shared.Enum;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WWTech_KanalSchnittstelle.Exporter.Kandis
{
    public static class ExporterHelper
    {
        public static Dictionary<string, int> LineSize = new Dictionary<string, int>()
        {
            { "KANSCH4.0",  557 },
            { "KANSCH6.0",  2041 },
            { "KANHAL4.0",  530 },
            { "KANHAL6.0",  2167 },
            { "HAUSREV4.0", 355 },
            { "HAUSREV6.0", 1708 }
        };


        
    }
    internal abstract class KANDIS_Exporter : IDisposable
    {
        public enum kType
        {
            HALTUNG,
            SCHACHT,
            REVSCHACHT
        }

        private StreamWriter sw;
        char[] zeile;
        protected IWWLog Logger;

        protected string Zeile => new string(zeile);

        public KANDIS_Exporter(string filename, EExportType exportType, kType kType, IWWLog Logger)
        {
            this.Logger = Logger;
            string version = string.Empty;
            switch (kType)
            {
                case kType.HALTUNG:
                    {
                        switch (exportType)
                        {
                            case EExportType.KANDIS4: version = "KANHAL4.0"; break;
                            case EExportType.KANDIS6: version = "KANHAL6.0"; break;
                            default: throw new NotImplementedException();
                        }
                    }
                    break;
                case kType.SCHACHT:
                    {
                        switch (exportType)
                        {
                            case EExportType.KANDIS4: version = "KANSCH4.0"; break;
                            case EExportType.KANDIS6: version = "KANSCH6.0"; break;
                            default: throw new NotImplementedException();
                        }
                    }
                    break;
                case kType.REVSCHACHT:
                    {
                        switch(exportType)
                        {
                            case EExportType.KANDIS4: version = "HAUSREV4.0"; break;
                            case EExportType.KANDIS6: version = "HAUSREV6.0"; break;
                        }
                    }
                    break;
            }

            if (!ExporterHelper.LineSize.ContainsKey(version)) 
            {
                throw new NotImplementedException();
            }
            int maxzeilen = ExporterHelper.LineSize[version];

            sw = new StreamWriter(filename, append: false, Encoding.GetEncoding("ISO-8859-1"));

            WriteHeader(version);
            zeile = new char[maxzeilen];
            ClearLine();  
        }

        private void WriteHeader(string header)
        {
            sw.WriteLine(header);
            sw.Flush();
        }

        private void ClearLine()
        {
            for (int i = 0; i < zeile.Length; i++)
            {
                zeile[i] = ' ';
            }
        }

        protected void WriteLineInFile()
        {
            sw.WriteLine(Zeile);
            sw.Flush();
            ClearLine();
        }

        protected void WriteContent(Tuple<uint, uint> spalten, string content)
        {
            uint start = spalten.Item1 - 1;
            uint ende = spalten.Item2 -1;

            uint length = (ende+1) - start;
            if(content.Length > length)
            {
                string newcontent = content.Substring(0,(int)length);
                Logger.Log(string.Format("Inhalt {0} des Feldes war zu lang. Feld wird auf {1} stellen gekürzt." +
                    "Neue Inhalt lautet: {2}",content,length,newcontent));
                content = newcontent;
                
            }

            int counter = 0;
            for (uint i = start; i < (content.Length + start); i++)
            {
                zeile[i] = content[counter];
                counter++;
            }
        }

        protected void CloseStream()
        {
            sw.Close();
        }
        public void Dispose()
        {
            sw.Close();
            sw.Dispose();
        }
    }
}
