//#define debug

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;


namespace BannerRotatorControl
{
    //[DefaultProperty("Text")]
    [ParseChildren(true, "BannerDisplayCheckCollection")]
    [PersistChildren(false)]
    [ToolboxData("<{0}:BannerRotator runat=server></{0}:BannerRotator>")]
    public class BannerRotator : WebControl, INamingContainer
    {

        public enum RepeatOptions
        {
            NoRepeat,
            RepeatX,
            RepeatY
        };


        #region Variables

        private List<BannerDisplayCheck> _BannerDisplayCheck = new List<BannerDisplayCheck>();










        protected bool _ShowOnlyActivatedBanners = false;
        protected int _RotateTime = 1000;
        protected string _BannerClickFile = null;






        protected string _ConnectionString = null;
        protected RepeatOptions _Repeat = RepeatOptions.NoRepeat;
        protected string _LocationCode = null;
        protected bool _EnableCaching = false;
        protected double _CacheDuration = 10;
        protected string _lang = "en";
        protected string _JavaScriptFlashGateway_path = "/scripts/";
        protected string _bms_data_url = null;


        protected string _Width = null;
        protected string _Height = null;
        protected string _banner_area_id = "0";
        protected string _NoAdFile = null;
        protected string _NoAdAlt = null;

        protected int _DisplayTimeSeconds = 0;
        protected string _BannerHtml = null;
        protected string _swfId = null;
        protected int _NextBannerIndex = 0;
        protected bool _SingleBanner = false;

        protected int _hspace = 0;
        protected int _vspace = 0;


        protected string _BorderStyle = "Solid";
        protected string _BorderWidth = "0";
        protected string _BorderColor = "black";

        protected string _UserDefinedParameterValue = null;


        #endregion


        #region Properties




        [
       Category("Behavior"),
        Description("The BannerDisplayCheck collection"),
      DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
      PersistenceMode(PersistenceMode.InnerDefaultProperty),
      DefaultValue(null), MergableProperty(false), Bindable(false)
        ]
        public List<BannerDisplayCheck> BannerDisplayCheckCollection
        {

            get
            {
                if (_BannerDisplayCheck == null)
                {
                    _BannerDisplayCheck = new List<BannerDisplayCheck>();
                }
                return _BannerDisplayCheck;
            }
        }




        [Bindable(true)]
        [Category("Setting")]
        [Description("Connection String for the Banners Database.")]
        public string ConnectionString
        {
            set
            {

                _ConnectionString = value;

            }


        }



        [Bindable(true)]
        [Category("Setting")]
        [Description("Location Code of the Banner. Refer to the Database Table 'BMS_BANNERS_LOCATIONS'")]
        public string LocationCode
        {
            set
            {

                _LocationCode = value;

            }
        }



        [Category("Setting")]
        [Description("Enable/Disable Caching in the Banner Control.")]
        public bool EnableCaching
        {
            set { _EnableCaching = value; }
        }



        [Category("Setting")]
        [Description("Set the Cache Duration in Minutes")]
        public double CacheDuration
        {
            set
            {
                if (_EnableCaching)
                    _CacheDuration = value;
                else
                    throw new Exception("'EnableCaching' Property is not set to 'True'!");
            }
        }



        [Category("Setting")]
        [DefaultValue("en")]
        [Description("Language Code of the Banner. Refer to the Database Table 'BMS_LANGS'")]
        public string BannersLanguage
        {
            set
            {

                _lang = value;

            }
            get
            {
                return _lang;
            }

        }



        [Bindable(true)]
        [Category("Setting")]
        [Description("URL Path of the Banners Images. example : http://www.mydomain/{0}/banners/. where {0} will be subistituted by 'BannerLanguage' value")]
        public string BannerImagesURL
        {
            set
            {

                _bms_data_url = value;

            }
        }



        [Category("Behavior")]
        [Description("Repeat Direction if there is more than banner area")]
        public RepeatOptions Repeat
        {
            set
            {
                _Repeat = value;
            }
        }










        [Category("Behavior")]
        [DefaultValue(false)]
        [Description("set to true if you wish to show only the activated banners. otherwise false to show all banners")]
        public bool ShowOnlyActivatedBanners
        {
            set
            {
                _ShowOnlyActivatedBanners = value;

            }
        }





        [Category("Setting")]
        [Description("Set or Get User Defined values to be used in the criteria condition list")]
        public string UserDefinedParameterValue
        {
            set
            {
                _UserDefinedParameterValue = value;

            }
            get
            {
                return _UserDefinedParameterValue;
            }
        }


        [Category("Setting")]
        [Description("Set the Banner Click aspx page URL")]
        public string BannerClickFile
        {
            set
            {
                _BannerClickFile = value;

            }
        }






        [Category("Setting")]
        [DefaultValue("/scripts/")]
        [Description("Scripts path. example '/scripts/'")]
        public string ScriptsPath
        {
            set
            {
                _JavaScriptFlashGateway_path = value;

            }
        }





