Type.registerNamespace('Devy.UI.Forms');

Devy.UI.Forms.Form = function() {
    Devy.UI.Forms.Form.initializeBase(this);

    //Miembros
    this._Parent = null;
    this._Container = null;
    this._CSSClass = "";

    this._FieldsContainer = null;

    this._ShowCommandOK = true;
    this._CommandOKText = "Aceptar";

    this._ShowCommandCancel = true;
    this._CommandCancelText = "Cancelar";
    
    this._ShowDuplicatedCommands = false;


    this._Fields = new Array();

    this._Validators = new Array();
    this._ValidatorsErrorsSumary = '';

    this._BusinessObject = null;

    this._events = null;
    this._FieldDescriptors = null;
    this._CustomCommands = null;
}

Devy.UI.Forms.Form.prototype = {
    //*********************************************************************
    //Publicos
    set_Parent: function (value) { this._Parent = value; },
    get_Parent: function () { return this._Parent; },

    set_CSSClass: function (value) { this._CSSClass = value; },
    get_CSSClass: function () { return this._CSSClass; },

    set_Container: function (value) { this._Container = value; },
    get_Container: function () { return this._Container; },

    set_BusinessObject: function (value) {
        this._BusinessObject = value;

        for (var i = 0; i < this._Fields.length; i++) {
            this._Fields[i].set_BusinessObject(this._BusinessObject);
        }

        this._aplyAuthorization();
    },
    get_BusinessObject: function () { return this._BusinessObject; },

    set_FieldDescriptors: function (value) {
        this._FieldDescriptors = value;

        if (this._FormIsSetUp)
            this._setUpForm();
    },

    get_FieldDescriptors: function () { return this._FieldDescriptors; },

    set_CustomCommands: function (value) { this._CustomCommands = value; },
    get_CustomCommands: function () { return this._CustomCommands; },

    set_ShowCommandOK: function (value) { this._ShowCommandOK = value; },
    get_ShowCommandOK: function () { return this._ShowCommandOK; },

    set_CommandOKText: function (value) { this._CommandOKText = value; },
    get_CommandOKText: function () { return this._CommandOKText; },


    set_ShowCommandCancel: function (value) { this._ShowCommandCancel = value; },
    get_ShowCommandCancel: function () { return this._ShowCommandCancel; },

    set_CommandCancelText: function (value) { this._CommandCancelText = value; },
    get_CommandCancelText: function () { return this._CommandCancelText; },


    set_ShowDuplicatedCommands: function (value) { this._ShowDuplicatedCommands = value; },
    get_ShowDuplicatedCommands: function () { return this._ShowDuplicatedCommands; },

    initialize: function () {
        Devy.UI.Forms.Form.callBaseMethod(this, 'initialize');

        var formContainer = $('<div class="Form ' + this._CSSClass + '"></div>');
        $(this._Container).append(formContainer);

        this._FieldsContainer = $('<div class="Fields"></div>')[0];
        formContainer.append(this._FieldsContainer);

        this._setUpForm();
    },

    dispose: function () {
        Devy.UI.Forms.Form.callBaseMethod(this, 'dispose');
    },

    _onOK: function () {
        if (this.IsValid()) {
            this.UpdateBusinessObject();
            this._raiseEvent("OKClick");
        }
        else
            Devy.Notifications.ShowError("Los datos ingresados no son válidos", this._ValidatorsErrorsSumary);
    },

    _onCancel: function () {
        this._raiseEvent("cancelClick");
    },

    _onCustomCommand: function (e) {
        //obtenemos el objeto
        var cmd = e.rawEvent.currentTarget;
        if (cmd) {

            if (cmd.___CausesValidation) {
                if (!this.IsValid()) {
                    Devy.Notifications.ShowError("Los datos ingresados no son válidos", this._ValidatorsErrorsSumary);
                    return;
                }
            }

            this.UpdateBusinessObject();
            this._raiseEvent("customCommandClick", cmd.___Name);
        }
    },

    get_events: function () {
        if (!this._events) {
            this._events = new Sys.EventHandlerList();
        }
        return this._events;
    },

    add_OKClick: function (handler) {
        this.get_events().addHandler('OKClick', handler);
    },
    remove_OKClick: function (handler) {
        this.get_events().removeHandler('OKClick', handler);
    },

    add_cancelClick: function (handler) {
        this.get_events().addHandler('cancelClick', handler);
    },
    remove_cancelClick: function (handler) {
        this.get_events().removeHandler('cancelClick', handler);
    },

    add_customCommandClick: function (handler) {
        this.get_events().addHandler('customCommandClick', handler);
    },
    remove_customCommandClick: function (handler) {
        this.get_events().removeHandler('customCommandClick', handler);
    },

    _raiseEvent: function (eventName, eventArgs) {
        var handler = this.get_events().getHandler(eventName);

        var theEventArgs = null;
        if (handler) {
            if (!eventArgs) {
                theEventArgs = Sys.EventArgs.Empty;
            }
            else {
                theEventArgs = eventArgs;
            }

            handler(this, theEventArgs);
        }
    },

    IsValid: function () {
        var result = true;
        var finalResult = true;

        var sbSumary = new Sys.StringBuilder();

        var maxErrorsToLog = 10;
        var errorsLogged = 0;

        sbSumary.append('<ul>');

        for (var i = 0; i < this._Fields.length; i++) {
            result = this._Fields[i].Validate();

            if (!result) {
                finalResult = false; //Deben validar TODOS

                if (errorsLogged < maxErrorsToLog) {

                    for (var j = 0; j < this._Fields[i].get_Validators().length; j++) {

                        if (!this._Fields[i].get_Validators()[j].get_IsValid()) {
                            sbSumary.append('<li>');
                            sbSumary.append(Devy.Util.HTMLEncode(this._Fields[i].get_HeaderText() + ': '));
                            sbSumary.append(Devy.Util.HTMLEncode(this._Fields[i].get_Validators()[j].get_ErrorMessage()));
                            sbSumary.appendLine('</li>');
                        }
                    }

                    errorsLogged++;
                }
                else if (errorsLogged == maxErrorsToLog) {
                    sbSumary.append('<li>Y otros errores más...</li>');
                    break;
                }
            }
        }


        sbSumary.append('</ul>');

        if (finalResult)
            this._ValidatorsErrorsSumary = '';
        else
            this._ValidatorsErrorsSumary = sbSumary.toString();

        return finalResult;
    },

    UpdateBusinessObject: function () {
        for (var i = 0; i < this._Fields.length; i++) {
            this._Fields[i].UpdateBusinessObject();
        }
    },

    _AddCommandsField: function (FieldsContainer, CSS) {
        var cmdContainer = $('<div class="Field Commands ' + CSS + '"></div>');
        $(FieldsContainer).append(cmdContainer);

        var contexto = this;

        if (this._ShowCommandOK) {
            var cmdOK = $('<a href="#" class="Command OK" title="' + this._CommandOKText + '"><span>' + this._CommandOKText + '</span></a>')[0];
            cmdContainer.append(cmdOK);

            cmdContainer.append('<span class="separador">&nbsp;</span>');

            $addHandler(cmdOK, "click", function (evt) {
                evt.preventDefault();
                contexto._onOK();
            });
        }

        //Custom Commands
        if (this._CustomCommands) {
            for (var i = 0; i < this._CustomCommands.length; i++) {
                var cmdDefinition = this._CustomCommands[i];

                var css = "Command CustomCommand";
                if (cmdDefinition.CSSClass)
                    css += " " + cmdDefinition.CSSClass;

                var name = cmdDefinition.Name;
                if (!name)
                    name = "EmptyCommandName!"

                var text = cmdDefinition.Text;
                if (!text)
                    text = name;

                var description = cmdDefinition.Description;
                if (!description)
                    description = text;

                var html = String.format('<a href="#" class="{0}" title="{1}"><span>{2}</span></a>',
                    css, description, text);

                var causesValidation = true;
                if (typeof (cmdDefinition.CausesValidation) != "undefined")
                    causesValidation = cmdDefinition.CausesValidation; //true by default

                var cmdCustom = $(html)[0];
                cmdCustom.___Name = name;
                cmdCustom.___CausesValidation = causesValidation;
                cmdContainer.append(cmdCustom);

                $addHandler(cmdCustom, "click", function (evt) {
                    evt.preventDefault();
                    contexto._onCustomCommand(evt);
                });

                cmdContainer.append('<span class="separador">&nbsp;</span>');
            }
        }

        if (this._ShowCommandCancel) {
            var cmdCancel = $('<a href="#" class="Command Cancel" title="' + this._CommandCancelText + '"><span>' + this._CommandCancelText + '</span></a>')[0];
            cmdContainer.append(cmdCancel);

            $addHandler(cmdCancel, "click", function (evt) {
                evt.preventDefault();
                contexto._onCancel();
            });
        }
    },

    _registerField: function (field, FieldsContainer, FieldDescriptor) {
        field.set_Parent(this);
        field.set_Container(FieldsContainer);
        field.set_HeaderText(FieldDescriptor.HeaderText);
        field.set_Description(FieldDescriptor.Description);
        field.set_PropertyName(FieldDescriptor.PropertyName);
        field.set_BusinessObject(this._BusinessObject);
        field.set_Validators(FieldDescriptor.Validators);
        field.set_ReadOnly(FieldDescriptor.ReadOnly);
        field.set_Properties(FieldDescriptor.Properties);
        Array.add(this._Fields, field);

        return field;
    },


    _setUpForm: function () {
        //cleanup
        if (this._FieldsContainer)$(this._FieldsContainer).empty();
        this._Fields = new Array();
        this._Validators = new Array();
    
        if (this._ShowDuplicatedCommands)
            this._AddCommandsField(this._FieldsContainer, "Top");

        if (this._FieldDescriptors) {
            this._processFieldDescriptors(this._FieldsContainer, this._FieldDescriptors);
        }

        this._AddCommandsField(this._FieldsContainer, "Bottom");

        this._FormIsSetUp = true;
    },

    _processFieldDescriptors: function (FieldsContainer, FieldDescriptors) {
        for (var _processFieldDescriptorsI = 0; _processFieldDescriptorsI < FieldDescriptors.length; _processFieldDescriptorsI++) {
            this._processFieldDescriptor(FieldsContainer, FieldDescriptors[_processFieldDescriptorsI]);
        }
    },

    _processFieldDescriptor: function (FieldsContainer, FieldDescriptor) {


        if (FieldDescriptor && FieldDescriptor.FieldType) {
            switch (FieldDescriptor.FieldType) {
                case "Date":
                    this._registerField(Devy.UI.Forms.Fields.Date.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "DateTime":
                    this._registerField(Devy.UI.Forms.Fields.DateTime.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "Boolean":
                    this._registerField(Devy.UI.Forms.Fields.Boolean.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "Number":
                    this._registerField(Devy.UI.Forms.Fields.Numeric.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "Text":
                case "String":
                    this._registerField(Devy.UI.Forms.Fields.Text.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "MultilineString":
                case "MultilineText":
                    this._registerField(Devy.UI.Forms.Fields.MultilineText.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "RichText":
                    this._registerField(Devy.UI.Forms.Fields.RichText.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "Password":
                    this._registerField(Devy.UI.Forms.Fields.Password.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "ImageURL":
                    this._registerField(Devy.UI.Forms.Fields.ImageURL.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "TagAsociations":
                    this._registerField(Devy.UI.Forms.Fields.TagAsociations.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "SecurityRules":
                    this._registerField(Devy.UI.Forms.Fields.SecurityRulesEdit.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "GEOPos":
                    this._registerField(Devy.UI.Forms.Fields.GEOPos.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "Autor":
                    this._registerField(Devy.UI.Forms.Fields.Autor.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "Categoria":
                    this._registerField(Devy.UI.Admin.Contenidos.ContenidoCategoriaEdit.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "Tag":
                    this._registerField(Devy.UI.Admin.Contenidos.ContenidoTagEdit.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "Articulo":
                    this._registerField(Devy.UI.Admin.Contenidos.ContenidoArticuloEdit.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "URLViewer":
                    this._registerField(Devy.UI.Forms.Fields.URLViewer.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "ReadOnlyHtml":
                    this._registerField(Devy.UI.Forms.Fields.ReadOnlyHtml.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "Captcha":
                    this._registerField(Devy.UI.Forms.Fields.Captcha.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "Carpeta":
                    this._registerField(Devy.UI.Admin.Recursos.RecursosCarpetaEdit.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;

                case "Custom":
                    this._registerField(FieldDescriptor.CustomControl, FieldsContainer, FieldDescriptor);
                    break;


                case "FieldGrupContainer":
                    this._AddFieldGrupContainer(FieldsContainer, FieldDescriptor);
                    break;

                default: /*Text*/
                    this._registerField(Devy.UI.Forms.Fields.Text.CreateObject(), FieldsContainer, FieldDescriptor);
                    break;
            }
        }
    },

    _AddFieldGrupContainer: function (FieldsContainer, FieldsGrupDescriptor) {
        if (FieldsGrupDescriptor.FieldGroups) {
            //generamos un id aleatorio
            var htmlIDprefix = "fgc" + Math.ceil(Math.random() * 100000);
            var grupContainer = $('<div id="' + htmlIDprefix + '"></div>').hide();

            //Generamos el indice 
            var sb = new Sys.StringBuilder();
            sb.appendLine('<ul>');
            for (var _AddFieldGrupContainerI = 0; _AddFieldGrupContainerI < FieldsGrupDescriptor.FieldGroups.length; _AddFieldGrupContainerI++) {
                sb.appendLine('<li><a href="#' + htmlIDprefix + "g" + _AddFieldGrupContainerI + '"><span>' +
                    FieldsGrupDescriptor.FieldGroups[_AddFieldGrupContainerI].HeaderText + '</span></a></li>');
            }
            sb.appendLine('</ul>');
            grupContainer.append(sb.toString());

            //los grupos
            for (_AddFieldGrupContainerI = 0; _AddFieldGrupContainerI < FieldsGrupDescriptor.FieldGroups.length; _AddFieldGrupContainerI++) {

                var group = $('<div id="' + htmlIDprefix + "g" + _AddFieldGrupContainerI + '"></div>')

                if (FieldsGrupDescriptor.FieldGroups[_AddFieldGrupContainerI].Description)
                    group.append('<p class="Description">' + FieldsGrupDescriptor.FieldGroups[_AddFieldGrupContainerI].Description + "</p>");

                var group_fields = $('<div class="Fields"></div>');

                group.append(group_fields);

                if (FieldsGrupDescriptor.FieldGroups[_AddFieldGrupContainerI].FieldDescriptors) {
                    this._processFieldDescriptors(group_fields, FieldsGrupDescriptor.FieldGroups[_AddFieldGrupContainerI].FieldDescriptors);
                }

                grupContainer.append(group);
            }

            var liContainer = $('<div class="Field FieldGroupContainer"></div>');

            if (FieldsGrupDescriptor.Description)
                liContainer.append('<p class="Description">' + FieldsGrupDescriptor.Description + "</p>");

            liContainer.append(grupContainer);

            $(FieldsContainer).append(liContainer);

            setTimeout(function () {
                $("#" + htmlIDprefix).tabs();
                $("#" + htmlIDprefix).show();
            }
            , 500);
        }
    },

    PrepareToShow: function () {
        for (var i = 0; i < this._Fields.length; i++) {
            this._Fields[i].PrepareToShow();
        }
    },

    _aplyAuthorization: function () {
        /*nada por el momento*/
    }
}

Devy.UI.Forms.Form.registerClass('Devy.UI.Forms.Form', Sys.Component);
