var EMAIL_FORM_CLASS = "EmailForm";

/* -------------------------------------------------------------------------- */
/**
 * EmailForm component manager
 */
function EmailFormManager() {
    this.componentClass = EMAIL_FORM_CLASS;
}
EmailFormManager.prototype = new AbstractComponentManager();
EmailFormManager.prototype.constructor = AbstractComponentManager;
/* Instance methods */
EmailFormManager.prototype.toString = function () { return "EmailFormManager" };
EmailFormManager.prototype.registerComponent = function registerComponent(id, props) {
        this._nComponents.push(new EmailForm(id, props));
    }; // registerComponent

/* -------------------------------------------------------------------------- */
/**
 * EmailForm component
 * Note: this uses JsCalendar
 */
function EmailForm(id, props) {
    AbstractComponent.apply(this, [id, props]);
}
/* STATIC MEMBERS */

EmailForm._messages = {};
EmailForm.addMessage = function addMessage(key, msg) {
        EmailForm._messages[key] = msg;
    };

EmailForm.dateInputStrategy = "dateInputStrategy";
EmailForm.dateInputStrategy_CalendarNonEditable = function() {
        // this strategy uses a JsCalendar object

        $jq(".proposedValues").each(function() {
                var jDateFields = $jq("input:visible", this).filter("[@name$=dayOfMonth], [@name$=month], [@name$=year]");
                if(0 != jDateFields.size()) {
                    this.style.backgroundColor = "yellow";
                    if(!Calendar) { alert("Calendar class is not accessible"); }
                    jDateFields.attr("class","hidden"); // hide the input objects
                    var html = "<span class='dateAsString'>28-10-2007</span>" +
                                "<button type='button' class='calendarCaller'></button>";
                    jDateFields.children(".calendarCaller").empty();

                    jDateFields.filter(":first").before(html);
                    $jq(this).children(".calendarCaller").click(function() {
                        alert("calendar not implemented");
                        //var cal = Calendar.getInstance();
                        //cal.open();
                    });
                }// if
            });
    };
EmailForm.dateInputStrategy_CalendarEditable = function() { };
EmailForm.dateInputStrategy_CalendarSelectableEditable1 = function() {
        // dayOfMonth and month inputs are replaced by selects
        // this strategy uses a JsCalendar object

        var dayOfMonthOptionHtml = "<option value=''>DD</option>", monthOptionsHtml = "<option value=''>MM</option>",
            monthsLabels = ["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"];
        for(var d=1;d<32;d++) {
            dayOfMonthOptionHtml += "<option value='"+d+"'>"+(d<10? ("0"+d):""+d) +"</option>";
        }
        for(var m=0;m<12;m++) {
            monthOptionsHtml += "<option value='"+(m+1)+"'>"+monthsLabels[m]+"</option>";
        }
        $jq(".proposedValues").each(function() { // for each set of date fields
                var jDateFields = $jq("input:visible", this).filter("[@name$=dayOfMonth], [@name$=month]"); // retrieve dayOfMonth and month inputs
                if(0 != jDateFields.size()) {
                    this.style.backgroundColor = "yellow";
                    if(!Calendar) { alert("Calendar class is not accessible"); }
                    var onSelectEventHandler = function(calendar, date) {
                            /* a definir*/
                        };
                    var cal = new Calendar(1, null, onSelectEventHandler, null);


                    jDateFields.each(function() { // for each date field
                        var opts = "";
                        switch(this.name.replace(/^[^-]*-/,"")) { // retrieve the type of field and define an option set
                            case "dayOfMonth": opts = dayOfMonthOptionHtml; break;
                            case "month":      opts = monthOptionsHtml;      break;
                        }
                        var classNames = this.className;
                        $jq(this).addClass("replacable").before("<select name='"+this.name+"' class='"+classNames+"'>"+opts+"</select>"); // prepare remplacement and insert selects
                        $jq(this.parentNode).children(".replacable").remove(); // remove old fields
                    });
                    var randomInt = parseInt(Math.random()*10000);
                    $jq(".year:visible", this)
                        .after("<button type='button' class='calendarCaller' id='calendarCaller-"+randomInt+"'></button>" +
                                "<input type='hidden' id='dateValue-"+randomInt+"'/>"); // insert a calendar caller after the year input


                    var selected = function (cal, date) {
                      cal.sel.value = date; // just update the date in the input field.
                      if (cal.dateClicked) {
                          // if we add this call we close the calendar on single-click.
                          // just to exemplify both cases, we are using this only for the 1st
                          // and the 3rd field, while 2nd and 4th will still require double-click.
                          cal.callCloseHandler();
                      }
                    }


                    var closeHandler = function(cal) {
                      /*cal.hide(); // hide the calendar
                      window.sharedCalendar = null;
                      */
                      window.sharedCalendar.hide(); // hide the calendar
                      cal = null;
                    }

                    var showCalendar = function(id) {
                          var el = document.getElementById(id);
                          if (window.sharedCalendar) { // we already have some calendar created
                            window.sharedCalendar.hide();      // so we hide it first.

                          } else { // first-time call, create the calendar.
                            var cal = new Calendar(1, null, selected, closeHandler);
                            cal.showsOtherMonths = true;
                            window.sharedCalendar = cal; // remember it in the global var
                            cal.setRange(1900, 2070);    // min/max year allowed.
                            cal.create();
                          }
                          sharedCalendar.setDateFormat("'%d-%m-%Y'");    // set the specified date format
                          sharedCalendar.parseDate(el.value);      // try to parse the text in field
                          sharedCalendar.sel = el;                 // inform it what input field we use

                          // the reference element that we pass to showAtElement is the button that
                          // triggers the calendar.  In this example we align the calendar bottom-right
                          // to the button.
                          sharedCalendar.showAtElement(el, "Br");        // show the calendar

                          return false;
                        }


                    $jq(this).children(".calendarCaller").each(function() {
                            $jq(this).click(function() {
                                    var numSuffix = this.id.replace(/^[^-]*-/,"");
                                    showCalendar("dateValue-"+numSuffix);
                                });
                        });


                }// if
            });
};
EmailForm.dateInputStrategy_CalendarSelectableEditable2 = function() { };


