using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using System.Reflection;
using System.IO;
using System.Resources;
using System.Xml.Serialization;

//---------------------------förändrings krav---------------------------
//  1.) Indexerande mellannivåer där count-måste sättas får inte hoppas över !
//
//
//        ====== BEFORE IMPLEMENTATION OF SAVER ==============
//        ====== IMPLEMENTATION OF SAVER STARTED =============
//----------------------------------------------------------------------
namespace CobXmlSupport
{

    public partial class GenCobCode : Form
    {
        // Jag har bara kommenterat lite för att testa att vi kan uppdatera repot
        Dictionary<string, string> uniqueTags, uniqueAttr, uniqueVars, uniqueCntVars;
        private List<string> CobResWords = null;
        private List<qualifieldhlp> qldList;
        private List<CobRow> rowList, tmpRowList;
        private CobRow latestLevelParent;
        private ShowCode genCode, genMoves, fromMoves, fromToMoves, genExtMoves;
        private frmSettings setWindow;
        private bool eventRun = false, formLoading = false;
        private string indTemp = "";
        private char[] splitChars = { '#' };
        private int ClientSizeMinWidth;
        private codeCompleter Cc;

        Dictionary<string, GenSetting> setObjs; // = new Dictionary<string, GenSetting>();
        SaverListener sl;

        //private string SettingUserName, SettingCompany;
        ////-------------------------
        //private bool SettingNoNsRef;
        //private bool SettingUniqueVars;
        //private bool SettingUniqueAttrVars;
        //private bool SettingUnique;
        //private bool SettingWrap;
        //private bool SettingValues;
        //private bool SettingAnaTag;
        //private string SettingPrefix;
        //private string SettingMaxOcc;
        //private bool SettingCountVars;
        //private string SettingLogVarName;
        //private string SettingLogSectName;
        ////-------------------------

        public readonly string NOMOVE = "NoMove";
        //private readonly bool MOVEFROM = true;

        public string FldPref
        {
            get
            {
                return txtPrefix.Text;
            }
        }

        public List<CobRow> RowList
        {
            get { return rowList; }
        }

        public System.Windows.Forms.ComboBox CmbLastFile
        {
            get { return cmbLastFile; }
        }

        public GenCobCode()
        {
            InitializeComponent();
            setObjs = new Dictionary<string, GenSetting>();
            sl = new SaverListener();
            sl.dict = setObjs;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            S.ettingActualFile = cmbLastFile.Text.Substring(cmbLastFile.Text.LastIndexOf("\\") + 1);
            GenSetting tmpGS = null;
            sl.dict.TryGetValue(S.ettingActualFile, out tmpGS);
            if (tmpGS != null)
            {
                tmpGS.SetSettings();
                setLocalValues();
            }
            else
            {
                S.ettingList = null;
            }
            runXMLgen();
        }

        private void runXMLgen()
        {
            chkEvents.Checked = false;
            if (!formLoading)
            {
                btnGenICode.Enabled = false;
                btnMoves.Enabled = false;
                btnMoveFrom.Enabled = false;
                chkDisplays.Enabled = false;
                chkPerform.Enabled = false;
                chkMvToDisp.Enabled = false;
                btnFrXMLTo.Enabled = false;

                if (cmbLastFile.Text.Length > 0)
                {
                    S.ettingActualFile = cmbLastFile.Text.Substring(cmbLastFile.Text.LastIndexOf("\\") + 1);
                    //GenSetting tmpGS=null;
                    //sl.dict.TryGetValue(S.ettingActualFile, out tmpGS);
                    //if (tmpGS != null)
                    //{
                    //    tmpGS.SetSettings();
                    //    setLocalValues();
                    //}

                    if(!File.Exists(cmbLastFile.Text))
                    {
                        runSetWindow(true);
                        cmbLastFile.Text = S.ettingFilePath + "\\" + S.ettingActualFile;
                    }

                    S.ettingFilePath = cmbLastFile.Text.Substring(0, cmbLastFile.Text.LastIndexOf("\\"));
                    uniqueTags = new Dictionary<string, string>();
                    uniqueAttr = new Dictionary<string, string>();
                    uniqueVars = new Dictionary<string, string>();
                    uniqueCntVars = new Dictionary<string, string>();
                    rowList = new List<CobRow>();
                    latestLevelParent = null;
                    outCob.Text = "";
                    outText.Text = "";
                    XmlDocument doc = new XmlDocument();
                    try
                    {
                        doc.Load(cmbLastFile.Text);
                        Process(doc);    //parse the xml-document, generate copybook resources
                        //prep_cobrows();  //order cobrowlist so that attributes are always the last in every level
                        showRows();      //display xml-structure and generated copybook
                        if (!cmbLastFile.Items.Contains(cmbLastFile.Text))
                        {
                            cmbLastFile.Items.Add(cmbLastFile.Text);
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace, "Felmeddelande från XMLCOB (" + ex.Source + ")");
                    }
                }
            }
        }

        private void prep_cobrows()
        {
            Stack<CobRow> Crs = new Stack<CobRow>();
            tmpRowList = new List<CobRow>();
            //int lastLevel = 0;
            CobRow lastRow = null;
            foreach (CobRow cr in rowList)
            {
                if (cr.isAttribute)
                {
                    Crs.Push(cr);
                }
                else
                {
                    if (Crs.Count > 0)
                    {
                        CobRow peekRow = Crs.Peek();
                        while (Crs.Count > 0
                            && (lastRow.CobLevel > cr.CobLevel
                            && peekRow.CobLevel <= lastRow.CobLevel
                            && peekRow.CobLevel > cr.CobLevel)
                            || (lastRow.CobLevel == cr.CobLevel
                            && (lastRow.FieldDef == ""
                            && cr.FieldDef == "")
                            && (peekRow.CobLevel > cr.CobLevel)))
                        {
                            tmpRowList.Add(Crs.Pop());
                            peekRow = Crs.Peek();
                        }
                    }
                    //lastLevel = cr.CobLevel;
                    lastRow = cr;
                    tmpRowList.Add(cr);
                }
            }
            if (Crs.Count > 0)
            {
                CobRow peekRow = Crs.Peek();
                while (Crs.Count > 0
                    && peekRow.CobLevel <= lastRow.CobLevel)
                {
                    tmpRowList.Add(Crs.Pop());
                    peekRow = Crs.Count > 0 ? Crs.Peek() : null;
                }
            }
            rowList = tmpRowList;
        }



        private void showRows()
        {
            // codeCompleter Cc = new codeCompleter(cmbLastFile.Text, txtPrefix.Text);
            Cc = new codeCompleter(cmbLastFile.Text, txtPrefix.Text);
            Cc.TryFill_In_Dic();
            Cc.TryFill_Out_Dic();
            Dictionary<string, int> FieldList = new Dictionary<string, int>();
            int objNr = 0;
            string fieldInCompl = "", fieldOutCompl = "";

            foreach (CobRow rw in rowList)
            {
                if (rw.CobLevel == 1)
                {
                    string inFile = cmbLastFile.Text.Substring(cmbLastFile.Text.LastIndexOf("\\") + 1);
                    CreateComment(outCob, rw.TagName, S.ettingUserName, S.ettingCompany, inFile, showJson: true);
                }
                if (rw.CobLevel > 0)
                {
                    // Prefill with possibly filled out code
                    if (!rw.isAttribute && !rw.SampleStr.Equals(NOMOVE))
                    {
                        if (Cc.WorkDicIn != null && Cc.WorkDicIn.Count > 0)
                        {
                            if (Cc.WorkDicIn.TryGetValue(rw.FieldName, out fieldInCompl))
                            {
                                rw.MoveCode = fieldInCompl;
                                //Debug.WriteLine("Existerarnde fält: " + rw.FieldName + " Kod : " + fieldInCompl);
                            }
                            else
                            {
                                Cc.WorkDicIn.Add(rw.FieldName, "");
                                //Debug.WriteLine("Upplagt fält: " + rw.FieldName);
                            }
                        }
                        if (rw.Move_Code == null) { rw.MoveCode = " "; }
                        Cc.WorkDicIn[rw.FieldName] = rw.Move_Code;

                        if (Cc.WorkDicOut != null && Cc.WorkDicOut.Count > 0)
                        {
                            if (Cc.WorkDicOut.TryGetValue(rw.FieldName, out fieldOutCompl))
                            {
                                rw.MoveFromCode = fieldOutCompl;
                                //Debug.WriteLine("Existerarnde fält: " + rw.FieldName + " Kod : " + fieldOutCompl);
                            }
                            else
                            {
                                Cc.WorkDicOut.Add(rw.FieldName, "");
                                //Debug.WriteLine("Upplagt fält: " + rw.FieldName);
                            }
                        }
                        if (rw.Move_FromCode == null) { rw.MoveFromCode = " "; }
                        Cc.WorkDicOut[rw.FieldName] = rw.Move_FromCode;

                        FieldList.Add(rw.FieldName, objNr++);
                    }
                    // Prefill with possibly filled out code
                    if (chkWrap.Checked)
                    {
                        outCob.Text += "\r\n" + rw.wrapped();
                    }
                    else
                    {
                        outCob.Text += "\r\n" + rw.wrapped(500);
                    }
                }
                //Debug.WriteLine(rw.TagName);
                //Debug.WriteLine(rw.Hirarchy);
            }
            string[] jkeys = Cc.WorkDicIn.Keys.ToArray();
            foreach (string jkey in jkeys)
            {
                int item;
                if (!FieldList.TryGetValue(jkey, out item))
                {
                    string checktxt = "";
                    Cc.WorkDicIn.TryGetValue(jkey, out checktxt);
                    if (checktxt.Trim().Length == 0)
                    {
                        Cc.WorkDicIn.Remove(jkey);
                    }
                }
            }
            Cc.Save_In_Dic();
            string[] jkeysOut = Cc.WorkDicOut.Keys.ToArray();
            foreach (string jkey in jkeysOut)
            {
                int item;
                if (!FieldList.TryGetValue(jkey, out item))
                {
                    string checktxt = "";
                    Cc.WorkDicOut.TryGetValue(jkey, out checktxt);
                    if (checktxt.Trim().Length == 0)
                    {
                        Cc.WorkDicOut.Remove(jkey);
                    }
                }
            }
            Cc.Save_Out_Dic();

            if (rowList.Count > 0)
            {
                btnGenICode.Enabled = true;
                btnMoves.Enabled = true;
                btnMoveFrom.Enabled = true;
                chkDisplays.Enabled = true;
                chkPerform.Enabled = true;
                chkMvToDisp.Enabled = true;
                btnFrXMLTo.Enabled = true;
            }
        }


        void Process(XmlNode node)
        {
            Process(node, 0);
        }

