/// <reference path="../../../../Scripts/IndustrialDashboard-debug.js" />
// Author: AustralTek 
// http://www.australtek.com
// Copyright: 2009 - 2012

//DOCS
//This widget does not DRAW an HTML element, this should be passed via parameters (it's the object param in the constructor).

(function () {
    var _FormSelectBootstrap = { Public: {}, Base: null };
    _FormSelectBootstrap.Base = function (MyReference) {

        /* MyReference will never come null but the next if statement is added just to fix the intellisense. */
        if (!MyReference)
            MyReference = {};
        /* MyReference.Public attribute will always come null if the class is the root of the herency. */
        if (!MyReference.Public)
            MyReference.Public = {};
        
        /* Inheritance from super class */
        FormWidget.Inherit(MyReference);

        Core.Object.Extend({
            Internal: {
                fetchingOptions: false
                , is_bootstrap_select: false
            }
            , DatabaseInfo: {
                optionsData: { ConnectionStringName: "", DBEngine: "", FixedParameters: [], Procedure: "" }
            }
            , Events: {
                onRefreshOptionsDataComplete: []
            }
            , Templates: null
        }, MyReference); 

        //setting default value for elem depending on what type of element we are working with.
        MyReference.value = "";         
        
        MyReference.AttachSelectEvents = function(){
            try {
                if (!MyReference.Internal.is_bootstrap_select) {
                    Core.Events.Add(MyReference.Internal.elem, "focus", MyReference.OnElemFocus);
                    Core.Events.Add(MyReference.Internal.elem, "onchange", MyReference.OnElemChange);
                    Core.Events.Add(MyReference.Internal.elem, "onblur", MyReference.OnElemBlur);
                } else {
                    $(MyReference.Internal.elem).change(MyReference.OnElemChange);
                    //$(MyReference.Internal.elem).bind("liszt:showing_dropdown", MyReference.OnElemFocus);
                    //$(MyReference.Internal.elem).bind("liszt:hiding_dropdown", MyReference.OnElemBlur); 
                }
            } catch (Error) { }
        }

        MyReference.SetCommitingUI = function (value) {
            try {
                //setting the element to disabled or enabled
                if (value == true) {
                    MyReference.Internal.elem.disabled = true;
                } else if (value == false) {
                    MyReference.Internal.elem.disabled = false;
                }

                //if the element is using the chosen.js library, then updating its state.
                if (MyReference.Internal.is_bootstrap_select) MyReference.UpdateBootstrapSelect();
            } catch (Error) { }
        }

        MyReference.SetDisabledUI = function (value) {
            try {
                //setting the element to disabled or enabled
                if (value == true) {
                    MyReference.Internal.elem.disabled = true;
                    MyReference.Internal.elem.title = "";
                } else if (value == false){
                    MyReference.Internal.elem.disabled = false;
                    MyReference.Internal.elem.title = "";
                }

                //if the element is using the chosen.js library, then updating its state.
                if (MyReference.Internal.is_bootstrap_select) MyReference.UpdateBootstrapSelect(); 
            } catch (Error) { }
        }

        MyReference.OnElemChange = function () {
            try {
                var value = MyReference.Internal.elem.value;
                MyReference.SetValue(value, { force: true, synced: false });
            } catch (Error) { }
        }

        MyReference.OnElemFocus = function () {
            try {
                //setting is focused to true so that the value nor the status can be changed.
                MyReference.SetIsFocused(true);
            } catch (Error) { }
        }

        MyReference.OnElemBlur = function () {
            try {
                var value = MyReference.Internal.elem.value;
                MyReference.SetIsFocused(false); 
                //MyReference.SetValue(value); 
            } catch (Error) { }
        }

        MyReference.UpdateValue = function(value) {
            if (Core.Object.ValidateEmpty(value) && MyReference.Internal.fetchingOptions == false) {
                
                for (var i = 0; i < MyReference.Internal.elem.options.length; i++) {
                    if (MyReference.Internal.elem.options[i].value == value) {
                        MyReference.Internal.elem.options[i].selected = true;
                    } else {
                        MyReference.Internal.elem.options[i].selected = false; 
                    }
                }

                if (MyReference.Internal.is_bootstrap_select) MyReference.UpdateBootstrapSelect(); 

            }
        };

        MyReference.InitializeSelect = function () {
            try {
                if (($) && ($().selectpicker)) {
                    //if jquery and chosen are available, we use it to prettify the select boxes.
                    $(MyReference.Internal.elem).selectpicker({
                    });
                    MyReference.Internal.is_bootstrap_select = true; 
                }
            } catch (Error) { }
        }; 

        MyReference.Public.SetOptionsData =
        MyReference.SetOptionsData = function(data){
            try {
                if (!data) throw "No data was passed to the method.";
                
                var defaultTemplate = "<option value='{{Id}}'>{{Value}}</option>"; 

                var html = ""; 
                for (var i = 0; i < data.length; i++) {
                    var opt = data[i]; 
                    var template = (Core.String.ValidateEmpty(opt.Template) && MyReference.Templates[opt.Template]) ? MyReference.Templates[opt.Template] : defaultTemplate; 
                    //html += Handlebars.compile(template)(opt);
                    var opt = Handlebars.compile(template)(opt);
                    $(MyReference.Internal.elem).append(opt); 
                }

                //MyReference.Internal.elem.innerHTML = html;

                MyReference.SetValue(((MyReference.value != "") ? MyReference.value : MyReference.Internal.elem.value), { force: true, synced: false });
                MyReference.SetOptionsFinished(); 

            }catch(Error){}
        }

        MyReference.UpdateBootstrapSelect = function(){
            try{
                $(MyReference.Internal.elem).selectpicker("refresh");
            }catch(Error){ }
        }

        MyReference.SetOptionsFinished = function () {
            try {
                MyReference.Internal.fetchingOptions = false;

                //if using bootstrap-select.js to prettify the select boxes, then we should update it.
                if (MyReference.Internal.is_bootstrap_select) MyReference.UpdateBootstrapSelect();

                if (MyReference.value) MyReference.UpdateValue(MyReference.value);

                //MyReference.FireEvents("onRefreshOptionsDataComplete", [{ elem: MyReference.Public }])

            } catch (Error) { }
        }        

        function SetFetchingUIState() {
            try {
                //MyReference.Internal.elem.innerHTML = "<option value='fetchingOptions'>...</option>";
                //MyReference.UpdateBootstrapSelect(); 
            } catch (Error) { }
        }

        MyReference.Public.RefreshOptionsData = 
        MyReference.FetchOptionsData = function(QP){
            try{

                //checking if a procedure for refreshing the data is available.
                if (!MyReference.DatabaseInfo.optionsData.Procedure) return false;

                MyReference.Internal.fetchingOptions = true; 
                SetFetchingUIState(); 

                if (!QP) QP = new QueryParameters();

                for (var fp in MyReference.DatabaseInfo.optionsData.FixedParameters)
                    QP.AddParameter(MyReference.DatabaseInfo.optionsData.FixedParameters[fp]);

                Core.Json.CallProcedure(MyReference.DatabaseInfo.optionsData.Procedure, QP, {
                    onSuccess: function (data) {
                        try {

                            if ((data) && (!data.Message)) {

                                if (Core.Object.Exist(data, "Table")) {
                                    var arrayData = data.Table; 
                                    MyReference.SetOptionsData(arrayData);
                                }

                            } else {
                                if (data == null) {
                                } else {

                                }
                            }

                        } catch (Error) { }
                    }
                    , onFailure: function (data) {
                        try {

                        } catch (Error) { }
                    }
                }, MyReference.DatabaseInfo.optionsData.ConnectionStringName);

            }catch(Error){ }
        }

    }    

    _FormSelectBootstrap.Constructor = function (object, options) {
        try {
            var instance = {};

            _FormSelectBootstrap.Base(instance);

            instance.Initialize(object, options);
            instance.InitializeSelect(); 
            instance.FetchOptionsData(); 
            instance.AttachSelectEvents();

            window.Core.Object.Extend(instance.Public, this);

        }
        catch (Error) { window.status = Error.message; }
    };

    _FormSelectBootstrap.Public.Inherit = function (obj) {
        try {
            _FormSelectBootstrap.Base(obj);
        }
        catch (Error) { window.status = Error.message; }
    };

    window.FormSelectBootstrap = _FormSelectBootstrap.Constructor;

    window.Core.Object.Extend(_FormSelectBootstrap.Public, window.FormSelectBootstrap);

})();