/* CONTRUCTOR */
EmailForm.prototype = new AbstractComponent();
EmailForm.prototype.constructor = EmailForm;

/* INSTANCE MEMBERS */
EmailForm.prototype.toString = function() { return "EmailForm, id: "+this._id; };

EmailForm.prototype.init = function init() {

        this.setDomElementById(this._id);

        if(!this.requireInit()) {
            return;
        }

        try {

            var forms = $jq("#"+this._id+" form");
            var componentId = this._id;

            var dateInputStrategy = EmailForm._messages[EmailForm.dateInputStrategy];
            if(dateInputStrategy && dateInputStrategy.constructor == Function) {
                this.initDateInputs = dateInputStrategy;
                this.initDateInputs();
            }

            var validate = function validate() { // applicable to a FORM object
                    var validationStatus = true;

                    $jq("#"+componentId+" .setting-missing").removeClass("setting-missing").addClass("setting-required");

                    try {

                    this.nElements = {};
                    var nonInputTagNameRE = /(^FIELDSET$)|(^BUTTON$)|(^OPTION$)|(^OPTGROUP$)/;
                    for(var i=0; i<this.elements.length; i++) {
                        var fElem = this.elements[i];
                        var tagName = fElem.tagName.toUpperCase();
                        if("SELECT"==tagName) {
                            debugger;
                        }
                        if(nonInputTagNameRE.test(tagName)) {
                            continue;
                        }
                        if(""==fElem.value) {
                            continue;
                        }

                        if((("INPUT" == tagName || "TEXTAREA" == tagName) && !fElem.value) || ("SELECT" == tagName && !fElem.options[fElem.selectedIndex].value)) {
                            var msg = "this.elements["+i+"] is null-value";
                            alert(msg);
                            throw new Error(msg);
                        }

                        if(!fElem.name) {
                            var msg = "this.elements["+i+"] has no name";
                            alert(msg);
                            throw new Error(msg);
                        }

                        if(!this.nElements[fElem.name]) {
                            this.nElements[fElem.name] = { values:[], specs:[] };
                        }

                        if(/^@.*/.test(fElem.value)) {
                            this.nElements[fElem.name].specs.push(fElem.value);
                        } else {
                            if("SELECT"==tagName) {
                                if(-1!=fElem.selectedIndex && ""!=fElem.options[fElem.selectedIndex].value) {
                                    this.nElements[fElem.name].values.push(fElem.options[fElem.selectedIndex].value);
                                }
                            } else if("INPUT"== tagName && /(^CHECKBOX$)|(^RADIO$)/.test(fElem.type.toUpperCase())) {
                                if(fElem.checked) {
                                    this.nElements[fElem.name].values.push(fElem.value);
                                }

                            } else if(!/^[ \t\n\r]*$/.test(fElem.value)){
                                this.nElements[fElem.name].values.push(fElem.value);
                            }
                        }
                    }


                    $jq("#"+componentId+" [class^='setting']").each(function(i) { this.id = "setting"+String(componentId)+"-"+String(i); });
debugger;
                    var missingSettingLabels = {};
                    for(var name in this.nElements) {
                        var namedValues = this.nElements[name].values;
                        var namedSpecs = this.nElements[name].specs;
                        //msg += "\n\n\n"+name+":";
                        //msg += "\nspecs : "+namedSpecs.join("; ");
                        //msg += "\nvalues:"+namedValues.join("; ");

                        for(var i=0; i<namedSpecs.length; i++) {
                            var spec = namedSpecs[i];
                            if("@required"==spec && 0==namedValues.length) {
                                validationStatus = false;
                                var selector = "#"+componentId+" *[name='"+name+"']";
                                $jq(selector).each(function() {
                                        var node = this;
                                        if(this.type && "HIDDEN"==this.type.toUpperCase()) {

                                            while(node) {
                                                if(node.className && /setting-/.test(node.className)) {
                                                    if("setting-required"==node.className) {
                                                        node.className = "setting-missing";
                                                    }
                                                    break;
                                                }
                                                node = node.parentNode;
                                            }

                                        } else {

                                            while(node) {
                                                if(node.className && /setting-/.test(node.className)) {
                                                        var labels = $jq("#"+node.id+" label").not(".proposedValues label");
                                                        var l = (labels[0].innerText ? labels[0].innerText : labels[0].textContent).replace(/(^ +)|(\*)|( +$)/,"");
                                                        if(l) { missingSettingLabels[l] = "any"; }
                                                    break;
                                                }
                                                node = node.parentNode;
                                            }
                                        }
                                    });
                            }
                        }
                    }

                    var msg = "";
                    for(var label in missingSettingLabels) {
                        msg += "\n - "+label;
                    }
                    if(""!=msg) {
                        alert("This form contains one or several errors.\n\nPlease check the highlighted fields:" + msg);
                    }

                    } catch(exc) {
                        alert(exc.message);
                    }
               
                    //Validate captcha
                    $jq.ajax({
                       async: false,
                       cache: false,
                       url: "jsp/checkcaptcha.jsp",
                       data: "objId="+componentId.replace(/emailform/ig,"")+"&captcha"+componentId.replace(/emailform/ig,"")+"="+$jq("input[name='captcha"+componentId.replace(/emailform/ig,"")+"']").val(),
                       dataType:"json",
                       success: function(data,textStatus,jqXHR){
                          if(data && data["valid"]){
                             validationStatus = validationStatus && data["valid"];
                          } else {
                             validationStatus = false;
                             alert("Introduzca por favor la captcha correctamente");
                          }
                       }
                    });

                    return validationStatus;
                };
            var onSubmitEventHandler = function(e) {
                    var self = null; // reference to the DOM object that emitted the event
                    if(e.target) {
                        self = e.target;
                        e.stopPropagation();
                    } else if(window.event.srcElement) {
                        self = window.event.srcElement;
                        window.event.cancelBubble = true;
                    }
                    if(!self) {
                        var msg = "Error: onSubmitEventHandler, self is null";
                        alert(msg);
                        throw new Error(msg);
                    }

                    var isValidated = null;
                    try {
                        isValidated = self.validate();
                    } catch(exception) {
                        alert(exception.message);
                        isValidated = false;
                    }
                    if(!isValidated && e.preventDefault) { // Mozilla
                        e.preventDefault();
                    }

                    return isValidated;
                }; // onSubmitEventHandler


            forms.each(function() {
                    var self = this;
                    this.validate = validate;
                    // add the event handler to the form
                    if(this.addEventListener) { // DOM2 : Mozilla, Opera
                        this.addEventListener("submit", onSubmitEventHandler, false);
                    } else if(this.attachEvent) { // IE
                        this.attachEvent("onsubmit", onSubmitEventHandler);
                    }
                });


        } catch(exception) {
            alert(exception);
            throw new Error(exception.toString());
        }


        this.setInitialized(true);
    }; // EmailForm.prototype.init

/* -------------------------------------------------------------------------- */
/**
 * Execution
 */
application.addComponentManager(new EmailFormManager(application));