        /// <summary>
        ///  Procedure for iterating through an XML-dom object 
        ///  and finding tags , attributes and values
        /// </summary>
        /// <param name="node"></param>
        /// <param name="level"></param>
        void Process(XmlNode node, int level)
        {
            string strLDisp, strLOcc, strLStdValue, tmpStrSample;
            string levelPad, strCode, levelCob, strCobCode;
            int extLevel = 0;

            string sLevel = level.ToString("00");
            levelPad = "-".PadLeft(level + 1);
            levelCob = sLevel.PadLeft(level + 1);

            if (node.ChildNodes != null && node.ChildNodes.Count == 1 && node.ChildNodes[0].NodeType == XmlNodeType.Text)
            {

                strCode = node.NodeType.ToString() + " " + node.Name.ToString() + " = " + node.ChildNodes[0].Value.ToString();
                winWriteLine("{0}{1}", levelPad, strCode);

                typeDispValueCheck(node.ChildNodes[0].Value.ToString(), out strLDisp, out strLOcc, out strLStdValue, out tmpStrSample);

                if (node.Attributes != null && node.Attributes.Count > 0)
                {

                    strCobCode = txtPrefix.Text + prepName(node.Name.ToString()).Replace(":", "_") + (string)((strLOcc != "" && strLOcc != "1") ? " OCCURS " + strLOcc + " " : "") + " IDENTIFIED BY \"" + prepName(node.Name.ToString()) + "\"";
                    strCobCode = countVarChecker(txtPrefix.Text + prepName(node.Name.ToString()).Replace(":", "_"), strCobCode);
                    strCobCode += ".";
                    //                  cobWriteLine("{0} {1}", levelCob, strCobCode, node.NodeType, tmpStrSample);
                    //                  Ingen move from när tagen blir header
                    cobWriteLine("{0} {1}", levelCob, strCobCode, node.NodeType, NOMOVE);


                    extLevel = level + 1;
                    sLevel = extLevel.ToString("00");
                    levelPad = "-".PadLeft(extLevel + 1) + "Attr: ";
                    levelCob = sLevel.PadLeft(extLevel + 1);

                    strCobCode = txtPrefix.Text + prepName(node.Name.ToString()).Replace(":", "_") + "_Value " + strLDisp;
                    strCobCode = countVarChecker(txtPrefix.Text + prepName(node.Name.ToString()).Replace(":", "_") + "_Value", strCobCode);
                    strCobCode += ".";
                    cobWriteLine("{0} {1}", levelCob, strCobCode, node.NodeType, tmpStrSample);


                    foreach (XmlAttribute attr in node.Attributes)
                    {
                        strCode = attr.Name.ToString() + " " + attr.Value.ToString();
                        winWriteLine("{0}{1}", levelPad, strCode);

                        typeDispValueCheck(attr.Value.ToString(), out strLDisp, out strLOcc, out strLStdValue, out tmpStrSample);
                        strCobCode = txtPrefix.Text + prepName(attr.Name.ToString()).Replace(":", "_") + " " + strLDisp + " IDENTIFIED BY \"" + prepName(attr.Name.ToString()) + "\"  IS ATTRIBUTE";
                        //---- testing with count-vars for attribs
                        strCobCode = countVarChecker(txtPrefix.Text + prepName(node.Name.ToString()).Replace(":", "_"), strCobCode);
                        //---- testing with count-vars for attribs
                        strCobCode = valueChecker(strLDisp, strLStdValue, strCobCode);
                        cobWriteLine("{0} {1}", levelCob, strCobCode, attr.NodeType, tmpStrSample);
                    }
                }
                else
                {
                    strCobCode = txtPrefix.Text + prepName(node.Name.ToString()).Replace(":", "_") + " " + (string)((strLOcc != "" && strLOcc != "1") ? " OCCURS " + strLOcc + " " : "") + strLDisp + " IDENTIFIED BY \"" + prepName(node.Name.ToString()) + "\"";
                    strCobCode = countVarChecker(txtPrefix.Text + prepName(node.Name.ToString()).Replace(":", "_"), strCobCode);
                    strCobCode = valueChecker(strLDisp, strLStdValue, strCobCode);
                    cobWriteLine("{0} {1}", levelCob, strCobCode, node.NodeType, tmpStrSample);
                }
            }
            else
            {
                strCode = node.NodeType.ToString() + " " + node.Name.ToString();
                winWriteLine("{0}{1}", levelPad, strCode);

                strLOcc = "";
                if (node.Attributes != null)
                {
                    foreach (XmlAttribute attr in node.Attributes)
                    {
                        if (attr.Name.ToString().ToLower().Equals("fd_occ"))
                        {
                            string xdsp, xstdval;
                            typeDispValueCheck(attr.Value.ToString(), out xdsp, out strLOcc, out xstdval);
                            break;
                        }
                    }
                }

                //if (strLOcc != "")
                //{
                //    strCobCode = txtPrefix.Text + prepName(node.Name.ToString()).Replace(":", "_") + " OCCURS " + strLOcc + " IDENTIFIED BY \"" + prepName(node.Name.ToString()) + "\"";
                //}
                //else 
                strCobCode = txtPrefix.Text + prepName(node.Name.ToString()).Replace(":", "_") + (string)((strLOcc != "" && strLOcc != "1") ? " OCCURS " + strLOcc + " " : "") + " IDENTIFIED BY \"" + prepName(node.Name.ToString()) + "\"";
                strCobCode = countVarChecker(txtPrefix.Text + prepName(node.Name.ToString()).Replace(":", "_"), strCobCode);
                strCobCode += ".";
                cobWriteLine("{0} {1}", levelCob, strCobCode, node.NodeType, NOMOVE);

                if (node.Attributes != null && node.Attributes.Count > 0)
                {
                    extLevel = level + 1;
                    sLevel = extLevel.ToString("00");
                    levelPad = "-".PadLeft(extLevel + 1) + "Attr: ";
                    levelCob = sLevel.PadLeft(extLevel + 1);

                    foreach (XmlAttribute attr in node.Attributes)
                    {
                        strCode = attr.Name.ToString() + " " + attr.Value.ToString();
                        winWriteLine("{0}{1}", levelPad, strCode);

                        if (!attr.Name.ToString().ToLower().Equals("fd_occ"))
                        {
                            typeDispValueCheck(attr.Value.ToString(), out strLDisp, out strLOcc, out strLStdValue, out tmpStrSample);
                            strCobCode = txtPrefix.Text + prepName(attr.Name.ToString()).Replace(":", "_") + " " + strLDisp + " IDENTIFIED BY \"" + prepName(attr.Name.ToString()) + "\"  IS ATTRIBUTE";
                            //---- testing with count-vars for attribs
                            strCobCode = countVarChecker(txtPrefix.Text + prepName(node.Name.ToString()).Replace(":", "_"), strCobCode);
                            //---- testing with count-vars for attribs
                            strCobCode = valueChecker(strLDisp, strLStdValue, strCobCode);
                            cobWriteLine("{0} {1}", levelCob, strCobCode, attr.NodeType, tmpStrSample);
                        }
                    }
                }
                foreach (XmlNode child in node.ChildNodes)
                {
                    Process(child, level + 1);
                }
            }
        }

        private string prepName(string instring)
        {
            string tmpString = instring;
            if (chkNoNsRef.Checked)
            {
                string[] strParts = instring.Split(':');
                if (strParts.Length > 1)
                {
                    tmpString = strParts[1];
                }
            }
            return tmpString;
        }

        private string countVarChecker(string strFieldName, string strCobCode)
        {
            if (chkCountVars.Checked)
            {
                int nr = 0;
                string countName = "", tmpStr = "";
                string newCountName = CobRow.checkLongNames(strFieldName, 22) + "_cnt";
                countName = newCountName;
                while (uniqueCntVars.TryGetValue(countName, out tmpStr))
                {
                    nr++;
                    countName = newCountName + "_" + nr.ToString();
                }
                uniqueCntVars.Add(countName, strFieldName);
                strCobCode += " COUNT IN " + countName;
            }
            return strCobCode;
        }

        private string valueChecker(string strLDisp, string strLStdValue, string strCobCode)
        {
            if (chkValues.Checked)
            {
                if (strLStdValue.Trim().Length > 0)
                {
                    if (strLDisp.ToUpper().IndexOf("X") > -1)
                    {
                        strCobCode += " VALUE \"" + strLStdValue + "\".";
                    }
                    else
                    {
                        strCobCode += " VALUE " + strLStdValue + ".";
                    }
                }
                else strCobCode += ".";
            }
            else strCobCode += ".";
            return strCobCode;
        }

        private void typeDispValueCheck(string strToAnalyse, out string strDisp, out string strOcc, out string strStdValue)
        {
            string xSample = "";
            typeDispValueCheck(strToAnalyse, out strDisp, out strOcc, out strStdValue, out xSample);
        }

        static Random _r = new Random();

        private string genSample(int chars, string typKd, bool sweTkn = true)
        {
            string strText = "abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZåäöÅÄÖ";
            string strFigures = "0123456789";
            string tmpReturn = "";
            if (typKd.Equals("N"))
            {
                for (int i = 0; i < chars; i++)
                {
                    tmpReturn += strFigures.Substring(_r.Next(10), 1);
                }
            }
            else
            {
                int longTextCounter = 0;
                for (int i = 0; i < chars; i++)
                {
                    tmpReturn += strText.Substring(_r.Next((int)(sweTkn ? 56 : 50)), 1);
                    longTextCounter++;
                    if (longTextCounter > (int)(sweTkn ? 54 : 48))
                    {
                        tmpReturn += "\r\n      -         \"";
                        longTextCounter = 0;
                    }
                }
                tmpReturn = "\"" + tmpReturn + "\"";
            }
            return tmpReturn;
        }

        /// <summary>
        /// To be able to know size, type and occurrance of handled data (when schema is missing) 
        /// the example xml, which is base for this cobol-xml-generation, has some parameters 
        /// included as values. That parameter-string is compiled here.
        /// </summary>
        /// <param name="strToAnalyse"></param>
        /// <param name="strDisp"></param>
        /// <param name="strOcc"></param>
        /// <param name="strStdValue"></param>
        /// <param name="strSample"></param>
        private void typeDispValueCheck(string strToAnalyse, out string strDisp, out string strOcc, out string strStdValue, out string strSample)
        {
            string tmpSample = "";
            strDisp = "";
            strOcc = "";
            strStdValue = "";
            if (strToAnalyse.Contains(";") && chkAnaTag.Checked)
            {
                string[] anaParts = strToAnalyse.Split(';');
                string strNum1, strNum2 = "";

                if (anaParts[1].Contains("."))
                {
                    strNum1 = anaParts[1].Substring(0, anaParts[1].IndexOf("."));
                    strNum2 = anaParts[1].Substring(anaParts[1].IndexOf(".") + 1);
                }
                else
                {
                    strNum1 = anaParts[1].Trim();
                }


                switch (anaParts[0].ToLower())
                {
                    case "string":
                        {
                            strDisp = "PIC X(" + int.Parse(strNum1).ToString("00") + ")";
                            tmpSample = genSample(int.Parse(strNum1), "X");
                            break;
                        }
                    case "int":
                        {
                            strDisp = "PIC S9(" + int.Parse(strNum1).ToString("00") + ")";
                            tmpSample = genSample(int.Parse(strNum1), "N");
                            break;
                        }
                    case "posint":
                        {
                            strDisp = "PIC 9(" + int.Parse(strNum1).ToString("00") + ")";
                            tmpSample = genSample(int.Parse(strNum1), "N");
                            break;
                        }
                    case "decimal":
                        {
                            strDisp = "PIC S9(" + int.Parse(strNum1).ToString("00") + ")V9(" + int.Parse(strNum2).ToString("00") + ")";
                            tmpSample = genSample(int.Parse(strNum1) + int.Parse(strNum2), "N");
                            break;
                        }
                    case "posdecimal":
                        {
                            strDisp = "PIC 9(" + int.Parse(strNum1).ToString("00") + ")V9(" + int.Parse(strNum2).ToString("00") + ")";
                            tmpSample = genSample(int.Parse(strNum1) + int.Parse(strNum2), "N");
                            break;
                        }
                }

                strOcc = "";
                if (anaParts[2].Length > 0)
                {
                    int maxOcc = int.Parse(txtMaxOcc.Text);
                    string[] figs = anaParts[2].Split('-');

                    //if (figs[1].Equals("*")) strOcc+=figs[0]+" TO "+maxOcc.ToString();
                    //else  strOcc+=figs[0]+" TO "+figs[1];

                    if (figs[1].Equals("*")) strOcc += maxOcc.ToString();
                    else strOcc += figs[1];
                }


                if (anaParts.Length < 4)
                {
                    strStdValue = "";
                }
                else
                {
                    strStdValue = anaParts[3];
                }

            }
            else
            {
                strDisp = "PIC X(" + strToAnalyse.Length.ToString("00") + ")";
                strOcc = "";
                strStdValue = strToAnalyse;
            }

            strSample = tmpSample;
            //Debug.WriteLine(">"+strStdValue+"<");
        }


