#define CATCHERROR

using System;
using System.IO;
using System.Windows.Forms;

namespace AdvancedDemo
{
    public partial class MainForm : Form
    {
        private const int FolderImageIndex = 0;
        private const int PdfImageIndex = 1;

        private readonly bool _exception;
        private TreeNode _lastSelected;
        private TemplateExampleBase _activeController;
        private readonly TemplateExampleBase _commonExampleController = new CommonTemplateExample();

        public MainForm()
        {
            try
            {
                InitializeComponent();
            }
            catch (ComponentPro.Licensing.TemplateEngine.UltimateLicenseException exc)
            {
                MessageBox.Show(exc.Message, "Error");
                _exception = true;
                return;
            }
        }

        /// <summary>
        /// Handles the Form's Load event.
        /// </summary>
        /// <param name="e">The event arguments.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (_exception)
                this.Close();

            BuildTree(Util.SamplesDir, tvSamples.Nodes);
            tvSamples.SelectedNode = tvSamples.Nodes[0];
        }

        private void BuildTree(string folderPath, TreeNodeCollection nodes)
        {
            TreeNode node;
            DirectoryInfo di = new DirectoryInfo(folderPath);
            if (di.Exists)
            {
                FileInfo[] files = di.GetFiles("*.tpl");
                foreach (FileInfo f in files)
                {
                    node = nodes.Add(f.Name.Substring(0, f.Name.Length - 4));
                    node.Tag = f.FullName;
                    node.ImageIndex = PdfImageIndex;
                    node.SelectedImageIndex = PdfImageIndex;
                }

                DirectoryInfo[] dirs = di.GetDirectories();
                foreach (DirectoryInfo d in dirs)
                {
                    node = nodes.Add(d.Name);
                    node.Tag = d.FullName;
                    node.ImageIndex = FolderImageIndex;
                    BuildTree(d.FullName, node.Nodes);
                    node.Expand();                    
                }
            }
        }

        private void EnableButtons(bool enable, bool hasCS, bool hasVB)
        {
            btnCS.Enabled = hasCS;
            btnVB.Enabled = hasVB;
            btnGenerate.Enabled = enable;
        }

        internal static string GetControlTypeName(string controlFileName)
        {
            string s = "AdvancedDemo.Samples." + controlFileName.Substring(0, controlFileName.Length - 4).Replace(' ', '_').Replace('\\', '.').Replace('-', '_');

            return s;
        }

        private void tvSamples_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.ImageIndex == PdfImageIndex)
            {
                string file = (string)e.Node.Tag;
                int p = file.LastIndexOf('.');
                string fileWithoutExt = file.Substring(0, p);
                bool hasCS = System.IO.File.Exists(fileWithoutExt + ".cs");
                bool hasVB = System.IO.File.Exists(fileWithoutExt + ".vb");

                // Load template content
                using (StreamReader sr = new StreamReader(file))
                {
                    txtTemplate.Text = sr.ReadToEnd();
                }
                txtOutput.Clear();

                EnableButtons(true, true, true);

                if (hasCS || hasVB)
                {
                    string tname = GetControlTypeName(file.Remove(0, Util.SamplesDir.Length + 1));
                    _activeController = (TemplateExampleBase)Activator.CreateInstance(Type.GetType(tname));
                }
                else
                    _activeController = _commonExampleController;

                _lastSelected = e.Node;
            }
            else
            {
                EnableButtons(false, false, false);
            }
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            if (_lastSelected != null)
            {
#if CATCHERROR
                try
                {
#endif
                    string file = (string)_lastSelected.Tag;
                    txtOutput.Text = _activeController.Generate(Path.GetDirectoryName(file), file, txtTemplate.Text);
#if CATCHERROR
                }
                catch (Exception exc)
                {
                    MessageBox.Show("Error: " + exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    System.Diagnostics.Trace.WriteLine(exc.StackTrace);

                    txtTemplate.Focus();
                    ComponentPro.TemplateEngineException dexc = exc as ComponentPro.TemplateEngineException;
                    if (dexc != null)
                    {
                        txtTemplate.Select(dexc.Position, 1);
                    }
                }
#endif
            }
        }

        private void btnCS_Click(object sender, EventArgs e)
        {
            string file;
            if (_activeController != _commonExampleController)
            {
                file = (string)_lastSelected.Tag;
                file = file.Substring(0, file.Length - 4) + ".cs";
            }
            else
                file = Util.SamplesDir + "\\CommonTemplateExample.cs";

            if (System.IO.File.Exists(file))
            {
                CodePreview pre = new CodePreview(file, true);
                pre.ShowDialog();
            }
        }

        private void btnVB_Click(object sender, EventArgs e)
        {
            string file;
            if (_activeController != _commonExampleController)
            {
                file = (string)_lastSelected.Tag;
                file = file.Substring(0, file.Length - 4) + ".vb";
            }
            else
                file = Util.SamplesDir + "\\CommonTemplateExample.vb";

            if (System.IO.File.Exists(file))
            {
                CodePreview pre = new CodePreview(file, false);
                pre.ShowDialog();
            }
        }
    }
}