using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Reflection;
using Telerik.WinControls.UI;

namespace Telerik.QuickStart.WinControls
{
    public enum NodeType
    {
        Category,
        Example
    }

    public class ExamplesTreeNode: RadTreeNode
    {
        private NodeType nodeType;
        private string exampleTypeName;
		private string path;
		private string formName = "Form1.cs";
		private string description;
		private Image exampleImage;
		private string[] exampleFiles;
		private string[] exampleFilesVB;
		private Type formType;
        private bool showInCarousel;
        private bool showInHomeCarousel;
        private string descriptionAsText;
        private string carouselTitle;
        private string categoryDescriptionPath;
        private bool theming;
        private string sourceFilesPath;


        public ExamplesTreeNode(string nodeText, NodeType nodeType)
            : base(nodeText)
        {
			this.NodeType = nodeType;
        }

        public NodeType NodeType
        {
            get { return nodeType; }
            set { nodeType = value; }
        }

		public string ExampleTypeName
        {
            get 
            {
                if (exampleTypeName == null)
                    return string.Empty;
                return exampleTypeName; 
            }
            set { exampleTypeName = value; }
        }

        public bool Theming
        {
            get { return theming; }
            set { theming = value; }
        }

		public string Path
		{
			get { return path; }
			set { path = value; }
		}

		public string FormName
		{
			get { return formName; }
			set { formName = value; }
		}

		public string Description
		{
			get
			{
				if ( string.IsNullOrEmpty( description ))
				{
					string filePath = GetFilePath("Description.html");
					if (filePath == null)
					{
						filePath = GetFilePath("Description.htm");
					}
					if (filePath != null)
					{
						StreamReader reader = new StreamReader(filePath);
						description = reader.ReadToEnd();
					}
				}

                if (description == null)
                    return string.Empty;
				return description;
			}
		}


        public string CarouselTitle
        {
            get { return carouselTitle; }
            set { carouselTitle = value; }
        }


        private string ParseHTML(string text)
        {
            if(!string.IsNullOrEmpty(text))
            {
                StringBuilder sb = new StringBuilder(text.Length);
                int br = 0;
                for(int i = 0; i < text.Length; ++i)
                {
                    if(text[i] == '<')
                    {
                        ++br;
                        continue;
                    }
                    if(text[i] == '>')
                    {
                        --br;
                        continue;
                    }

                    if(br <= 0)
                        sb.Append(text[i]);
                }
                return sb.ToString();
            }
            return string.Empty;
        }


        public string CategoryDescriptionPath
        {
            get { return categoryDescriptionPath; }
            set { categoryDescriptionPath = value; }
        }


        public string DescriptionText
        {
            get
            {
                if( String.IsNullOrEmpty( descriptionAsText))
                {
                    string descriptionFileName = "CarouselDescription.txt";
                    
                    string filePath = string.Empty;

                    if (this.nodeType == NodeType.Example)
                    {
                        filePath = GetFilePath(descriptionFileName);
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(this.CategoryDescriptionPath))
                        {
                            filePath = System.IO.Path.Combine(this.CategoryDescriptionPath, descriptionFileName);
                        }
                    }

                    if( string.IsNullOrEmpty( filePath ))
                    {
                        filePath = GetFilePath(descriptionFileName);
                    }
                    if( !string.IsNullOrEmpty( filePath ))
                    {                        
                        string fullPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Application.ExecutablePath), filePath);
                        if (System.IO.File.Exists(fullPath))
                        {
                            using (StreamReader reader = new StreamReader(fullPath))
                            {
                                descriptionAsText = reader.ReadToEnd();
                            }
                        }
                        else
                        {
                            descriptionAsText = string.Empty;
                        }
                    }
                }
                if(descriptionAsText == null)
                    descriptionAsText = ParseHTML(Description);
                