        private void winWriteLine(string defs, string startPos, string nodeName)
        {
            string wrkStr = String.Format(defs, startPos, nodeName);
            outText.Text += "\r\n" + wrkStr;
        }

        /// <summary>
        /// Creates a CobRow object from a cobol declaration text
        /// </summary>
        /// <param name="defs"></param>
        /// <param name="startPos">cobol level text</param>
        /// <param name="nodeName">variable declaration</param>
        /// <param name="xnt"></param>
        /// <param name="strValSample">stores value sample if applicable</param>
        private void cobWriteLine(string defs, string startPos, string nodeName, XmlNodeType xnt, string strValSample)
        {
            if (xnt.Equals(XmlNodeType.Attribute) || xnt.Equals(XmlNodeType.Element))
            {
                int lastLevel = 0;
                // check which is the latest inserted CobRow to determ if level is changed
                if (rowList.Count > 0)
                {
                    lastLevel = rowList[rowList.Count - 1].CobLevel;
                }
                string wrkStr = String.Format(defs, startPos, nodeName);
                CobRow tmpRow = new CobRow("       " + wrkStr);
                tmpRow.CobLevel = int.Parse(startPos.Trim());
                tmpRow.isAttribute = xnt.Equals(XmlNodeType.Attribute);
                tmpRow.SampleStr = strValSample;

                if (lastLevel > 0 && tmpRow.CobLevel != lastLevel)
                {
                    if (tmpRow.CobLevel > lastLevel)
                    {
                        latestLevelParent = rowList[rowList.Count - 1];
                    }
                    else
                    {
                        while (latestLevelParent.CobLevel >= tmpRow.CobLevel)
                        {
                            latestLevelParent = latestLevelParent.LevelParent;
                        }
                    }
                }
                tmpRow.LevelParent = latestLevelParent;

                CheckForUniqueVariables(tmpRow, true);
                CheckForUniqueVariables(tmpRow, false);

                // Arrange any xml-group uniquely when checkbox checked (by comparing X-path for every (tag-)field)
                if (lastLevel > 0 && chkUnique.Checked)
                {
                    try
                    {
                        uniqueTags.Add(tmpRow.Hirarchy, tmpRow.FieldName);
                        //Debug.WriteLine("OK:-" + tmpRow.FieldName.PadRight(40) + " Key : " + tmpRow.Hirarchy);
                        rowList.Add(tmpRow);
                    }
                    catch (ArgumentException)
                    {
                        Debug.WriteLine("NA:-" + tmpRow.FieldName);
                    }
                }
                else rowList.Add(tmpRow);
            }
        }

        private void CheckForUniqueVariables(CobRow tmpRow, bool attributes)
        {
            // arrange attribute variables uniquely when checkbox checked
            if ((chkUniqueAttrVars.Checked && attributes) || (chkUniqueVars.Checked && !attributes))
            {
                if (tmpRow.isAttribute == attributes)
                {
                    int verNr = 0;
                    bool ok = false;
                    string fName = tmpRow.FieldName;

                    while (!ok)
                    {
                        try
                        {
                            if (attributes) uniqueAttr.Add(fName, tmpRow.GetHashCode().ToString());
                            else uniqueVars.Add(fName, tmpRow.GetHashCode().ToString());
                            ok = true;
                        }
                        catch (ArgumentException)
                        {
                            verNr++;
                            fName = tmpRow.FieldName + "_" + verNr.ToString();
                        }
                    }
                    if (!fName.Equals(tmpRow.FieldName))
                    {
                        tmpRow.FieldName = fName;
                    }
                }
            }
        }

        private void DeserializeMetaData()
        {

            string SavePath = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]).ToString();

            GenSetting[] saveColl = null;
            setObjs = new Dictionary<string, GenSetting>();

            if (File.Exists(SavePath + "\\FilnamnsDict.xml"))
            {
                XmlSerializer x = new XmlSerializer(typeof(GenSetting[]));
                StreamReader reader = new StreamReader(SavePath + "\\FilnamnsDict.xml");
                saveColl = (GenSetting[])x.Deserialize(reader);

                foreach (GenSetting g in saveColl)
                {
                    setObjs.Add(g.ActualFile, g);
                }
            }

            sl.dict = setObjs;
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            formLoading = true;

            chkValues.Checked = true;
            chkUnique.Checked = true;
            chkAnaTag.Checked = true;
            chkUniqueAttrVars.Checked = true;
            chkUniqueVars.Checked = true;
            chkCountVars.Checked = true;
            chkDisplays.Checked = true;
            chkWrap.Checked = true;
            chkNewArea.Checked = false;
            //chkNewArea.Checked = true;
            chkEvents.Checked = false;
            ClientSizeMinWidth = this.ClientSize.Width;



            cmbLastFile.Items.Clear();
            foreach (string usedFile in Properties.Settings.Default.LastFile)
            {
                cmbLastFile.Items.Add(usedFile);
            }

            DeserializeMetaData();
            if (sl.dict.Count > 0)
            {
                cmbLastFile.Items.Clear();
                foreach (GenSetting x in sl.dict.Values)
                {
                    cmbLastFile.Items.Add(x.FilePath + "\\" + x.ActualFile);
                }
            }

            S.ettingUserName = Properties.Settings.Default.UserName;
            S.ettingCompany = Properties.Settings.Default.CompanyName;
            S.ettingAnaTag = Properties.Settings.Default.AnaTag;
            S.ettingCountVars = Properties.Settings.Default.CountVars;
            S.ettingMaxOcc = Properties.Settings.Default.MaxOcc;
            S.ettingNoNsRef = Properties.Settings.Default.NoNsRef;
            S.ettingPrefix = Properties.Settings.Default.Prefix;
            S.ettingExpPrefix = Properties.Settings.Default.ExpPrefix;
            S.ettingUnique = Properties.Settings.Default.Unique;
            S.ettingUniqueAttrVars = Properties.Settings.Default.UniqueAttrVars;
            S.ettingUniqueVars = Properties.Settings.Default.UniqueVars;
            S.ettingValues = Properties.Settings.Default.Values;
            S.ettingWrap = Properties.Settings.Default.Wrap;
            S.ettingLogVarName = Properties.Settings.Default.LogVarName;
            S.ettingLogSectName = Properties.Settings.Default.LogSectName;
            S.ettingShowTestbtns = Properties.Settings.Default.ShowTestbtns;

            chkAnaTag.Checked = S.ettingAnaTag;
            chkCountVars.Checked = S.ettingCountVars;
            txtMaxOcc.Text = S.ettingMaxOcc;
            chkDisplays.Checked = true;
            chkNoNsRef.Checked = S.ettingNoNsRef;
            txtPrefix.Text = S.ettingPrefix;
            txtExpPrefix.Text = S.ettingExpPrefix;
            chkUnique.Checked = S.ettingUnique;
            chkUniqueAttrVars.Checked = S.ettingUniqueAttrVars;
            chkUniqueVars.Checked = S.ettingUniqueVars;
            chkValues.Checked = S.ettingValues;
            chkWrap.Checked = S.ettingWrap;
            btnTestThings.Visible = S.ettingShowTestbtns;
            btnCrossref.Visible = S.ettingShowTestbtns;

            formLoading = false;
            // cmbLastFile.Text = cmbLastFile.Items[0].ToString();
            if (cmbLastFile.Items.Count > 0)
            {
                cmbLastFile.Text = cmbLastFile.Items[0].ToString();
            }

        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// generates initializing code for cobol variables attributes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGenICode_Click(object sender, EventArgs e)
        {
            Dictionary<string, string> indexNames = new Dictionary<string, string>();
            string IndVarText = "      *--------------------------------------------------*\r\n      * Extra indexvariabler för occurs-taggar   --------*\r\n      *--------------------------------------------------*";
            string slask = "";
            genCode = new ShowCode();
            genCode.FormParent = this;
            genCode.Labeltext = "Creating Initialization Code";

            savedFile SF = new savedFile();
            SF.idConnect = "A472C801-2A7A-4A09-B432-8F16504964C3";
            SF.usageName = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Init";
            SF.fNameSaved = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Init.cbl";
            genCode.SavedFile = SF;


            string inFile = cmbLastFile.Text.Substring(cmbLastFile.Text.LastIndexOf("\\") + 1);
            CreateComment(genCode.CodeShower, "Initializer", S.ettingUserName, S.ettingCompany, inFile);
            foreach (CobRow cr in rowList)
            {
                if (cr.isAttribute)
                {
                    string occParRows = "";
                    CobRow crTmp = cr;
                    genCode.CodeShower.Text += "\r\n           " + "MOVE " + cr.Value + "\r\n               TO " + cr.FieldName;
                    while (crTmp.LevelParent != null)
                    {
                        crTmp = crTmp.LevelParent;
                        genCode.CodeShower.Text += "\r\n               OF " + crTmp.FieldName;
                        genCode.CodeShower.Text = checkForOccurs(indexNames, crTmp, genCode.CodeShower.Text, ref occParRows, ref slask);
                    }
                    if (occParRows.Length > 0)
                    {
                        genCode.CodeShower.Text += " (" + occParRows + " )\r\n";
                    }
                }
            }

            genCode.CodeShower.Text = addOccursVars(indexNames, genCode.CodeShower.Text, IndVarText);

            tmpRowList = new List<CobRow>();
            foreach (string frmRow in genCode.CodeShower.Lines)
            {
                tmpRowList.Add(new CobRow(frmRow, false));
            }
            genCode.CodeShower.Text = "";
            tmpRowList.ForEach(delegate(CobRow crtmp)
            {
                genCode.CodeShower.Text += crtmp.wrapped() + "\r\n";
            });

            genCode.ShowDialog();
        }