        [Category("Behavior")]
        [DefaultValue(0)]
        [Description("Set the Horizental spacing in pixels")]
        public int HorizentalSpacing
        {
            set
            {
                _hspace = value;

            }
        }


        [Category("Behavior")]
        [DefaultValue(0)]
        [Description("Set the Vertical spacing in pixels")]
        public int VerticalSpacing
        {
            set
            {
                _vspace = value;

            }
        }




        [Category("Behavior")]
        [DefaultValue("Solid")]
        [Description("Set the Banner Area Border Style")]
        public override BorderStyle BorderStyle
        {
            get
            {
                return BorderStyle.None;
            }
            set
            {
                _BorderStyle = value.ToString();

            }

        }

        [Category("Behavior")]
        [DefaultValue("0")]
        [Description("Set the Banner Area Border Width")]
        public override Unit BorderWidth
        {
            get
            {
                return Unit.Empty;
            }
            set
            {
                if (value != null)
                    _BorderWidth = value.Value.ToString();
            }

        }


        [Category("Behavior")]
        [DefaultValue("black")]
        [Description("Set the Banner Area Border Color")]
        public override System.Drawing.Color BorderColor
        {
            get
            {
                return System.Drawing.Color.Empty;
            }
            set
            {
                if (value != null)
                    _BorderColor = System.Drawing.ColorTranslator.ToHtml(value);
            }
        }




        //hiding un-wanted properties




        [Browsable(false)]
        public override Unit Width { get; set; }


        [Browsable(false)]
        public override System.Drawing.Color BackColor { get; set; }





        [Browsable(false)]
        public override string CssClass { get; set; }

        [Browsable(false)]
        public override bool Enabled { get; set; }

        [Browsable(false)]
        public override bool EnableTheming { get; set; }



        [Browsable(false)]
        public override System.Drawing.Color ForeColor { get; set; }

        [Browsable(false)]
        public override Unit Height { get; set; }

        [Browsable(false)]
        public override string SkinID { get; set; }

        [Browsable(false)]
        public override string ToolTip { get; set; }


        [Browsable(false)]
        public override FontInfo Font
        {
            get
            {
                return base.Font;
            }
        }

















        #endregion



        #region private function


        /// <summary>
        /// 
        /// </summary>
        /// <param name="BannerID"></param>
        /// <returns></returns>
        protected string GenerateBannerClickURL(double BannerID)
        {
            string retVal = VirtualPathUtility.ToAbsolute(_BannerClickFile);

            double newBannerID = (BannerID + 99) * 4;

            string strBannerID = Guid.NewGuid().ToString() + newBannerID.ToString();


            retVal += "?clickid=" + HttpContext.Current.Server.UrlEncode(strBannerID);

            string qs_params = null;

            if (_BannerDisplayCheck.Count > 0)
            {
                retVal += "&params=";
                foreach (BannerDisplayCheck bdc in _BannerDisplayCheck)
                {

                    switch (bdc.ParameterType)
                    {
                        case BannerDisplayCheck.CriteriaTypes.QueryString:
                            if (!string.IsNullOrEmpty(HttpContext.Current.Request[bdc.ParameterName]))
                                qs_params += bdc.ParameterType.ToString() + "|" + HttpContext.Current.Request[bdc.ParameterName] + ",";
                          
                            break;

                        case BannerDisplayCheck.CriteriaTypes.PageURL:
                            qs_params += bdc.ParameterType.ToString() + "|" + HttpContext.Current.Request.RawUrl.Split('?')[0] + ",";
                            break;

                        case BannerDisplayCheck.CriteriaTypes.UserDefined:
                            if (!string.IsNullOrEmpty(_UserDefinedParameterValue))
                                qs_params += bdc.ParameterType.ToString() + "|" + _UserDefinedParameterValue + ",";
                            break;



                        case BannerDisplayCheck.CriteriaTypes.Session:
                            if (!string.IsNullOrEmpty(Convert.ToString(HttpContext.Current.Session[bdc.ParameterName])))
                                qs_params += bdc.ParameterType.ToString() + "|" + HttpContext.Current.Session[bdc.ParameterName].ToString() + ",";
                            break;

                        case BannerDisplayCheck.CriteriaTypes.Cookie:

                            HttpCookie cookies = HttpContext.Current.Request.Cookies[bdc.ParameterName];
                            if (cookies != null)
                            {
                                if (!string.IsNullOrEmpty(Convert.ToString(HttpContext.Current.Request.Cookies[bdc.ParameterName].Value)))
                                    qs_params += bdc.ParameterType.ToString() + "|" + HttpContext.Current.Request.Cookies[bdc.ParameterName].Value.ToString() + ",";
                            }

                            break;


                        default:
                            break;
                    }
                }


                //removing the last un-needed ","
                qs_params = qs_params.Substring(0, qs_params.Length - 1);
            }



            retVal += HttpContext.Current.Server.UrlEncode(qs_params);

            return retVal;
        }