                return descriptionAsText;
            }
        }

        //add support for rad carousel
        //pp 22/08/07
        public bool ShowInCarousel
        {
            get{return showInCarousel;}
            set{showInCarousel = value;}
        }

        public bool ShowInHomeCarousel
        {
            get{return showInHomeCarousel;}
            set{showInHomeCarousel = value;}
        }

       

        //end add

		public Image ExampleImage
		{
			get
			{
				if (exampleImage == null)
				{
					string imageFile = GetFilePath("screenshot.png"); 
					if (imageFile != null)
					{
						exampleImage = Image.FromFile(imageFile);
					}
				}

				return exampleImage;
			}
            set
            {
                exampleImage = value;
            }
		}
		
		public Control Form
		{
			get
			{
                try
                {
                    Control form = Activator.CreateInstance(this.FormType) as Control;
                    return form;
                }
                catch (Exception ex)
                {
                    while (ex.InnerException != null)
                    {
                        ex = ex.InnerException;
                    }
                    //throw new Exception(string.Format("{0}{1}{2}", "Not found Telerik.Examples.WinControls.", ExampleTypeName.Replace("/", "."), ".Form1"), ex);
#if DEBUG
                    MessageBox.Show(ex.ToString());
                    throw;
#else
                    throw ex;
#endif
                }
			}
		}

		public Type FormType
		{
			get
			{
				if (this.formType == null)
				{
					string formTypeName = "Telerik.Examples.WinControls." + ExampleTypeName.Replace("/", ".") + ".Form1";
					this.formType = MainForm.EntryAssembly.GetType(formTypeName);
				}

				return this.formType;
			}
		}
		
		public string[] ExampleFiles
		{
			get
			{
				if (exampleFiles == null)
					exampleFiles = GetExampleFiles("*.cs");
				
				return exampleFiles;
			}
		}

		public string[] ExampleFilesVB
		{
			get
			{
				if (exampleFilesVB == null)
					exampleFilesVB = GetExampleFiles("*.vb");

				return exampleFilesVB;
			}
		}

        public string SourceFilesPath
        {
            get { return sourceFilesPath; }
            set { sourceFilesPath = value; }
        }

        public string[] GetExampleFiles(string fileMask)
		{
			string path = "";
			if (!string.IsNullOrEmpty(SourceFilesPath))
			{
                path = System.IO.Path.Combine(System.IO.Path.Combine(Application.StartupPath, MainForm.WorkingPath), SourceFilesPath);
			}
			else
			{
				path = System.IO.Path.Combine(System.IO.Path.Combine(Application.StartupPath, MainForm.WorkingPath), ExampleTypeName);
			}

			string[] files = Directory.GetFiles(path, fileMask, SearchOption.AllDirectories);
			string[] names = new string[files.Length];
			for (int i = 0; i < names.Length; i++)
				names[i] = files[i].Replace(path + System.IO.Path.DirectorySeparatorChar, "");

			Array.Sort(names);

			return names;
		}

        public string GetSourceFilePath(string fileName)
        {
            string path = "";
            if (!string.IsNullOrEmpty(SourceFilesPath))
            {
                path = System.IO.Path.Combine(System.IO.Path.Combine(Application.StartupPath, MainForm.WorkingPath), SourceFilesPath);
            }
            else
            {
                if (!string.IsNullOrEmpty(ExampleTypeName))
                    path = System.IO.Path.Combine(System.IO.Path.Combine(Application.StartupPath, MainForm.WorkingPath), ExampleTypeName);
            }

            string filePath = System.IO.Path.Combine(path, fileName);
            if (File.Exists(filePath))
            {
                return filePath;
            }

            return null;
        }

		public string GetFilePath(string fileName)
		{
			string path = "";
			if (!string.IsNullOrEmpty(Path))
			{
				path = System.IO.Path.Combine(System.IO.Path.Combine(Application.StartupPath, MainForm.WorkingPath), Path);
			}
			else
			{
                if( !string.IsNullOrEmpty( ExampleTypeName))
				    path = System.IO.Path.Combine(System.IO.Path.Combine(Application.StartupPath, MainForm.WorkingPath), ExampleTypeName);                
			}

			string filePath = System.IO.Path.Combine(path, fileName);
			if (File.Exists(filePath))
			{
				return filePath;
			}

			return null;
		}

		public string GetRenderedFile(string fileName)
		{
			string filePath = GetFilePath(fileName);
			string code = CodeViewerHelper.RenderFile(filePath);
			return code;
		}
    }
}