        private void btnGenICodeNew_Click(object sender, EventArgs e)
        {
            //bool justOut = true;
            //bool loopTyp = false;

            Dictionary<string, string> indexNames = new Dictionary<string, string>();
            //string IndVarText = "      *--------------------------------------------------*\r\n      * Extra indexvariabler för occurs-taggar   --------*\r\n      *--------------------------------------------------*";
            //string slask = "";
            genCode = new ShowCode();
            genCode.FormParent = this;
            genCode.Labeltext = "Creating Initialization Code";

            savedFile SF = new savedFile();
            SF.idConnect = "15E1040B-2206-4F02-8212-FE9DF6B209B8";
            SF.usageName = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Init";
            SF.fNameSaved = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Init.cbl";
            genCode.SavedFile = SF;

            string inFile = cmbLastFile.Text.Substring(cmbLastFile.Text.LastIndexOf("\\") + 1);
            CreateComment(genCode.CodeShower, "Initializer", S.ettingUserName, S.ettingCompany, inFile);
            genCode.CodeShower.Text += "\r\n";

            //Dictionary for indexes, init IndexState class and list for qualifiedHelper class
            Dictionary<string, string> testIndexes = new Dictionary<string, string>();
            IndexState lIs = new IndexState(testIndexes, rowList);
            qldList = new List<qualifieldhlp>();

            foreach (CobRow cr in rowList)
            {
                //                if (cr.isAttribute)
                //                {
                qualifieldhlp tmpQlh = new qualifieldhlp(cr, lIs.Indexes);
                qldList.Add(tmpQlh);
                //string occParRows = "";
                //CobRow crTmp = cr;
                //genCode.CodeShower.Text += "\r\n           " + "MOVE " + cr.Value + "\r\n               TO " + cr.FieldName;
                //while (crTmp.LevelParent != null)
                //{
                //    crTmp = crTmp.LevelParent;
                //    genCode.CodeShower.Text += "\r\n               OF " + crTmp.FieldName;
                //    genCode.CodeShower.Text = checkForOccurs(indexNames, crTmp, genCode.CodeShower.Text, ref occParRows, ref slask);
                //}
                //if (occParRows.Length > 0)
                //{
                //    genCode.CodeShower.Text += " (" + occParRows + " )\r\n";
                //}
                //                }
            }

            //Indstatus keep track on present changings concerning indexes qualifying each qualified XML-record-field

            IndStatus indSt = new IndStatus();

            //here comes the central work-loop
            foreach (qualifieldhlp tmpQfh in qldList)
            {
                //IndStatus-object takes care of optionally occuring indexes 
                indSt.handleStatus(tmpQfh.indexStrings);

                //If indexes get out of scope there will come an END-PERFORM for each
                for (int i = 0; i < indSt.Returns; i++)
                {
                    genCode.CodeShower.Text += "           END-PERFORM" + "\r\n";
                }

                //Each index comming into scope will start a new PERFORM VARYING loop
                if (indSt.NewInds != null)
                {
                    foreach (string indTxt in indSt.NewInds)
                    {
                        //Perform

                        //genCode.CodeShower.Text += "           PERFORM VARYING " + indTxt + " FROM 1 BY 1\r\n           UNTIL " +
                        //indTxt + "\r\n            > " + tmpQfh.qualCobRow.CountIn.ToString() + "\r\n" + tmpQfh.indexRedText;

                        genCode.CodeShower.Text += "           PERFORM VARYING " + indTxt + " FROM 1 BY 1\r\n           UNTIL " +
                        indTxt + "\r\n            > " + tmpQfh.qualCobRow.occNum.ToString() + "\r\n"; // +tmpQfh.indexRedText;

                        //if (tmpQfh.qualCobRow.isOccurs) slask = "";
                    }
                }

                if (tmpQfh.qualCobRow.isAttribute)
                {
                    //when xml-record-field with occurs, the last index shall not be used (then use tmpQfh.indexRedText instead of tmpQfh.indexText
                    //loopTyp = tmpQfh.qualCobRow.isOccurs;
                    //genCode.CodeShower.Text += "           IF " + tmpQfh.qualCobRow.CountIn.ToString() + "\r\n" + (string)(loopTyp ? tmpQfh.indexRedText : tmpQfh.indexText) + "           > 0 \r\n";

                    //The acutal move of present fields
                    genCode.CodeShower.Text += "           MOVE " + tmpQfh.qualCobRow.Value;

                    genCode.CodeShower.Text += "\r\n           TO " + tmpQfh.ToString() + "\r\n";
                }

            }


            // get optionally occuring last END-PERFORMs...

            indSt.handleStatus(null);
            for (int i = 0; i < indSt.Returns; i++)
            {
                genCode.CodeShower.Text += "           END-PERFORM" + "\r\n";
            }


            //List all used indexes
            string tempIndText = "";
            genCode.CodeShower.Text = addOccursVars(testIndexes, genCode.CodeShower.Text, tempIndText);

            genCode.ShowDialog();
        }

        /// <summary>
        /// creates declaration for generated index-variables (in checkForOccurs())
        /// </summary>
        /// <param name="indexNames"></param>
        /// <param name="showString"></param>
        /// <param name="IndVarText"></param>
        /// <returns></returns>
        private string addOccursVars(Dictionary<string, string> indexNames, string showString, string IndVarText)
        {
            if (indexNames.Count > 0)
            {
                foreach (string indNamn in indexNames.Values)
                {
                    IndVarText += "\r\n      *01 " + indNamn + "    PIC 9(3) VALUE 0.";
                }
                IndVarText += "\r\n      *--------------------------------------------------*\r\n      * --- Avkommentera och lägg i Working Storage------*\r\n      *--------------------------------------------------*\r\n";
                showString = IndVarText + showString;
            }
            return showString;
        }
        /// <summary>
        /// Builds up string/string dictionary keeping index-variables to use together with indexed groups
        /// when the indexes are used in cobol-xml-code 
        /// </summary>
        /// <param name="indexNames"></param>
        /// <param name="crTmp"></param>
        /// <param name="showString"></param>
        /// <param name="occVars"></param>
        /// <returns></returns>
        private string checkForOccurs(
            Dictionary<string, string> indexNames,
            CobRow crTmp,
            string showString,
            ref string occVars,
            ref string indList)
        {
            return checkForOccurs(
                indexNames,
                crTmp,
                showString,
                ref occVars,
                ref indList,
                false);
        }


        private string checkForOccurs(
            Dictionary<string, string> indexNames,
            CobRow crTmp,
            string showString,
            ref string occVars,
            ref string indList,
            bool displ,
            bool adj = false,
            string tmpInds = "")
        {
            if (crTmp.isOccurs)
            {
                string indVarName = "";
                if (!indexNames.TryGetValue(crTmp.FieldName, out indVarName))
                {
                    indVarName = CobRow.checkLongNames(crTmp.FieldName, 25) + "_ind";
                    indexNames.Add(crTmp.FieldName, indVarName);
                }
                showString += " *> (" + indVarName + ")";
                if (occVars.Length == 0)
                {
                    //if (displ) occVars += "\r\n               " + adjustIf(adj) + "\" ( \" " + indVarName;
                    if (displ)
                    {
                        occVars += "\r\n               " + adjustIf(adj) + "\" ( \" delimited by size ";
                        occVars += "\r\n               " + adjustIf(adj) + indVarName + " delimited by size ";
                    }
                    //                    else occVars += "\r\n               " + adjustIf(adj) + "( " + indVarName;
                    else occVars += "\r\n               " + adjustIf(adj) + indVarName;
                    indList = indVarName;
                }
                else
                {
                    //if (displ) occVars += " \", \"\r\n                     " + adjustIf(adj) + indVarName;
                    if (displ)
                    {
                        occVars += "\r\n                     " + adjustIf(adj) + " \", \" delimited by size ";
                        occVars += "\r\n                     " + adjustIf(adj) + indVarName + " delimited by size ";
                    }
                    //                    else occVars += ",\r\n                 " + adjustIf(adj) + indVarName;
                    else occVars = "\r\n                 " + adjustIf(adj) + indVarName + "," + occVars;
                    indList += "#" + indVarName;
                }
                if (indTemp.Length == 0)
                {
                    indTemp = indVarName;
                }
                else
                {
                    indTemp += "#" + indVarName;
                }
            }
            return showString;
        }


        /// <summary>
        /// Create comment-formatted info about time/date user who has run the tool 
        /// </summary>
        /// <param name="outView"></param>
        /// <param name="typeComm"></param>
        /// <param name="Author"></param>
        /// <param name="Firm"></param>
        public void CreateComment(TextBox outView, string typeComm, string Author, string Firm, string sourceFile = "", bool showJson = false)
        {
            outView.Text = "      *----------------------------------------------------------------*";
            string part1 = string.Empty, part2 = string.Empty;
            centeredComment(outView, typeComm.ToUpper());
            if (sourceFile.Length > 0)
            {
                sourceFile = "( " + sourceFile + " )";
                centeredComment(outView, sourceFile); //, ref marg, ref halvMarg, ref ext);
            }
            outView.Text += "\r\n      *  Date     : " + DateTime.Now.ToShortDateString().PadRight(51) + "*";
            outView.Text += "\r\n      *  Time     : " + DateTime.Now.ToShortTimeString().PadRight(51) + "*";
            outView.Text += "\r\n      *  Author   : " + Author.PadRight(51) + "*";
            outView.Text += "\r\n      *  Company  : " + Firm.PadRight(51) + "*";
            if (showJson)
            {
                if (Cc.jsonPathId.PadRight(51).Length > 51)
                {
                    MapSplit(Cc.jsonPathId, 51, out part1, out part2);
                    outView.Text += "\r\n      *  Json-path: " + part1.PadRight(51) + "*";
                    outView.Text += "\r\n      *    -->    : " + part2.PadRight(51) + "*";
                }
                else outView.Text += "\r\n      *  Json-pth : " + Cc.jsonPathId.PadRight(51) + "*";
                outView.Text += "\r\n      *  Json-in  : " + Cc.CcFileInId.PadRight(51) + "*";
                outView.Text += "\r\n      *  Json-Out : " + Cc.CcFileOutId.PadRight(51) + "*";
            }
            outView.Text += "\r\n      *----------------------------------------------------------------*";
        }

        private void MapSplit(string inStr, int chrs, out string prt1, out string prt2)
        {
            int locLen = inStr.Substring(0, chrs).LastIndexOf("\\");
            prt1 = inStr.Substring(0, locLen);
            prt2 = inStr.Substring(locLen);
        }

        private static void centeredComment(TextBox outView, string centeredText)
        {
            int marg = (64 - centeredText.Length);
            int halvMarg = marg / 2;
            int ext = ((halvMarg + halvMarg) < marg) ? 0 : -1;
            outView.Text += "\r\n      * " + "".PadLeft(marg / 2) + centeredText.PadRight(halvMarg + centeredText.Length + ext) + "*";
        }

        /// <summary>
        /// Create correct qualified Cobol Move specifications for each of the tags
        /// which data can be moved to (Started from a button on the main page)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMoves_Click(object sender, EventArgs e)
        {

            if (chkPerform.Checked)
            {
                CreateMoveToDataExt();
                genExtMoves.Show();
            }
            else
            {
                CreateMoveToData();
                genMoves.Show();
            }
        }



        /// <summary>
        /// Choose file for handling in the openfille dialog
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnChooseFile_Click(object sender, EventArgs e)
        {
            openFile.Title = "Välj XML-fil för generering";
            openFile.InitialDirectory = Environment.SpecialFolder.Recent.ToString();
            openFile.Multiselect = false;
            openFile.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
            if (openFile.ShowDialog() == DialogResult.OK)
            {
                cmbLastFile.Text = openFile.FileName;
            }
        }