        /// <summary>
        /// function to check if the file name passed is flash file or not. 
        /// </summary>
        /// <param name="file_name"></param>
        /// <returns></returns>
        protected bool IsFlashFile(string file_name)
        {

            bool retval = false;

            try
            {
                string ext = file_name.Substring(file_name.Length - 3, 3);
                if (ext.ToLower() == "swf")
                    retval = true;
            }
            catch (Exception)
            {

            }

            return retval;
        }



        /// <summary>
        /// this function used to generate condition part of sql statment to display banners accrding to the parameter defined by the user.
        /// </summary>
        /// <returns>string</returns>
        protected string GetBannerDisplaySqlConditions()
        {
            string retVal = null;

            if (_BannerDisplayCheck.Count > 0)
            {
                retVal += " and banner_id in (select banner_id from BMS_BANNER_DISPLAY_CRITERIAS where ";
                foreach (BannerDisplayCheck bdc in _BannerDisplayCheck)
                {

                    switch (bdc.ParameterType)
                    {
                        case BannerDisplayCheck.CriteriaTypes.QueryString:
                            if (!string.IsNullOrEmpty(HttpContext.Current.Request[bdc.ParameterName]))
                            {
                                retVal += "(criteria_code='" + bdc.ParameterType.ToString() + "'";
                                retVal += " and criteria_value='" + HttpContext.Current.Request[bdc.ParameterName] + "') or ";
                            }

                            break;

                        case BannerDisplayCheck.CriteriaTypes.PageURL:
                            retVal += "(criteria_code='" + bdc.ParameterType.ToString() + "'";
                            retVal += " and criteria_value='" + HttpContext.Current.Request.RawUrl.Split('?')[0] + "') or ";
                            break;

                        case BannerDisplayCheck.CriteriaTypes.UserDefined:
                            if (!string.IsNullOrEmpty(_UserDefinedParameterValue))
                            {
                                retVal += "(criteria_code='" + bdc.ParameterType.ToString() + "'";
                                retVal += " and criteria_value='" + _UserDefinedParameterValue + "') or ";
                            }

                            break;



                        case BannerDisplayCheck.CriteriaTypes.Session:
                            if (!string.IsNullOrEmpty(Convert.ToString(HttpContext.Current.Session[bdc.ParameterName])))
                            {
                                retVal += "(criteria_code='" + bdc.ParameterType.ToString() + "'";
                                retVal += " and criteria_value='" + HttpContext.Current.Session[bdc.ParameterName].ToString() + "') or ";
                            }

                            break;

                        case BannerDisplayCheck.CriteriaTypes.Cookie:

                            HttpCookie cookies = HttpContext.Current.Request.Cookies[bdc.ParameterName];
                            if (cookies != null)
                            {
                                if (!string.IsNullOrEmpty(Convert.ToString(HttpContext.Current.Request.Cookies[bdc.ParameterName].Value)))
                                {
                                    retVal += "(criteria_code='" + bdc.ParameterType.ToString() + "'";
                                    retVal += " and criteria_value='" + HttpContext.Current.Request.Cookies[bdc.ParameterName].Value.ToString() + "') or ";
                                }
                            }

                            break;


                        default:
                            break;
                    }
                }

                //removing the last un-needed or
                retVal = retVal.Substring(0, retVal.Length - 3);

                retVal += ")";
            }


#if (debug)
            HttpContext.Current.Response.Write(retVal);
          //  HttpContext.Current.Response.End();
#endif


            return retVal;
        }


        /// <summary>
        /// Get list of the banner areas based on location code and language
        /// </summary>
        /// <returns>DataTable</returns>
        protected DataTable GetBannerArea()
        {
            DataTable retVal = null;


            string sql = "select ";
            //selecting a single record (first record based on order of "ls_order" column)
            if (_Repeat == RepeatOptions.NoRepeat)
                sql += "top 1 ";

            sql += " * from BMS_BANNERS_AREAS where location_code=@location_code and lang=@lang and Active_flag='1' order by ls_order";

            SqlConnection conn = new SqlConnection(_ConnectionString);
            SqlDataAdapter da = new SqlDataAdapter(sql, conn);

            try
            {
                da.SelectCommand.Parameters.AddWithValue("location_code", _LocationCode);
                da.SelectCommand.Parameters.AddWithValue("lang", _lang);
                DataTable dt = new DataTable();

                if (_EnableCaching)
                {
                    DataTable dt_c = HttpContext.Current.Cache["AdRotator_" + _Repeat.ToString() + "_" + _LocationCode + "_" + _lang] as DataTable;
                    if (dt_c != null)
                        dt = dt_c;
                    else
                    {
                        da.Fill(dt);
                        HttpContext.Current.Cache.Insert("AdRotator_" + _Repeat.ToString() + "_" + _LocationCode + "_" + _lang, dt, null, DateTime.Now.AddMinutes(_CacheDuration), TimeSpan.Zero);

                    }


                }
                else
                    da.Fill(dt);



                da.Dispose();
                conn.Dispose();

                retVal = dt;


            }
            catch (Exception ex)
            {
                throw new Exception("Exception Accured in : protected void GetBannerArea(). For More Details See Inner Exception Message", ex);
            }



            return retVal;
        }


