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.IO;
using System.Globalization;
using System.Resources;
using System.Text.RegularExpressions;


namespace EduNetworkBuilder
{
    public partial class RTFWindow : Form
    {
        public RTFWindow()
        {
            InitializeComponent();
            LanguagifyComponents();
        }
        /// <summary>
        /// Used when viewing help from the ? button.  This displays network specific help information
        /// </summary>
        /// <param name="theHelp"></param>
        /// <param name="theTests"></param>
        public RTFWindow(string title, string theHelp, List<NetTest> theTests)
        {
            InitializeComponent();
            LanguagifyComponents();
            BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
            if (myWin != null)
            {
                StartPosition = FormStartPosition.Manual;
                Point newlocation = new Point(myWin.Location.X + myWin.Width + 5, myWin.Location.Y);
                if (newlocation.X > (Screen.PrimaryScreen.Bounds.Width + 5))
                {
                    newlocation = new Point(Screen.PrimaryScreen.Bounds.Width - 5, newlocation.Y);
                }
                Location = newlocation;
                Height = myWin.Height;
            }
            System.Drawing.Font currentFont = rtbContent.SelectionFont;
            Text = title;
            rtbContent.Text = theHelp;
            rtbContent.SelectAll();
            rtbContent.SelectionFont = new Font(
                currentFont.FontFamily,
                currentFont.Size + 2, FontStyle.Regular);
            rtbContent.DeselectAll();
        }

        /// <summary>
        /// Start an RTFWindow with the specified information showing
        /// </summary>
        /// <param name="WhatToShow"></param>
        public RTFWindow(RTFWindowContents WhatToShow)
        {
            InitializeComponent();
            LanguagifyComponents();
            string currentDir = Directory.GetCurrentDirectory();
            string myRTF;
            Form myWin = null;
            myWin = Application.OpenForms["RTFWindow"];
            if (myWin == null)
            {
                myWin = Application.OpenForms["BuilderWindow"];
            }
            if (myWin != null)
            {
                StartPosition = FormStartPosition.Manual;
                Point newlocation = new Point(myWin.Location.X + myWin.Width + 5, myWin.Location.Y);
                if (newlocation.X > (Screen.PrimaryScreen.Bounds.Width + 5))
                {
                    newlocation = new Point(Screen.PrimaryScreen.Bounds.Width - 5, newlocation.Y);
                }
                Location = newlocation;
                Height = myWin.Height;
            }
            if (WhatToShow == RTFWindowContents.help)
            {                
                myRTF = SafeRTF(Properties.Resources.Help);
                rtbContent.Rtf = myRTF;
            }
            else if (WhatToShow == RTFWindowContents.about)
            {
                myRTF = SafeRTF(Properties.Resources.about);
                rtbContent.Rtf = myRTF;
            }
            else if (WhatToShow == RTFWindowContents.release_notes)
            {
                myRTF = SafeRTF(Properties.Resources.ReleaseNotes);
                rtbContent.Rtf = myRTF;
            }
        }

        /// <summary>
        /// When running using Mono (on Linux) the RTF reader fails on some images.
        /// </summary>
        /// <param name="inRTF"></param>
        /// <returns></returns>
        public string SafeRTF(string inRTF)
        {
            string What = string.Copy(inRTF);
            if (!NB.IsRunningOnMono()) return What;
            string newWhat = "";
            List<string> ToMatch = new List<string>();
            ToMatch.Add(@"{\nonshppict");
            ToMatch.Add(@"{\*\shppict");
            ToMatch.Add(@"{\pict");

            string MatchedSoFar = "";
            int count = 0;
            int posincompare = 0;
            bool Foundit = false;
            bool FoundPartMatch = false;
            using (var ms = new MemoryStream())
            {
                var sw = new StreamWriter(ms);
                foreach (char c in What)
                {
                    if (Foundit)
                    {
                        if (c == '{') count++;
                        if (c == '}') count--;
                        if (count == 0)
                        {
                            Foundit = false; //We have finished finding it.
                            posincompare = 0;//start from the beginning again
                        }
                    }
                    else
                    {
                        MatchedSoFar += c;
                        FoundPartMatch = false;
                        for(int i=0; i< ToMatch.Count; i++)
                        {
                            int howfar = MatchedSoFar.Length;
                            if (ToMatch[i].Length < howfar) howfar = ToMatch[i].Length;
                            if (MatchedSoFar.Equals(ToMatch[i].Substring(0,howfar)))
                            {
                                FoundPartMatch = true;
                                break;
                            }
                        }

                        if (FoundPartMatch)
                        {
                            posincompare++;
                            for (int i = 0; i < ToMatch.Count; i++)
                            {
                                if (ToMatch[i].Equals(MatchedSoFar))
                                    Foundit = true;
                            }
                            if (Foundit)
                            {
                                posincompare = 0;
                                Foundit = true;
                                count = 1; //There is one { in the compare string
                                MatchedSoFar = "";//reset it
                            }
                        }
                        else
                        {
                            if (posincompare > 0)
                            {
                                //newWhat += picstart.Substring(0, posincompare);
                                sw.Write(MatchedSoFar); //What has matched up to this point
                                posincompare = 0;
                            }
                            else
                            {
                                //newWhat += c;
                                sw.Write(c);
                            }
                            MatchedSoFar = ""; //reset it
                        }
                    }
                }
                sw.Flush();
                ms.Position = 0;
                var sr = new StreamReader(ms);
                newWhat = sr.ReadToEnd();
            }
            return newWhat;
        }

        public void JumpToSelection(string WhatToFind)
        {
            int indexToText = rtbContent.Find(WhatToFind);
            if (indexToText > 0)
            {
                rtbContent.SelectionStart = indexToText;
                rtbContent.ScrollToCaret();
            }
        }
        public void JumpToSelection(HelpTopics WhatToFind)
        {
            string toFind = NB.Translate(NB.GetHelpTopicKey(WhatToFind));
            JumpToSelection(toFind);
        }
        private void LanguagifyComponents()
        {
            rtbContent.Text = NB.Translate("RTFW_rtbContent");
            btnOK.Text = NB.Translate("_OK");
            Text = NB.Translate("RTFW_Form");
            lblFind.Text = NB.Translate("RTFW_lblFind");
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void Search(bool GoForward)
        {
            int loc = rtbContent.SelectionStart;
            int indexToText;
            string WhatToFind =  tbFind.Text;
            if (tbFind.Text == "") return; //We do nothing if nothing to find.
            if (GoForward)
            {
                loc++; //move forward just a smidge
                if (loc >= rtbContent.MaxLength) loc = rtbContent.MaxLength;
                indexToText = rtbContent.Find(WhatToFind,loc,RichTextBoxFinds.None);
            }
            else
            {
                loc--;//Move back a smidge
                if (loc < 0) loc = 0;
                indexToText = rtbContent.Find(WhatToFind, loc, RichTextBoxFinds.Reverse);
            }
            if (indexToText > 0)
            {
                rtbContent.SelectionStart = indexToText;
                rtbContent.SelectionBackColor = Color.LightBlue;
                rtbContent.ScrollToCaret();
            }
            if(indexToText == -1)
            {
                //We did not go anywhere
                MessageBox.Show(NB.Translate("RTFW_NotFound"));
            }
        }

        private void btnFwd_Click(object sender, EventArgs e)
        {
            Search(true);
        }

        private void btnBack_Click(object sender, EventArgs e)
        {
            Search(false);
        }

    }
}