        /// <summary>
        /// Create correct qualified Cobol Move specifications for each of the tags
        /// which data can be moved from (Started from a button on the main page)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMoveFrom_Click(object sender, EventArgs e)
        {
            GenerateFromCode(false);
        }

        private void GenerateFromCode(bool inclAttr)
        {
            //if (chkNewArea.Checked)
            //{
            //    CreateMoveDataFromTo();
            //    fromToMoves.Show();
            //}
            //else
            //{
                if (!chkDisplays.Checked)
                {
                    savedFile SF = new savedFile();
                    SF.idConnect = "313728E2-F78E-46CC-A448-F6A6F54319AB";
                    SF.usageName = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Unload";
                    SF.fNameSaved = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Unload.cbl";
                    createXMLMoveCode(SF, true, inclAttr);
                }
                else
                {

                    CreateMoveFromData();
                    fromMoves.Show();
                }
            //}
        }

        private string adjustIf(bool ifTrue)
        {
            string tmp = "";
            if (ifTrue)
            {
                tmp = "".PadLeft(4);
            }
            return tmp;
        }

        private void cmbLastFile_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (S.ettingActualFile != null)
            {
                GenSetting tmpSetting = new GenSetting();
                this.sl.Subscribe(tmpSetting);
                tmpSetting.GetSettings();
                this.sl.UnSubscribe(tmpSetting);
            }
            S.ettingActualFile = cmbLastFile.Text.Substring(cmbLastFile.Text.LastIndexOf("\\") + 1);
            GenSetting tmpGS = null;
            sl.dict.TryGetValue(S.ettingActualFile, out tmpGS);
            if (tmpGS != null)
            {
                tmpGS.SetSettings();
                setLocalValues();
            }
            else
            {
                S.ettingList = null;
            }