        /// <summary>
        /// this function will return datatable containg list of banner based on banner_area_id
        /// </summary>
        /// <returns>datatable</returns>
        protected DataTable GetBannersWithinArea()
        {
            DataTable retVal = null;

            //generating sql statement for selecting the banners
            string sql = "select * from BMS_BANNERS";
            sql += " where banner_area_id=" + _banner_area_id;

            //check for banner start date and expiry date
            sql += " and CONVERT(varchar(10),expiry_date,121) >=CONVERT(varchar(10),getdate(),121)  ";
            sql += " and CONVERT(varchar(10),getdate(),121) >=CONVERT(varchar(10),start_date,121)  ";


            //apply banner display condition based on the user define parameters in the control.
            string BannerDisplaySqlConditions = GetBannerDisplaySqlConditions();
            if (!string.IsNullOrEmpty(BannerDisplaySqlConditions))
                sql += BannerDisplaySqlConditions;

            if (_ShowOnlyActivatedBanners)
                sql += " and active_flag='1' ";

            sql += " order by ls_order";



            SqlConnection conn = new SqlConnection(_ConnectionString);
            SqlDataAdapter da = new SqlDataAdapter(sql, conn);
            DataTable dt = new DataTable();



            try
            {
                //applying cache if applicable.
                if (_EnableCaching)
                {
                    string c_BannerDisplaySqlConditions = null;
                    if (!string.IsNullOrEmpty(BannerDisplaySqlConditions))
                    {
                        c_BannerDisplaySqlConditions = BannerDisplaySqlConditions.Replace(" ", "_");
                        c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace("'", "_");
                        c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace(">", "_");
                        c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace("<", "_");
                        c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace("(", "_");
                        c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace(")", "_");
                        c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace(":", "_");
                        c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace("/", "_");
                        c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace(@"\", "_");

                        c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace("=", "_");
                    }

                    //get data from cache if exists
                    DataTable dt_c = HttpContext.Current.Cache["AdRotator_" + _banner_area_id + "_" + _ShowOnlyActivatedBanners + "_" + c_BannerDisplaySqlConditions] as DataTable;
                    if (dt_c != null)
                        dt = dt_c;
                    else
                    {
                        //or get it from database and store it in the cache for later retrieval.
                        da.Fill(dt);
                        HttpContext.Current.Cache.Insert("AdRotator_" + _banner_area_id + "_" + _ShowOnlyActivatedBanners + "_" + c_BannerDisplaySqlConditions, dt, null, DateTime.Now.AddMinutes(_CacheDuration), TimeSpan.Zero);

                    }


                }
                else
                    da.Fill(dt);


                da.Dispose();

                retVal = dt;



            }


            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                conn.Dispose();

            }

            return retVal;

        }



        /// <summary>
        /// this function will generate the banner html based on the datarow passed containing the banner information.
        /// </summary>
        /// <param name="dr">datarow to be passed</param>
        protected void GenerateBannerHTML(DataRow dr)
        {


            if (dr != null)
            {


                float display_time_seconds = float.Parse(dr["display_time_seconds"].ToString());
                display_time_seconds = display_time_seconds * 1000; // convering to milliseconds for javasctipt to understand

                //assign the value of the banner display time (how long should the banner stay in the page before rotating to the next banner) in seconds
                _DisplayTimeSeconds = Convert.ToInt32(display_time_seconds);



                // check if the banner file is flash file or not so that we assign the _swfid without extention. this is needed like that for the java function to load flah
                if (IsFlashFile(dr["img_file"].ToString()))
                    _swfId = string.Format(_bms_data_url, _lang) + dr["img_file"].ToString().Substring(0, dr["img_file"].ToString().Length - 4);

                //check if the banner has a link url (means clickable to )                   
                else if (!string.IsNullOrEmpty(dr["link_url"].ToString()))
                {
                    //the "_BannerClickFile" asssigned by the "BannerClickFile" property of the control
                    if (!string.IsNullOrEmpty(_BannerClickFile))
                    {
                        //build up hyperlink markup
                        _BannerHtml = "<a href='" + GenerateBannerClickURL(Convert.ToDouble(dr["banner_id"])) + "'";
                        _BannerHtml += " target='" + dr["url_target"].ToString() + "'"; // build up target (open in new window or same window)
                        _BannerHtml += " title='" + dr["img_alt"].ToString() + "'>";
                    }
                    //this is the banner image HTML
                    _BannerHtml += "<img src='" + string.Format(_bms_data_url, _lang) + dr["img_file"].ToString() + "' style='border:" + _BorderStyle + " " + _BorderWidth + "px " + _BorderColor + ";' width='" + _Width + "' height='" + _Height + "'>";

                    if (!string.IsNullOrEmpty(_BannerClickFile))
                        _BannerHtml += "</a>";


                }
                else
                {
                    //else just show the banner without hyperlink
                    _BannerHtml = "<img src='" + string.Format(_bms_data_url, _lang) + dr["img_file"].ToString() + "' style='border:" + _BorderStyle + " " + _BorderWidth + "px " + _BorderColor + ";' width='" + _Width + "' height='" + _Height + "' title='" + dr["img_alt"].ToString() + "'>";


                }


            }

            else
            {
                // otherwise, just show a default image. example "advertizing space". based on the user input if he wish to reserve the banner area then he need to set the "NoAds_image" value in the database table "BMS_BANNERS_AREAS"
                //this will be assigned to the "_NoAdFile" var.
                if (!string.IsNullOrEmpty(_NoAdFile))
                {


                    _BannerHtml = "<img src='" + _NoAdFile + "' border='0' width='" + _Width + "' height='" + _Height + "' title='" + _NoAdAlt + "'>";

                }

            }

        }





