using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Web;

namespace DPLib
{
    /// <summary>
    /// Represents a client script to be rendered to an ASP.Net web form.
    /// </summary>
    [TypeConverter(typeof(ClientScriptTypeConverter)),
    ToolboxItem(false)]
    public class ClientScript : System.Web.UI.Control
    {
        private string scriptUrl;
        private string preScriptHtml;
        private string postScriptHtml;
        private bool scriptEnabled;
        private bool embedScript;
        private ScriptTypes scriptType = ScriptTypes.ClientScript;

        /// <summary>
        /// Initializes a new instance of the ClientScript class with no parameters.
        /// </summary>
        public ClientScript()
        { 
            this.scriptUrl = string.Empty;
            this.preScriptHtml = string.Empty;
            this.postScriptHtml = string.Empty;
            this.scriptEnabled = true;
        }


        /// <summary>
        /// Initializes a new instance of the ClientScript class with the 
        /// parameter values provided.
        /// </summary>
        /// <param name="scriptUrl">The file system path to the file containing the script.</param>
        /// <param name="preScriptHtml">HTML to be rendered to the page before this ClientScript.</param>
        /// <param name="postScriptHtml">HTML to be rendered to hte page after this ClientScript.</param>
        /// <param name="scriptEnabled">True to cause the ClientScript to be enabled to the page.</param>
        /// <param name="embedScript">True to embed the contents of the script file in the page or false to create a script reference to the file.</param>
        /// <param name="id"></param>
        public ClientScript(
            string scriptUrl,
            string preScriptHtml,
            string postScriptHtml,
            bool scriptEnabled,
            bool embedScript,
            string id)
        {
            this.scriptUrl = scriptUrl;
            this.preScriptHtml = preScriptHtml;
            this.postScriptHtml = postScriptHtml;
            this.scriptEnabled = scriptEnabled;
            this.embedScript = embedScript;
            this.ID = id;
        }


        /// <summary>
        /// Returns the Name of the currente ClientScript object
        /// </summary>
        /// <returns>A System.String</returns>
        public override string ToString()
        {
            return this.GetType().ToString() + " - " +  this.ID;
        }


        /// <summary>
        /// Creates the HTML string to include in the HTML document that will create the sting.
        /// </summary>
        /// <returns>The string representation of the Script object.</returns>
        public string ToHtmlString(string uniqueID)
        {
            string path = string.Empty;
            string newLine = System.Environment.NewLine;
            if (this.scriptUrl.Trim().Length > 0)
            {
                switch(this.embedScript)
                {
                    case true :
                        // This script will be embedded in the HTML for the page
                        string error = string.Empty;

                        // Get the script file
                        try
                        {
                            path = HttpContext.Current.Request.MapPath(this.ScriptUrl);

                            using (System.IO.StreamReader sr = new System.IO.StreamReader(path))
                            {
                                // Return the preScriptHtml, the contents of the script file 
                                // as a string suitable for inclusion in a register script 
                                // command, and the postScriptHtml.  Create the script id 
                                // using the ClientScripts control uniqueID and the scripts
                                // Name value.
                                return newLine
                                    + this.preScriptHtml
                                    + newLine
                                    + "<script language=javascript id='"
                                    + uniqueID + "_" + this.ID
                                    + "'>"
                                    + newLine
                                    // Read the script file contents to include in the script
                                    + sr.ReadToEnd()
                                    + newLine
                                    + "</script>"
                                    + newLine
                                    + this.postScriptHtml
                                    + newLine;
                            }
                        }
                        catch (Exception ex)
                        {
                            return newLine + "<!-- Could not open script file " + this.scriptUrl + " -->";
                        }
                    case false : // This is not an embedded script
                        // Return the preScriptHtml, the script element with the name of the 
                        // script file as a src attribute for the script tag, and the
                        // postScriptHtml.  Create the script id using the ClientScripts 
                        // control uniqueID and the scripts Name value.
                        return newLine
                            + this.preScriptHtml
                            + newLine
                            + "<script language=javascript id='"
                            + uniqueID
                            + "_"
                            + this.ID
                            + "' src='"
                            + this.scriptUrl
                            + "'></script>"
                            + newLine
                            + this.postScriptHtml
                            + newLine;
                }
                return string.Empty;
            }
            else
            {
                return newLine + "<!-- Could not render " + this.ID + " because no script path was assigned. -->";
            }
        }


        [Editor(typeof(MyHundredDollarUrlEditor), typeof(UITypeEditor))]
        [Description("The URL for the script file to include or reference.")]
        [NotifyParentProperty(true)]
        public string ScriptUrl
        {
            get { return this.scriptUrl; }
            set { this.scriptUrl = value; }
        }


        /// <summary>
        /// This value will be rendered to the page before the script is rendered. 
        /// Typical use is to provide HTML content that is only required 
        /// if the script exists on the page.
        /// </summary>
        public string PreScriptHtml
        {
            get { return preScriptHtml; }
            set { preScriptHtml = value; }
        }

        /// <summary>
        /// This value will be rendered to the page after the script is rendered. 
        /// Typical use is to provide HTML content that is only required 
        /// if the script exists on the page.
        /// </summary>
        public string PostScriptHtml
        {
            get { return postScriptHtml; }
            set { postScriptHtml = value; }
        }


        /// <summary>
        /// If enabled and no other script with the same name has been rendered,
        /// then this script will be rendered to the page.  If not enabled, the
        /// script will not be rendered.
        /// </summary>
        public bool ScriptEnabled
        {
            get { return scriptEnabled; }
            set { scriptEnabled = value; }
        }


        /// <summary>
        /// If ClientScript, the script will be rendered immediately after the opening 
        /// Form tag in the body of the page.  If StartupScript, the script will be 
        /// rendered immediately before the closing form tag.
        /// </summary>
        public ScriptTypes ScriptType
        {
            get { return scriptType; }
            set { scriptType = value; }
        }


        /// <summary>
        /// If true, attempt to read scriptUrl and embed the script into the page.
        /// Otherwise, add the file as a src attribute of the Script object.
        /// </summary>
        public bool EmbedScript
        {
            get { return embedScript; }
            set { embedScript = value; }
        }
    }


    /// <summary>
    /// ScriptTypes are used to determine where the script will be rendered.
    /// ClientScript will cause the script to be rendered using 
    /// System.Web.UI.Page.RegisterClientScriptBlock and StartupScript will 
    /// be rendered using System.Web.UI.Page.RegisterStartupScript.
    /// </summary>
    public enum ScriptTypes
    {
        ClientScript,
        StartupScript
    }

}