            runXMLgen();
        }

        private void GenCobCode_FormClosing(object sender, FormClosingEventArgs e)
        {

            GenSetting tmpGS = new GenSetting();
            this.sl.Subscribe(tmpGS);
            tmpGS.GetSettings();
            this.sl.UnSubscribe(tmpGS);

            Properties.Settings.Default.LastFile.Clear();
            foreach (string savedFile in cmbLastFile.Items)
            {
                Properties.Settings.Default.LastFile.Add(savedFile);
            }
            Properties.Settings.Default.CompanyName = S.ettingCompany;
            Properties.Settings.Default.UserName = S.ettingUserName;
            Properties.Settings.Default.Save();


            SerializeMetadata();
        }

        private void SerializeMetadata()
        {
            string SavePath = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]).ToString();
            GenSetting[] saveColl = new GenSetting[setObjs.Count];
            int i = 0;
            foreach (GenSetting x in setObjs.Values)
            {
                saveColl[i++] = x;
            }

            try
            {
                XmlSerializer x = new XmlSerializer(saveColl.GetType());
                StreamWriter writer = new StreamWriter(SavePath + "\\FilnamnsDict.new", false);
                x.Serialize(writer, saveColl);
                //MessageBox.Show("Objektet är serialiserat !(" + SavePath + "\\FilnamnsDict.xml)");
                writer.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Serialisering : " + ex.Message);
            }

            long lNewSize = fileSize(SavePath + "\\FilnamnsDict.new");
            long lOldSize = fileSize(SavePath + "\\FilnamnsDict.xml");

            if (lNewSize > 0 && lNewSize >= lOldSize)
            {
                try
                {
                    File.Replace(SavePath + "\\FilnamnsDict.new", SavePath + "\\FilnamnsDict.xml", SavePath + "\\FilnamnsDict.old");
                }
                catch (FileNotFoundException)
                {
                    File.Move(SavePath + "\\FilnamnsDict.new", SavePath + "\\FilnamnsDict.xml");
                    File.Move(SavePath + "\\FilnamnsDict.xml", SavePath + "\\FilnamnsDict.old");
                }
                //                File.Move(SavePath + "\\FilnamnsDict.xml", SavePath + "\\FilnamnsDict.old");
                //              File.Move(SavePath + "\\FilnamnsDict.new", SavePath + "\\FilnamnsDict.xml");
            }

        }

        private long fileSize(string fileStr)
        {
            FileInfo fi;
            try
            {
                fi = new FileInfo(fileStr);
                return fi.Length;
            }
            catch (Exception)
            {
                return 0;
            }
        }


        private void btnClearSettings_Click(object sender, EventArgs e)
        {
            cmbLastFile.Items.Clear();
            cmbLastFile.Text = "";
        }

        private void chkWrap_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingWrap = chkWrap.Checked;
            if (!eventRun) runXMLgen();
        }

        private void chkNoNsRef_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingNoNsRef = chkNoNsRef.Checked;
            if (!eventRun)
            {
                eventRun = true;
                chkCountVars.Checked = true;
                eventRun = false;
                runXMLgen();
            }
        }

        private void chkAnaTag_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingAnaTag = chkAnaTag.Checked;
            if (!eventRun) runXMLgen();
        }

        private void chkValues_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingValues = chkValues.Checked;
            if (!eventRun) runXMLgen();
        }

        private void chkUniqueAttrVars_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingUniqueAttrVars = chkUniqueAttrVars.Checked;
            if (!eventRun) runXMLgen();
        }

        private void chkUnique_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingUnique = chkUnique.Checked;
            if (!eventRun) runXMLgen();
        }

        private void chkUniqueVars_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingUniqueVars = chkUniqueVars.Checked;
            if (!eventRun) runXMLgen();
        }

        private void chkCountVars_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingCountVars = chkCountVars.Checked;
            if (!eventRun) runXMLgen();
        }

        private void btnSettings_Click(object sender, EventArgs e)
        {
            runSetWindow();
            runXMLgen();
        }

        private void runSetWindow(bool chooseFile=false)
        {
            if (setWindow == null)
            {
                setWindow = new frmSettings();
                setWindow.SL = this.sl;
                setWindow.SettingObj = new GenSetting();
                if (chooseFile)
                {
                    setWindow.VisaFilVal = chooseFile;
                }
            }

            eventRun = true;

            setWindow.ShowDialog();

            setLocalValues();

            eventRun = false;
        }

        private void setLocalValues()
        {
            eventRun = true;
            chkAnaTag.Checked = S.ettingAnaTag; chkAnaTag.Refresh();
            chkCountVars.Checked = S.ettingCountVars; chkCountVars.Refresh();
            chkDisplays.Checked = S.ettingDisplays;
            chkDisplays.Refresh();
            chkNoNsRef.Checked = S.ettingNoNsRef;
            chkNoNsRef.Refresh();
            chkUnique.Checked = S.ettingUnique;
            chkUnique.Refresh();
            chkUniqueAttrVars.Checked = S.ettingUniqueAttrVars;
            chkUniqueAttrVars.Refresh();
            chkUniqueVars.Checked = S.ettingUniqueVars;
            chkUniqueVars.Refresh();
            chkValues.Checked = S.ettingValues;
            chkValues.Refresh();
            chkWrap.Checked = S.ettingWrap;
            chkWrap.Refresh();
            txtMaxOcc.Text = S.ettingMaxOcc;
            txtMaxOcc.Refresh();
            txtPrefix.Text = S.ettingPrefix;
            txtPrefix.Refresh();
            txtExpPrefix.Text = S.ettingExpPrefix;
            txtExpPrefix.Refresh();
            btnTestThings.Visible = S.ettingShowTestbtns;
            btnTestThings.Refresh();
            btnCrossref.Visible = S.ettingShowTestbtns;
            btnCrossref.Refresh();
            chkBackupVars.Checked = S.ettingUserCodeBcup;
            chkBackupVars.Refresh();
            eventRun = false;
        }



        private void CreateMoveToData()
        {
            Dictionary<string, string> indexNames = new Dictionary<string, string>();
            string IndVarText = "      *--------------------------------------------------*\r\n      * Extra indexvariabler för occurs-taggar   --------*\r\n      *--------------------------------------------------*";
            string slask = "";
            genMoves = new ShowCode();
            genMoves.FormParent = this;
            genMoves.Labeltext = "Creating \"move to\" Code";
            //            CreateComment(genMoves.CodeShower, "Moves to", "Tommy Öman", "Fordonsdata Nordic AB");

            savedFile SF = new savedFile();
            SF.idConnect = "6EFF8B31-7F88-4A81-B94E-41D54A3D3197";
            SF.usageName = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Load";
            SF.fNameSaved = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Load.cbl";
            genMoves.SavedFile = SF;

            foreach (CobRow cr in rowList)
            {
                string occParRows = "";
                if (cr.CobLevel < 2)
                {
                    string inFile = cmbLastFile.Text.Substring(cmbLastFile.Text.LastIndexOf("\\") + 1);
                    CreateComment(genMoves.CodeShower, "Moves to " + cr.FieldName, S.ettingUserName, S.ettingCompany, inFile);
                }
                if (!cr.isAttribute && !cr.SampleStr.Equals(NOMOVE))
                {
                    CobRow crTmp = cr;
                    //                    genMoves.CodeShower.Text += "\r\n           " + "MOVE \"#" + cr.FieldName + "#\"\r\n               TO " + cr.FieldName;
                    if (cr.Value.Length > 0)
                    {
                        genMoves.CodeShower.Text += "\r\n           " + "MOVE " + cr.Value + "\r\n               TO " + cr.FieldName;
                    }
                    else genMoves.CodeShower.Text += "\r\n           " + "MOVE " + cr.SampleStr + "\r\n               TO " + cr.FieldName;
                    genMoves.CodeShower.Text = checkForOccurs(indexNames, cr, genMoves.CodeShower.Text, ref occParRows, ref slask);
                    while (crTmp.LevelParent != null)
                    {
                        crTmp = crTmp.LevelParent;
                        genMoves.CodeShower.Text += "\r\n               OF " + crTmp.FieldName;
                        genMoves.CodeShower.Text = checkForOccurs(indexNames, crTmp, genMoves.CodeShower.Text, ref occParRows, ref slask);
                    }
                    if (occParRows.Length > 0)
                    {
                        genMoves.CodeShower.Text += " (" + occParRows + " )\r\n";
                    }
                }
            }
            genMoves.CodeShower.Text = addOccursVars(indexNames, genMoves.CodeShower.Text, IndVarText);
        }

        private void CreateMoveToDataExt()
        {
            Dictionary<string, string> indexNames = new Dictionary<string, string>();
            string IndVarText = "      *--------------------------------------------------*\r\n      * Extra indexvariabler för occurs-taggar   --------*\r\n      *--------------------------------------------------*";
            string aktIndList = "", slask = "", slask2 = "", struktMove = ""; ;
            IndexState Is = new IndexState(indexNames, rowList);
            genExtMoves = new ShowCode();
            genExtMoves.FormParent = this;
            genExtMoves.Labeltext = "Creating \"move to (with loop)\" Code";

            savedFile SF = new savedFile();
            SF.idConnect = "5DC1D9E6-DD38-4DD7-9DCB-203ABCE96B47";
            SF.usageName = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Load";
            SF.fNameSaved = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Load.cbl";
            genExtMoves.SavedFile = SF;

            bool adj = false;
            int prfNiv = 0;

            foreach (CobRow cr in rowList)
            {
                string occParRows = "";
                if (cr.CobLevel < 2)
                {
                    string inFile = cmbLastFile.Text.Substring(cmbLastFile.Text.LastIndexOf("\\") + 1);
                    CreateComment(genExtMoves.CodeShower, "Moves to (with loop) " + cr.FieldName, S.ettingUserName, S.ettingCompany, inFile);
                }
                // Header square created

                if (!cr.isAttribute && !cr.SampleStr.Equals(NOMOVE))
                {
                    // No attribute and not unmoveable (by "NOMOVE"-principle)

                    if (cr.CountIn.Length > 0)
                    {
                        adj = true;
                        string fejkRow = "";
                        CobRow crChk = cr;
                        // Get index - variables per field (where "OCCURS" exists)
                        if (cr.FieldDef.Length < 1)
                        {
                            fejkRow = checkForOccurs(indexNames, cr, genExtMoves.CodeShower.Text, ref occParRows, ref aktIndList);
                        }
                        // the first is for present row
                        while (crChk.LevelParent != null)
                        {
                            crChk = crChk.LevelParent;
                            fejkRow += "\r\n               OF " + crChk.FieldName;
                            fejkRow = checkForOccurs(indexNames, crChk, genExtMoves.CodeShower.Text, ref occParRows, ref aktIndList);
                        }
                        //  Here a test giving header for new iter-group would be created
                        //  Debug.WriteLine(aktIndList);
                        string tmpPerfCode = Is.PresentStrings(aktIndList);
                        if (tmpPerfCode.Length > 0)
                        {
                            struktMove += AdjPerfNiv(tmpPerfCode, ref prfNiv);
                        }
                        genExtMoves.CodeShower.Text += tmpPerfCode; // Is.PresentStrings(aktIndList);

                        //  Until here---

                        genExtMoves.CodeShower.Text += "\r\n           MOVE ";

                        if (cr.Move_Code == null || cr.Move_Code.Trim().Length < 1)
                            genExtMoves.CodeShower.Text += "0";
                        else
                            genExtMoves.CodeShower.Text += "1";

                        genExtMoves.CodeShower.Text += " TO " + cr.CountIn;

                        if (occParRows.Length > 0)
                        {
                            genExtMoves.CodeShower.Text += " (" + occParRows + " )";
                        }

                        genExtMoves.CodeShower.Text += "\r\n           IF " + cr.CountIn;
                        if (occParRows.Length > 0)
                        {
                            genExtMoves.CodeShower.Text += " (" + occParRows + " )";
                        }

                        genExtMoves.CodeShower.Text += "\r\n                > 0";
                        occParRows = "";
                    }
                    CobRow crTmp = cr;
                    struktMove += "\r\n           " + "".PadLeft(prfNiv) + " <" + cr.TagName.Replace("\"", "") + "> (" + cr.FieldName + ")";

                    genExtMoves.CodeShower.Text += "\r\n"; //"           " + adjustIf(adj);
                    //------------- move from --------------

                    //---------------- Changed 
                    //if (cr.MoveCode.Length > 1 && cr.MoveCode != " ")
                    if (cr.Move_Code == null || cr.Move_Code.Trim() == "")
                    {
                        if (cr.FieldDef.ToUpper().IndexOf("X") > -1)
                        {
                            genExtMoves.CodeShower.Text += "           " + adjustIf(adj) + "MOVE MoveToStringVar ";
                        }
                        else
                        {
                            genExtMoves.CodeShower.Text += "           " + adjustIf(adj) + "MOVE MoveToNumVar ";
                        }
                        genExtMoves.CodeShower.Text += "      *> #" + cr.FieldName + "#";
                    }
                    else
                    {
                        if (cr.MoveCode.ToUpper().Contains("MOVE") || (cr.MoveCode.ToUpper().Contains("STRING") && cr.MoveCode.ToUpper().Contains("INTO"))) { }
                        else genExtMoves.CodeShower.Text += "MOVE ";
                        genExtMoves.CodeShower.Text += cr.MoveCode;
                    }

                    //---------------- Changed 
                    //if (cr.MoveCode.Length > 1 && cr.MoveCode != " ")
                    //{
                    //    if (cr.MoveCode.ToUpper().Contains("MOVE") || (cr.MoveCode.ToUpper().Contains("STRING") && cr.MoveCode.ToUpper().Contains("INTO"))) { }
                    //    else genExtMoves.CodeShower.Text += "MOVE ";
                    //    genExtMoves.CodeShower.Text += cr.MoveCode;
                    //}
                    //else
                    //{
                    //    if (cr.FieldDef.ToUpper().IndexOf("X") > -1)
                    //    {
                    //        genExtMoves.CodeShower.Text += "           " + adjustIf(adj)+"MOVE MoveToStringVar ";
                    //    }
                    //    else
                    //    {
                    //        genExtMoves.CodeShower.Text += "           " + adjustIf(adj)+ "MOVE MoveToNumVar ";
                    //    }
                    //    genExtMoves.CodeShower.Text += "      *> #" + cr.FieldName + "#";
                    //}

                    //------------- move to ---------------
                    genExtMoves.CodeShower.Text += "\r\n           " + adjustIf(adj);

                    if (cr.MoveCode == null)
                        genExtMoves.CodeShower.Text += "TO ";
                    else
                    {
                        if (cr.MoveCode.ToUpper().Contains("STRING") && cr.MoveCode.ToUpper().Contains("INTO")) { }
                        else genExtMoves.CodeShower.Text += "TO ";
                    }
                    genExtMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + cr.FieldName;
                    genExtMoves.CodeShower.Text = checkForOccurs(indexNames, cr, genExtMoves.CodeShower.Text, ref occParRows, ref slask, false, adj);
                    while (crTmp.LevelParent != null)
                    {
                        crTmp = crTmp.LevelParent;
                        genExtMoves.CodeShower.Text += "\r\n        " + adjustIf(adj) + "       OF " + crTmp.FieldName;
                        genExtMoves.CodeShower.Text = checkForOccurs(indexNames, crTmp, genExtMoves.CodeShower.Text, ref occParRows, ref slask, false, adj);
                    }
                    if (occParRows.Length > 0)
                    {
                        genExtMoves.CodeShower.Text += " (" + occParRows + " )";
                    }

                    if (cr.MoveCode == null) { }
                    else
                    {
                        if (cr.MoveCode.ToUpper().Contains("STRING") && cr.MoveCode.ToUpper().Contains("INTO"))
                        {
                            genExtMoves.CodeShower.Text += "\r\n        " + adjustIf(adj) + "END-STRING ";
                        }
                    }

                    if (chkMvToDisp.Checked)
                    {
                        occParRows = "";
                        CobRow crTmpx = cr;
                        genExtMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "Display \"" + cr.FieldName + "\"";
                        while (crTmpx.LevelParent != null)
                        {
                            crTmpx = crTmpx.LevelParent;
                            genExtMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "\" OF " + crTmpx.FieldName + "\"";
                            genExtMoves.CodeShower.Text = checkForOccurs(indexNames, crTmpx, genExtMoves.CodeShower.Text, ref occParRows, ref slask2, true);
                        }
                        if (occParRows.Length > 0)
                        {
                            genExtMoves.CodeShower.Text += occParRows + " \")\"";
                        }
                        if (cr.FieldDef.ToUpper().IndexOf("X") > -1)
                        {
                            genExtMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "\" = \"  MoveToStringVar ";
                        }
                        else genExtMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "\" = \"  MoveToNumVar ";
                    }
                    if (cr.CountIn.Length > 0)
                    {
                        genExtMoves.CodeShower.Text += "\r\n           END-IF ";
                    }

                }
            }

            string tmpPerfCode2 = Is.PresentStrings("");
            struktMove += AdjPerfNiv(tmpPerfCode2, ref prfNiv);
            genExtMoves.CodeShower.Text += tmpPerfCode2; //Is.PresentStrings("");
            string varAndStructAdditions = "";
            varAndStructAdditions = addOccursVars(indexNames, varAndStructAdditions, IndVarText);
            varAndStructAdditions += "\r\n       01 MoveToNumVar         PIC 9(12).";
            varAndStructAdditions += "\r\n       01 MoveToStringVar      PIC X(500).";
            if (Is.ProcStr.Length > 0)
            {
                varAndStructAdditions += "\r\n      *================ Extra procs =====================*\r\n";
                varAndStructAdditions += Is.ProcStr;
                varAndStructAdditions += "\r\n      *================ Extra procs =====================*\r\n";
            }
            varAndStructAdditions += "\r\n      *--------------------------Strukturlistning ------*\r\n";
            varAndStructAdditions += struktMove.Replace("\r\n        ", "\r\n      *>") + "\r\n";
            varAndStructAdditions += "\r\n      *------------------------- Strukturlistning ------*\r\n";
            genExtMoves.CodeShower.Text = varAndStructAdditions + "\r\n" + genExtMoves.CodeShower.Text;

            tmpRowList = new List<CobRow>();
            foreach (string frmRow in genExtMoves.CodeShower.Lines)
            {
                tmpRowList.Add(new CobRow(frmRow, false));
            }
            genExtMoves.CodeShower.Text = "";
            tmpRowList.ForEach(delegate(CobRow crtmp)
            {
                genExtMoves.CodeShower.Text += crtmp.wrapped() + "\r\n";
            });
        }

        private string AdjPerfNiv(string inStr, ref int prfNiv)
        {
            string tmpWrk = inStr;
            string[] tmpRows = Regex.Split(tmpWrk, "\r\n");
            tmpWrk = "";
            foreach (string row in tmpRows)
            {
                if (row.Contains(" END-PERFORM"))
                {
                    prfNiv -= 2;
                }
                if (row.Length > 0)
                {
                    tmpWrk += "\r\n" + "".PadLeft(prfNiv) + row;
                }
                if (row.Contains(" PERFORM VARYING"))
                {
                    prfNiv += 2;
                }
            }
            return tmpWrk;
        }

        private void CreateMoveFromData()
        {
            Dictionary<string, string> indexNames = new Dictionary<string, string>();
            string IndVarText = "      *--------------------------------------------------*\r\n      * Extra indexvariabler för occurs-taggar   --------*\r\n      *--------------------------------------------------*";
            string aktIndList = "", slask = "", slask2 = "";
            IndexState Is = new IndexState(indexNames, rowList, false);
            fromMoves = new ShowCode();
            fromMoves.FormParent = this;
            fromMoves.Labeltext = "Creating \"move from\" Code";

            savedFile SF = new savedFile();
            SF.idConnect = "9C3E8CC7-FA20-4E11-8E81-73BE8D2E9CFB";
            SF.usageName = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Unload";
            SF.fNameSaved = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Unload.cbl";
            fromMoves.SavedFile = SF;

            bool adj = false;

            foreach (CobRow cr in rowList)
            {
                string occParRows = "";
                if (cr.CobLevel < 2)
                {
                    string inFile = cmbLastFile.Text.Substring(cmbLastFile.Text.LastIndexOf("\\") + 1);
                    CreateComment(fromMoves.CodeShower, "Moves from " + cr.FieldName, S.ettingUserName, S.ettingCompany, inFile);
                }
                if (!cr.isAttribute && !cr.SampleStr.Equals(NOMOVE))
                {

                    if (chkDisplays.Checked && cr.CountIn.Length > 0)
                    {
                        adj = true;
                        string fejkRow = "";
                        CobRow crChk = cr;
                        indTemp = "";
                        while (crChk.LevelParent != null)
                        {
                            //                            crChk = crChk.LevelParent;
                            fejkRow += "\r\n               OF " + crChk.FieldName;
                            fejkRow = checkForOccurs(indexNames, crChk, fromMoves.CodeShower.Text, ref occParRows, ref aktIndList);
                            crChk = crChk.LevelParent;
                        }
                        aktIndList = reduceIndList(aktIndList, indTemp);
                        //  Here a test giving header for new iter-group would be created

                        fromMoves.CodeShower.Text += Is.PresentStrings(aktIndList);
                        //  Until here---
                        fromMoves.CodeShower.Text += "\r\n           IF " + cr.CountIn;
                        if (occParRows.Length > 0)
                        {
                            fromMoves.CodeShower.Text += "( " + occParRows + " )";
                        }

                        fromMoves.CodeShower.Text += "\r\n                > 0";
                        occParRows = "";
                    }
                    CobRow crTmp = cr;
                    fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "MOVE " + cr.FieldName;
                    fromMoves.CodeShower.Text = checkForOccurs(indexNames, cr, fromMoves.CodeShower.Text, ref occParRows, ref slask, false, adj);
                    while (crTmp.LevelParent != null)
                    {
                        crTmp = crTmp.LevelParent;
                        fromMoves.CodeShower.Text += "\r\n        " + adjustIf(adj) + "       OF " + crTmp.FieldName;
                        fromMoves.CodeShower.Text = checkForOccurs(indexNames, crTmp, fromMoves.CodeShower.Text, ref occParRows, ref slask, false, adj);
                    }
                    if (occParRows.Length > 0)
                    {
                        fromMoves.CodeShower.Text += "( " + occParRows + " )";
                    }
                    fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "TO ";
                    if (cr.Move_FromCode.Trim().Length > 0)
                    {
                        fromMoves.CodeShower.Text += cr.MoveFromCode;
                    }
                    else
                    {
                        if (cr.FieldDef.ToUpper().IndexOf("X") > -1)
                        {
                            fromMoves.CodeShower.Text += "MoveToStringVar ";
                        }
                        else
                        {
                            fromMoves.CodeShower.Text += "MoveToNumVar ";
                        }
                    }
                    fromMoves.CodeShower.Text += " *> #" + cr.FieldName + "#";
                    if (chkDisplays.Checked)
                    {
                        occParRows = "";
                        CobRow crTmpx = cr;

                        fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "Move space to " + S.ettingLogVarName + " ";
                        fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "String ";

                        if (cr.Move_FromCode.Trim().Length > 0)
                        {
                            fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + cr.MoveFromCode + " delimited by \"   \" ";
                        }
                        else
                        {
                            if (cr.FieldDef.ToUpper().IndexOf("X") > -1)
                            {
                                fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "MoveToStringVar delimited by \"   \" ";
                            }
                            else fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "MoveToNumVar delimited by size";
                        }

                        fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "\" <= \" delimited by size ";
                        fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "\"" + cr.FieldName + "\" delimited by size ";
                        while (crTmpx.LevelParent != null)
                        {
                            crTmpx = crTmpx.LevelParent;
                            fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "\" OF " + crTmpx.FieldName + "\" delimited by size";
                            fromMoves.CodeShower.Text = checkForOccurs(indexNames, crTmpx, fromMoves.CodeShower.Text, ref occParRows, ref slask2, true);
                        }
                        if (occParRows.Length > 0)
                        {
                            fromMoves.CodeShower.Text += occParRows;
                            fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + " \")\" delimited by size";
                        }
                        fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "Into " + S.ettingLogVarName;
                        fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "End-String";
                        fromMoves.CodeShower.Text += "\r\n           " + adjustIf(adj) + "Perform " + S.ettingLogSectName;
                    }
                    if (chkDisplays.Checked && cr.CountIn.Length > 0)
                    {
                        fromMoves.CodeShower.Text += "\r\n           END-IF ";
                    }

                }
            }

            fromMoves.CodeShower.Text += Is.PresentStrings("");

            fromMoves.CodeShower.Text = "       01 MoveToNumVar         PIC 9(12).\r\n" + fromMoves.CodeShower.Text;
            fromMoves.CodeShower.Text = "\r\n       01 MoveToStringVar      PIC X(500).\r\n" + fromMoves.CodeShower.Text;
            fromMoves.CodeShower.Text = addOccursVars(indexNames, fromMoves.CodeShower.Text, IndVarText);

            tmpRowList = new List<CobRow>();
            foreach (string frmRow in fromMoves.CodeShower.Lines)
            {
                tmpRowList.Add(new CobRow(frmRow, false));
            }
            fromMoves.CodeShower.Text = "";
            tmpRowList.ForEach(delegate(CobRow crtmp)
            {
                fromMoves.CodeShower.Text += crtmp.wrapped() + "\r\n";
            });

        }

        private string reduceIndList(string aktIndList, string indTemp)
        {

            string[] extList = aktIndList.Split(splitChars);
            string[] jmfList = indTemp.Split(splitChars);
            string resStr = "";

            if (extList.Length > 0)
            {
                foreach (string txtInd in extList)
                {
                    if (jmfList.Contains(txtInd))
                    {
                        resStr += (resStr.Length > 0) ? "#" : "";
                        resStr += txtInd;
                    }
                }
            }

            return resStr;
        }


        private void outCob_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.A)
            {
                outCob.SelectAll();
            }
        }


        private void createXMLMoveCode(savedFile SF, bool justOut = false, bool inclAttribs = false)
        {
            bool loopTyp = false;
            string SectionNames = "", BoolVars = "";
            qualifieldhlp locTmpQfh = null;
            Stack<string> indexStack = new Stack<string>();

            //Create showing window
            fromToMoves = new ShowCode();
            fromToMoves.FormParent = this;
            if (!justOut)
            {
                fromToMoves.Labeltext = "Created \"move From To\" Code";
            }
            else fromToMoves.Labeltext = "Created \"move From \" Code";


            //savedFile SF = new savedFile();
            //SF.idConnect = "598A5F20-9A8A-415D-81B2-BBFE04465381";
            //SF.usageName = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Unload";
            //SF.fNameSaved = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Unload.cbl";
            fromToMoves.SavedFile = SF;


            //Dictionary for indexes, init IndexState class and list for qualifiedHelper class
            Dictionary<string, string> testIndexes = new Dictionary<string, string>();
            IndexState lIs = new IndexState(testIndexes, rowList);
            qldList = new List<qualifieldhlp>();

            //Build the qualified helper object for each xml-record fieal (eg XMLTag)
            foreach (CobRow zRow in rowList)
            {
                qualifieldhlp tmpQlh = new qualifieldhlp(zRow, lIs.Indexes);
                qldList.Add(tmpQlh);
            }
            //Indstatus keep track on present changings concerning indexes qualifying each qualified XML-record-field
            IndStatus indSt = new IndStatus();

            //here comes the central work-loop
            foreach (qualifieldhlp tmpQfh in qldList)
            {

                //Create header information on created text
                if (tmpQfh.qualCobRow.CobLevel < 2)
                {
                    string inFile = cmbLastFile.Text.Substring(cmbLastFile.Text.LastIndexOf("\\") + 1);
                    CreateComment(fromToMoves.CodeShower, "Moves from " + tmpQfh.qualCobRow.FieldName, S.ettingUserName, S.ettingCompany, inFile);
                    fromToMoves.CodeShower.Text += "\r\n";
                }

                // inclAttribs)
                //if (!tmpQfh.qualCobRow.isAttribute && !tmpQfh.qualCobRow.SampleStr.Equals(NOMOVE))
                if (bringAttrs(tmpQfh,inclAttribs))
                {

                    //IndStatus-object takes care of optionally occuring indexes 
                    indSt.handleStatus(tmpQfh.indexStrings);

                    //If indexes get out of scope there will come an END-PERFORM for each
                    for (int i = 0; i < indSt.Returns; i++)
                    {
                        string xtIndex = indexStack.Pop();
                        string chosenKey = testIndexes.FirstOrDefault(x => x.Value == xtIndex).Key;  // indexes = <FieldName , FieldIndex> search FieldName from present FieldIndex
                        locTmpQfh = qldList.First(x => x.qualCobRow.FieldName == chosenKey); // Find QualifiedHelp-object for right field 

                        if (chkEvents.Checked)
                        {
                            fromToMoves.CodeShower.Text += "           PERFORM  " + createAftReferenceSections(locTmpQfh.qualCobRow.TagName, "LAST-in-",
                                                                       xtIndex, ref SectionNames) + "\r\n";
                        }
                        fromToMoves.CodeShower.Text += "           END-PERFORM" + "\r\n";
                    }

                    //Each index comming into scope will start a new PERFORM VARYING loop
                    if (indSt.NewInds != null)
                    {
                        foreach (string indTxt in indSt.NewInds)
                        {
                            //                            if (!justOut)
                            //                            {
                            //Before perform varying, move the count-value from old structure to new
                            string chosenKey = testIndexes.FirstOrDefault(x => x.Value == indTxt).Key;  // indexes = <FieldName , FieldIndex> search FieldName from present FieldIndex
                            locTmpQfh = qldList.First(x => x.qualCobRow.FieldName == chosenKey); // Find QualifiedHelp-object for right field 
                            if (!justOut)
                            {
                                fromToMoves.CodeShower.Text += "           MOVE " + locTmpQfh.qualCobRow.CountIn + "\r\n" + locTmpQfh.indexRedText;
                                fromToMoves.CodeShower.Text += "           TO " +
                                    locTmpQfh.qualCobRow.CountIn.ToString().Replace(S.ettingPrefix, S.ettingExpPrefix) + "\r\n" + locTmpQfh.indexRedText;
                            }
                            //Perform
                            fromToMoves.CodeShower.Text += "           PERFORM VARYING " + indTxt + " FROM 1 BY 1\r\n           UNTIL " +
                                indTxt + "\r\n            > " + locTmpQfh.qualCobRow.CountIn.ToString() + "\r\n" + locTmpQfh.indexRedText;

                            //string tmpCheckVar = "";
                            indexStack.Push(indTxt);
                            if (chkEvents.Checked)
                            {

                                fromToMoves.CodeShower.Text += "               PERFORM  " + createAftReferenceSections(locTmpQfh.qualCobRow.TagName, "FIRST-in-",
                                                            indTxt, ref SectionNames) + "\r\n";
                            }
                        }
                    }

                    //When count-variable is put on a "Value" XML-record-field the the count-value isnt correctly updated so better always move the value as is
                    if (tmpQfh.qualCobRow.FieldName.ToUpper().Contains("_VALUE")) { }
                    else
                    {
                        //when xml-record-field with occurs, the last index shall not be used (then use tmpQfh.indexRedText instead of tmpQfh.indexText
                        loopTyp = tmpQfh.qualCobRow.isOccurs;
                        fromToMoves.CodeShower.Text += "           IF " + tmpQfh.qualCobRow.CountIn.ToString() + "\r\n" +
                            (string)(loopTyp ? tmpQfh.indexRedText : tmpQfh.indexText) + "           > 0 \r\n";
                    }

                    //The acutal move of present fields
                    fromToMoves.CodeShower.Text += "           MOVE " + tmpQfh.ToString();
                    if (!justOut)
                    {
                        fromToMoves.CodeShower.Text += "           TO " + tmpQfh.ToExpString();
                        if (tmpQfh.qualCobRow.Move_FromCode != null && tmpQfh.qualCobRow.Move_FromCode.Trim().Length > 0)
                        {
                            fromToMoves.CodeShower.Text += tmpQfh.qualCobRow.MoveFromCode + "\r\n";
                        }
                    }
                    else
                    {
                        if (tmpQfh.qualCobRow.Move_FromCode != null && tmpQfh.qualCobRow.Move_FromCode.Trim().Length > 0)
                        {
                            //if (tmpQfh.qualCobRow.MoveFromCode.IndexOf("<?>") > -1 || tmpQfh.qualCobRow.MoveFromCode.IndexOf("<NYPOST>") > -1)
                            //{
                            //    fromToMoves.CodeShower.Text += "         *>" + tmpQfh.qualCobRow.MoveFromCode + "\r\n";
                            //    fromToMoves.CodeShower.Text += "           TO " +
                            //        (string)(tmpQfh.qualCobRow.FieldDef.ToUpper().Contains("X") ? "MoveToStringVar" : "MoveToNumVar") + "\r\n";
                            //}
                            //else
                            //{
                            fromToMoves.CodeShower.Text += tmpQfh.qualCobRow.MoveFromCode + "\r\n";
                            //}
                        }
                        else
                        {
                            fromToMoves.CodeShower.Text += "           TO " +
                                (string)(tmpQfh.qualCobRow.FieldDef.ToUpper().Contains("X") ? "MoveToStringVar" : "MoveToNumVar") + "\r\n";
                        }
                    }

                    if (!justOut)
                    {
                        if (tmpQfh.qualCobRow.FieldName.ToUpper().Contains("_VALUE")) { }
                        else
                        {
                            fromToMoves.CodeShower.Text += "           MOVE " + tmpQfh.qualCobRow.CountIn + "\r\n" +
                                (string)(loopTyp ? tmpQfh.indexRedText : tmpQfh.indexText);
                            fromToMoves.CodeShower.Text += "           TO " +
                                tmpQfh.qualCobRow.CountIn.ToString().Replace(S.ettingPrefix, S.ettingExpPrefix) + "\r\n" +
                                (string)(loopTyp ? tmpQfh.indexRedText : tmpQfh.indexText);
                            fromToMoves.CodeShower.Text += "           ELSE\r\n";
                            fromToMoves.CodeShower.Text += "           MOVE 0 TO " +
                                tmpQfh.qualCobRow.CountIn.ToString().Replace(S.ettingPrefix, S.ettingExpPrefix) + "\r\n" +
                                (string)(loopTyp ? tmpQfh.indexRedText : tmpQfh.indexText);
                            fromToMoves.CodeShower.Text += "           END-IF\r\n";
                        }
                    }
                    else
                    {
                        if (tmpQfh.qualCobRow.FieldName.ToUpper().Contains("_VALUE")) { }
                        else
                        {
                            fromToMoves.CodeShower.Text += "           END-IF\r\n";
                        }
                    }
                }
            }

            // get optionally occuring last END-PERFORMs...
            indSt.handleStatus(null);
            for (int i = 0; i < indSt.Returns; i++)
            {
                fromToMoves.CodeShower.Text += "           END-PERFORM" + "\r\n";
            }

            fromToMoves.CodeShower.Text = SectionNames + "\r\n" + fromToMoves.CodeShower.Text;
            fromToMoves.CodeShower.Text = BoolVars + "\r\n" + fromToMoves.CodeShower.Text;
            //List all used indexes
            string tempIndText = "";
            fromToMoves.CodeShower.Text = addOccursVars(testIndexes, fromToMoves.CodeShower.Text, tempIndText);

            fromToMoves.Show();

        }

        private bool bringAttrs(qualifieldhlp qfh, bool yes)
        {
            if (yes)
                return (!qfh.qualCobRow.SampleStr.Equals(NOMOVE));
            else
                return (!qfh.qualCobRow.isAttribute && !qfh.qualCobRow.SampleStr.Equals(NOMOVE));
        }

        private string createAftReferenceSections(string tagName, string procPrefix, string indexVar, ref string wrkSectStr)
        {
            string tmpProcName = procPrefix + tagName.Replace("\"", "").Replace(":", "") + "-x";
            if (!wrkSectStr.Contains(tmpProcName + "-x"))
            {
                wrkSectStr += "\r\n      *>------------------- HANDLE SECTION --------------*" + tmpProcName;
                wrkSectStr += "\r\n      * Den här sektionen används för att positionera ";
                wrkSectStr += "\r\n      * datat när den genererade xml-proceduren körs";
                wrkSectStr += "\r\n      *-------------------- HANDLE SECTION --------------*\r\n";
                wrkSectStr += "\r\n       " + tmpProcName + " SECTION.";
                wrkSectStr += "\r\n      *    Styrs av :" + indexVar;
                wrkSectStr += "\r\n           .";
                wrkSectStr += "\r\n       " + tmpProcName + "-EX.";
                wrkSectStr += "\r\n           EXIT.\r\n";

            }
            return tmpProcName;
        }


        private void btnFrXMLTo_Click(object sender, EventArgs e)
        {
            savedFile SF = new savedFile();
            SF.idConnect = "ECCF8A4D-64A6-4674-84F0-C62CEAD19632";
            SF.usageName = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Transfer";
            SF.fNameSaved = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Transfer.cbl";
            createXMLMoveCode(SF);
        }

        private void btnTestThings_Click(object sender, EventArgs e)
        {
            //Create showing window
            loadResWords();
            fromToMoves = new ShowCode();
            fromToMoves.FormParent = this;
            fromToMoves.Labeltext = "Cobol \"reserved\" Words";

            savedFile SF = new savedFile();
            SF.idConnect = "DD5A8C24-C322-4901-85B5-776DD6E21FB9";
            SF.usageName = "Cobol_Reserved_Words";
            SF.fNameSaved = "Cobol_Reserved_Words.txt";
            fromToMoves.SavedFile = SF;

            foreach (string str in CobResWords.ToArray())
            {
                if (fromToMoves.CodeShower.Text == "") { }
                else fromToMoves.CodeShower.Text += "\r\n";
                fromToMoves.CodeShower.Text += str;
            }

            fromToMoves.Show();
            //createXMLMoveCode();
            //func_exit: ;
        }

        private void loadResWords()
        {
            string number = "";
            CobResWords = new List<string>();
            for (int i = 0; i < 700; i++)
            {
                number = i.ToString("0");
                string strName = "String" + (string)(i > 0 ? number : "");
                string str = Properties.Resources.ResourceManager.GetString(strName);
                if (str == null) break;
                CobResWords.Add(str);
            }
        }

        private void btnSaveArea_Click(object sender, EventArgs e)
        {
            SaveRegCopyFile srcf = new SaveRegCopyFile();
            savedFile localSaver = new savedFile();
            localSaver.idConnect = "4B0E5C02-B2D0-4755-B4EC-AF449D513582";
            localSaver.usageName = S.ettingActualFile + "_XMLCOBfrom";
            localSaver.fNameSaved = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + ".cpy";
            srcf.SavedFile = localSaver;
            srcf.FileData = this.outCob.Text;
            srcf.ShowDialog();
        }

        private void GenCobCode_ClientSizeChanged(object sender, EventArgs e)
        {

            if (ClientSize.Width < ClientSizeMinWidth)
            {
                MessageBox.Show("Form can't be narrower !");
                this.Size = new Size(ClientSizeMinWidth + 15, Size.Height);
            }
        }

        private void btnCrossref_Click(object sender, EventArgs e)
        {
            //Create showing window
            fromToMoves = new ShowCode();
            fromToMoves.FormParent = this;
            fromToMoves.BSynch = true;
            fromToMoves.Labeltext = "Cobol \"CrossRef\" List";

            savedFile SF = new savedFile();
            SF.idConnect = "1C1FAE9D-39DD-4A24-A6C2-8696EAE3CB32";
            SF.usageName = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Crossref";
            SF.fNameSaved = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Crossref.txt";

            fromToMoves.SavedFile = SF;

            foreach (CobRow cr in rowList)
            {
                if (cr.CobLevel < 2)
                {
                    string inFile = cmbLastFile.Text.Substring(cmbLastFile.Text.LastIndexOf("\\") + 1);
                    CreateComment(fromToMoves.CodeShower, "Moves reference (with loop) " + cr.FieldName, S.ettingUserName, S.ettingCompany, inFile);
                }
                // Header square created

                if (!cr.isAttribute && !cr.SampleStr.Equals(NOMOVE))
                {
                    if (fromToMoves.CodeShower.Text == "") { }
                    else fromToMoves.CodeShower.Text += "\r\n";
                    if (cr.MoveCode == null)
                    {
                        fromToMoves.CodeShower.Text += "".PadRight(30) + " " + cr.FieldName.PadRight(30);

                    }
                    else
                    {
                        fromToMoves.CodeShower.Text += cr.MoveCode.PadRight(30) + " " + cr.FieldName.PadRight(30);
                    }
                }

            }

            fromToMoves.Show();

        }

        private void txtPrefix_TextChanged(object sender, EventArgs e)
        {
            S.ettingPrefix = txtPrefix.Text;
        }

        private void txtExpPrefix_TextChanged(object sender, EventArgs e)
        {
            S.ettingExpPrefix = txtExpPrefix.Text;
        }

        private void txtMaxOcc_TextChanged(object sender, EventArgs e)
        {
            S.ettingMaxOcc = txtMaxOcc.Text;
        }

        private void chkBackupVars_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingUserCodeBcup = chkBackupVars.Checked;
        }

        private void chkPerform_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingPerform = chkPerform.Checked;
        }

        private void chkMvToDisp_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingMvToDisp = chkMvToDisp.Checked;
        }

        private void chkDisplays_CheckedChanged(object sender, EventArgs e)
        {
            S.ettingDisplays = chkDisplays.Checked;
        }

        private void btnRerun_Click(object sender, EventArgs e)
        {
            runXMLgen();
        }

        private void btnShowWorkFiles_Click(object sender, EventArgs e)
        {
            CheckWorkItems cwi = new CheckWorkItems();
            cwi.FileList = setObjs;
            cwi.ShowDialog();
        }

        private void btnXmlKopAttr_Click(object sender, EventArgs e)
        {
            // kopiera xml inclusive Attribut
            savedFile SF = new savedFile();
            SF.idConnect = "598A5F20-9A8A-415D-81B2-BBFE04465381";
            SF.usageName = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Transfer";
            SF.fNameSaved = S.ettingActualFile.Substring(0, S.ettingActualFile.LastIndexOf(".")) + "_Transfer.cbl";
            createXMLMoveCode(SF, inclAttribs: true);
        }

        private void btnMoveFromAttr_Click(object sender, EventArgs e)
        {
            GenerateFromCode(true);
        }

    }
}