        /// <summary>
        /// this function will generate the javascript array items based on the list of banners within banner area
        /// </summary>
        /// <returns></returns>
        protected string GenerateJavascriptArrayItems()
        {
            string retVal = null;


            // getting list of banner within an area banner. based on the "_banner_area_id"
            DataTable dt = GetBannersWithinArea();
            int i = 0;

            if (dt.Rows.Count > 0)
            {
                retVal += "banner_count" + _banner_area_id + "=" + dt.Rows.Count.ToString() + Environment.NewLine + Environment.NewLine;

                //loop through the banners
                foreach (DataRow dr in dt.Rows)
                {
                    //generate the banner
                    GenerateBannerHTML(dr);

                    retVal += "BannerHtml_arr" + _banner_area_id + "[" + i.ToString() + "]=\"" + _BannerHtml + "\";" + Environment.NewLine;
                    retVal += "swfId_arr" + _banner_area_id + "[" + i.ToString() + "]='" + _swfId + "';" + Environment.NewLine;
                    retVal += "DisplayTimeSeconds_arr" + _banner_area_id + "[" + i.ToString() + "]='" + _DisplayTimeSeconds + "';" + Environment.NewLine + Environment.NewLine;
                    i++;

                    //nullfy the values for next banner usage
                    _BannerHtml = null;
                    _swfId = null;
                    _DisplayTimeSeconds = 0;


                }
            }
            else
            {
                //generate and empty banner. (just the banner area block with advertizing space image if provided)
                GenerateBannerHTML(null);
                retVal += "BannerHtml_arr" + _banner_area_id + "[0]=\"" + _BannerHtml + "\";" + Environment.NewLine;
                retVal += "swfId_arr" + _banner_area_id + "[0]='" + _swfId + "';" + Environment.NewLine;
                retVal += "DisplayTimeSeconds_arr" + _banner_area_id + "[0]='" + _DisplayTimeSeconds + "';" + Environment.NewLine + Environment.NewLine;

            }
            return retVal;
        }



        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected string ValidateBannerDisplayCheckParameters()
        {
            string retVal = "OK";

            if (_BannerDisplayCheck.Count == 0)
                retVal = "OK";
            else
            {



                //creating tmp table to hold up the parameters collection
                DataTable dt = new DataTable();
                dt.Columns.Add(new DataColumn("ParameterType"));
                dt.Columns.Add(new DataColumn("ParameterName"));

                //loop throught the collection
                foreach (BannerDisplayCheck bdc in _BannerDisplayCheck)
                {

                    //check for ParameterName attribute if it is set for the following ParameterTypes. becuase is it applicable to them
                    if (bdc.ParameterType == BannerDisplayCheck.CriteriaTypes.Cookie || bdc.ParameterType == BannerDisplayCheck.CriteriaTypes.QueryString || bdc.ParameterType == BannerDisplayCheck.CriteriaTypes.Session)
                    {
                        if (string.IsNullOrEmpty(bdc.ParameterName))
                        {
                            retVal = "'ParameterName' attribute is not set for the selected 'ParameterType' (" + bdc.ParameterType.ToString() + ")";
                            break;
                        }
                    }



                    //add each item in a new row
                    DataRow dr = dt.NewRow();
                    dr["ParameterType"] = bdc.ParameterType;
                    dr["ParameterName"] = bdc.ParameterName;
                    dt.Rows.Add(dr);
                }

                // now we have all the collection in a datatable so that we can utilize the filter.
                // first rule: we should not have more than one parameter of type "PageURL"
                DataView dv1 = dt.DefaultView;

                dv1.RowFilter = "ParameterType='PageURL'";
                if (dv1.Count > 1)
                    retVal = "You cannot define more than one parameter with a ParameterType='PageURL'";


                // Second rule: we should not have more than one parameter of type "UserDefined"
                dv1.RowFilter = "ParameterType='UserDefined'";
                if (dv1.Count > 1)
                    retVal = "You cannot define more than one parameter with a ParameterType='UserDefined'";


                // third rule: we should not have duplicate parameter of type "QueryString","Session","Cookie" with same ParameterName
                // to do that i am going to filter ParameterType by QueryString,Session, or Cookie

                dv1.RowFilter = "ParameterType='QueryString' or ParameterType='Session' or ParameterType='Cookie'";

                //create an array to hold up the rows
                ArrayList dupRows = new ArrayList();

                //then loop through the records
                for (int i = 0; i < dv1.Count; i++)
                {
                    //concatinate the row values to come up with a unique value 
                    string dupRow = dv1[i]["ParameterType"].ToString() + dv1[i]["ParameterName"].ToString();

                    //check if the concatinated item is exists in the array. then yeah found an duplicate!
                    if (dupRows.Contains(dupRow))
                    {
                        retVal = "Duplicated ParameterType '" + dv1[i]["ParameterType"].ToString() + "' with the same ParameterName '" + dv1[i]["ParameterName"].ToString() + "'";

                        break;
                    }
                    else
                        dupRows.Add(dupRow);

                }

                //clear the array.. no need to keep values.
                dupRows.Clear();


                //clear things up.
                dv1.Dispose();
                dt.Clear();
                dt.Dispose();


            }



            return retVal;
        }


        #endregion





        protected override void OnPreRender(EventArgs e)
        {
            // When pre-rendering, add in external JavaScript file
            if (!Page.ClientScript.IsClientScriptIncludeRegistered("JavaScriptFlashGateway"))
            {


                string script_content = VirtualPathUtility.ToAbsolute("~" + _JavaScriptFlashGateway_path + "JavaScriptFlashGateway.js");
                Page.ClientScript.RegisterClientScriptInclude("JavaScriptFlashGateway", script_content);

            }

            base.OnPreRender(e);
        }

        protected override void RenderContents(HtmlTextWriter output)
        {
            //get the validation message of the banner display parameters.
            string BDC_Error = ValidateBannerDisplayCheckParameters();


            //check for mandatory properties.

            if (string.IsNullOrEmpty(_ConnectionString))
                throw new Exception("ConnectionString Property is not set");

            else if (string.IsNullOrEmpty(_LocationCode) || string.IsNullOrEmpty(_lang))
                throw new Exception("'LocationCode' and 'Language' properties need to be set.");

            else if (BDC_Error != "OK")
                throw new Exception(BDC_Error);
            else
            {


                //initially we get the list of banner areas in a datatable
                DataTable dt_banner_areas = GetBannerArea();

                if (dt_banner_areas.Rows.Count > 0)
                {

                    StringBuilder sb = new StringBuilder();
                    sb.Append(Environment.NewLine);

                    //check if we have more than one banner area within a location code and lang.
                    if (dt_banner_areas.Rows.Count > 1)
                    {
                        // building the html table to allocate the banner according to the repeat direction.
                        sb.Append("<table cellspacing='0' cellpadding='0'>" + Environment.NewLine);
                        if (_Repeat == RepeatOptions.RepeatX)
                            sb.Append("<tr>" + Environment.NewLine);

                    }

                    //loop throuhg the banner areas
                    foreach (DataRow dr in dt_banner_areas.Rows)
                    {


                        // assigning values
                        _banner_area_id = Convert.ToString(dr["banner_area_id"]);
                        _Width = Convert.ToString(dr["widthpx"]);
                        _Height = Convert.ToString(dr["hieghtpx"]);

                        if (!string.IsNullOrEmpty(Convert.ToString(dr["NoAds_image"])))
                            _NoAdFile = string.Format(_bms_data_url, _lang) + Convert.ToString(dr["NoAds_image"]);

                        _NoAdAlt = Convert.ToString(dr["NoAds_imageAlt"]);


                        //again check the banner areas count for doing the html table. and placing the banner areas.
                        if (dt_banner_areas.Rows.Count > 1)
                        {
                            if (_Repeat == RepeatOptions.RepeatX)
                                sb.Append("<td>" + Environment.NewLine);

                            else if (_Repeat == RepeatOptions.RepeatY)
                                sb.Append("<tr><td>" + Environment.NewLine);
                        }


                        //start doing the html and javascript. better you view source of the aspx page to see the resulted html.
                        sb.Append(@"<div id=""Banner1" + _banner_area_id + @""">" + Environment.NewLine);
                        sb.Append("</div>" + Environment.NewLine);

                        //writing up the javasctript that will do the banner rotation.
                        sb.Append(@"<script type=""text/javascript"">" + Environment.NewLine);

                        sb.Append(@"var BannerHtml_arr" + _banner_area_id + "= new Array();" + Environment.NewLine);
                        sb.Append(@"var swfId_arr" + _banner_area_id + " = new Array();" + Environment.NewLine);
                        sb.Append(@"var DisplayTimeSeconds_arr" + _banner_area_id + " = new Array();" + Environment.NewLine);


                        sb.Append(@"var banner_count" + _banner_area_id + " =0;" + Environment.NewLine);


                        sb.Append(@"var BannerHtml" + _banner_area_id + "=null;" + Environment.NewLine);
                        sb.Append(@"var swfId" + _banner_area_id + "=null;" + Environment.NewLine);

                        sb.Append(@"var BannerIndex" + _banner_area_id + "=0;" + Environment.NewLine);



                        // getting the generated javascript array list
                        sb.Append(GenerateJavascriptArrayItems());


                        sb.Append(@"function DisplayBanner" + _banner_area_id + "()" + Environment.NewLine);

                        sb.Append(@"{" + Environment.NewLine);

                        // sb.Append(@"// alert(swfId" + _banner_area_id + ");" + Environment.NewLine);

                        sb.Append(@"if (BannerHtml" + _banner_area_id + "!=null || swfId" + _banner_area_id + "!=null)" + Environment.NewLine);

                        sb.Append(@"{" + Environment.NewLine);

                        sb.Append(@"if (BannerHtml" + _banner_area_id + "!=null) {" + Environment.NewLine);

                        sb.Append(@"document.getElementById('Banner1" + _banner_area_id + "').innerHTML  =BannerHtml" + _banner_area_id + ";" + Environment.NewLine);
                        sb.Append(@"}" + Environment.NewLine);

                        sb.Append(@"else if (swfId" + _banner_area_id + "!=null) {" + Environment.NewLine);


                        sb.Append(@"//loading flash object using java script." + Environment.NewLine);

                        sb.Append(@"var lcId" + _banner_area_id + " = new Date().getTime();" + Environment.NewLine);

                        sb.Append(@"var flashProxy" + _banner_area_id + " = new FlashProxy(lcId" + _banner_area_id + ", '" + VirtualPathUtility.ToAbsolute("~" + _JavaScriptFlashGateway_path + "JavaScriptFlashGateway.js") + "');" + Environment.NewLine);


                        sb.Append(@"var flashObject" + _banner_area_id + " = new FlashTag(swfId" + _banner_area_id + "+'.swf'," + _Width + "," + _Height + ", '8,0,0,0');" + Environment.NewLine);

                        sb.Append(@"flashObject" + _banner_area_id + ".setFlashvars('lcId=' + lcId" + _banner_area_id + ");" + Environment.NewLine);

                        sb.Append(@"flashObject" + _banner_area_id + ".write(document.getElementById('Banner1" + _banner_area_id + "'));" + Environment.NewLine);



                        sb.Append(@"}" + Environment.NewLine);





                        sb.Append(@"}" + Environment.NewLine);



                        sb.Append(@"if (banner_count" + _banner_area_id + ">1)" + Environment.NewLine);
                        sb.Append(@"setTimeout('DisplayBanner" + _banner_area_id + "()',DisplayTimeSeconds_arr" + _banner_area_id + "[BannerIndex" + _banner_area_id + "],'JavaScript')" + Environment.NewLine);



                        sb.Append(@"BannerIndex" + _banner_area_id + "++;" + Environment.NewLine);

                        sb.Append(@"if (BannerIndex" + _banner_area_id + " >= banner_count" + _banner_area_id + ")" + Environment.NewLine);
                        sb.Append(@"BannerIndex" + _banner_area_id + "=0;" + Environment.NewLine);

                        sb.Append(@"SetValues" + _banner_area_id + "();" + Environment.NewLine);

                        sb.Append(@"}" + Environment.NewLine);




                        sb.Append(@"function SetValues" + _banner_area_id + "()" + Environment.NewLine);
                        sb.Append(@"{" + Environment.NewLine);

                        sb.Append(@"if (BannerHtml_arr" + _banner_area_id + "[BannerIndex" + _banner_area_id + "]!=null && BannerHtml_arr" + _banner_area_id + "[BannerIndex" + _banner_area_id + "]!='')" + Environment.NewLine);
                        sb.Append(@"BannerHtml" + _banner_area_id + " = BannerHtml_arr" + _banner_area_id + "[BannerIndex" + _banner_area_id + "];" + Environment.NewLine);
                        sb.Append(@"else" + Environment.NewLine);
                        sb.Append(@"BannerHtml" + _banner_area_id + " = null;" + Environment.NewLine);

                        sb.Append(@"if (swfId_arr" + _banner_area_id + "[BannerIndex" + _banner_area_id + "]!=null && swfId_arr" + _banner_area_id + "[BannerIndex" + _banner_area_id + "]!='')" + Environment.NewLine);
                        sb.Append(@"swfId" + _banner_area_id + " = swfId_arr" + _banner_area_id + "[BannerIndex" + _banner_area_id + "];" + Environment.NewLine);
                        sb.Append(@"else" + Environment.NewLine);
                        sb.Append(@"swfId" + _banner_area_id + " = null;" + Environment.NewLine);


                        sb.Append(@"}" + Environment.NewLine);

                        sb.Append(@"function LoadBanners" + _banner_area_id + "()" + Environment.NewLine);
                        sb.Append(@"{" + Environment.NewLine);

                        sb.Append(@"if (BannerIndex" + _banner_area_id + "==0)" + Environment.NewLine);
                        sb.Append(@"{" + Environment.NewLine);
                        sb.Append(@"SetValues" + _banner_area_id + "();" + Environment.NewLine);
                        sb.Append(@"DisplayBanner" + _banner_area_id + "();" + Environment.NewLine);
                        sb.Append(@"}" + Environment.NewLine);
                        sb.Append(@"}" + Environment.NewLine);



                        sb.Append(@"LoadBanners" + _banner_area_id + "();" + Environment.NewLine);




                        sb.Append(@"</script>" + Environment.NewLine);


                        if (dt_banner_areas.Rows.Count > 1)
                        {
                            if (_Repeat == RepeatOptions.RepeatX)
                            {
                                sb.Append("</td>" + Environment.NewLine);
                                if (_hspace > 0)
                                    sb.Append(@"<td style=""width:" + _hspace.ToString() + @"px""><div style=""width:" + _hspace + @"px;""></div></td>" + Environment.NewLine);
                            }

                            else if (_Repeat == RepeatOptions.RepeatY)
                            {
                                sb.Append("</td></tr>" + Environment.NewLine);
                                if (_vspace > 0)
                                    sb.Append(@"<tr><td style=""height:" + _vspace.ToString() + @"px""></td></tr>" + Environment.NewLine);
                            }


                        }

                    }



                    if (dt_banner_areas.Rows.Count > 1)
                    {

                        if (_Repeat == RepeatOptions.RepeatX)
                            sb.Append("</tr>" + Environment.NewLine);

                        sb.Append("</table>" + Environment.NewLine);

                    }




                    output.Write(sb);
                }

            }







        }



        /// <summary>
        /// 
        /// </summary>
        public static string UpdateBannerClick(string ConnectionString)
        {
            string retVal = null;

            SqlConnection conn = new SqlConnection(ConnectionString);
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;


            //getting the click id querystring.
            string banner_id = HttpContext.Current.Server.UrlDecode(HttpContext.Current.Request["clickid"]);
            banner_id = banner_id.Substring(Guid.NewGuid().ToString().Length, (banner_id.Length - Guid.NewGuid().ToString().Length));
            double b = Convert.ToDouble(banner_id);
            
            //apply our formula (reversed)
            b = (b / 4) - 99;
            banner_id = b.ToString();
                    

            string qs_params = HttpContext.Current.Server.UrlDecode(HttpContext.Current.Request["params"]);


            try
            {

                
                conn.Open();

                if (!string.IsNullOrEmpty(qs_params))
                {
                    //set the update command
                    cmd.CommandText = "update BMS_BANNER_DISPLAY_CRITERIAS set clicks=clicks+1 where banner_id=@banner_id and criteria_code=@criteria_code and criteria_value=@criteria_value";


                    //loop through each couple
                    foreach (string couple in qs_params.Split(','))
                    {
                        //start doing the clicks update according to the conditions.
                        cmd.Parameters.Clear();
                        cmd.Parameters.AddWithValue("banner_id", banner_id);
                        cmd.Parameters.AddWithValue("criteria_code", couple.Split('|')[0]);
                        cmd.Parameters.AddWithValue("criteria_value", couple.Split('|')[1]);
                        cmd.ExecuteNonQuery();
                    }
                }
                else
                {
                    //set the update command
                    cmd.CommandText = "update BMS_BANNERS set clicks=clicks+1 where banner_id=@banner_id";
                    cmd.Parameters.AddWithValue("banner_id", banner_id);
                    cmd.ExecuteNonQuery();

                }


                // check if the banner has a url link to redirect.
                cmd.Parameters.Clear();
                cmd.CommandText = "select link_url from BMS_BANNERS where banner_id=@banner_id";
                cmd.Parameters.AddWithValue("banner_id", banner_id);

                SqlDataReader dr = cmd.ExecuteReader();
                if (dr.HasRows)
                {
                    dr.Read();
                    if (!string.IsNullOrEmpty(Convert.ToString(dr["link_url"])))
                        retVal = Convert.ToString(dr["link_url"]);
                }

                dr.Close();
                dr.Dispose();



            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally 
            {
                conn.Close();
                cmd.Dispose();
                conn.Dispose();
            }


            return retVal;
        }



    }
}
