/*  */

var form = {
    
    c: {
        classNameByError: 'red',
        selectorMarkContainer: '.mark-container',
        isSkinning: false,
        tipText: '',
        calendarButtonImage: ''
    },
    
    obj: null,
    element: new Array(),
    group: new Array(),
    
    init: function(formSelector, options){
        
        this.c = jQuery.extend(this.c, options);
        
        this.element = new Array();
        this.obj = jQuery(formSelector).get(0);
    },
    
    addElement: function(selector, type, options){
        
        var pattern = null;
        type = (type.substr(0,1) == "/") ? eval(type) : type; 
        var typeOfType = typeof type;
        if ((typeOfType.toLowerCase() == "object") || (typeOfType.toLowerCase() == "function")) {
            pattern = type;
            type = 'pattern';
        }
        var mandatory = (typeof(options.mandatory)!='undefined') ? options.mandatory : false;
        
        var elm = new formElement(selector, type, mandatory, pattern, options);
        if (elm) this.element.push(elm);
    },
    
    validateForm: function(){
        var valid = true;
        
        if (this.element != null)
            for(var i=0; i < this.element.length; i++){
                if (this.element[i].checkElement() == false) valid = false;
            }
        if (this.group != null)
            for(var i=0; i < this.group.length; i++){
                if (this.group[i].checkGroup() == false) valid = false;
            }
            
        return valid;
    },
    addGroup: function(groupName, options){
    
        var mandatory = (typeof(options.mandatory) != 'undefined') ? options.mandatory : false;
        var rule = (typeof(options.rule) != 'undefined') ? options.rule : 'OR';
        
        var group = new formGroup(groupName, mandatory, rule);
        this.group.push(group);
    },
    
    addElementToGroup: function(groupName, elementSelector, elementType, options){
        for(var i=0; i<this.group.length;i++) {
            if (this.group[i].groupName == groupName) {
                this.group[i].addElement(elementSelector, elementType, options);
            }
        }
    }
    
    
} //form
function formElement(selector, type, mandatory, pattern, options){
    this.selector = selector; 
    this.type = ((type == 'pattern') && (pattern == null)) ? 'string' : type;
    
    switch(this.type){
        case "radio":
            this.obj = jQuery('input[type="radio"][name="'+selector+'"]');
        break;
        default:
            this.obj = jQuery(selector).get(0);
        break;
    }
    
    this.mandatory = mandatory;
    this.pattern = pattern;    
    this.options = options;
    
    this.tipText = (typeof(options.tipText) != 'undefined') ? options.tipText : '';
    
    this.markObj = null;
    this.dateFieldConfig = null;
    
    switch(this.type){
    
        case "radio" :
            this.markObj = (jQuery(this.obj.get(0)).parents(form.c.selectorMarkContainer).length > 0) ? jQuery(this.obj.get(0)).parents(form.c.selectorMarkContainer).get(0) : null;
            break;
            
        case "checkbox" :
            this.markObj = (jQuery(this.selector).parents(form.c.selectorMarkContainer).length > 0) ? jQuery(this.selector).parents(form.c.selectorMarkContainer).get(0) : null;
            break;
            
        case "text" :
        case "textarea" :
        case "email" :
        case "string" :
            this.markObj = this.obj;
            if (this.tipText != '') {
                var self = this;
                if (this.obj.value == '') this.obj.value = this.tipText;
                jQuery(this.obj).bind('focus', function(){ if (this.value == self.tipText) this.value = '' });
                jQuery(this.obj).bind('blur', function(){ if (jQuery.trim(this.value) == '') this.value = self.tipText });
            }
            break;
            
        case "date" :
            var self = this;
            this.markObj = this.obj;
            this.dateFieldConfig = {
                title: 'Kalender',
                fieldId: jQuery(this.selector).attr('id'),
                showButton: true,
                buttonId: jQuery(this.selector).attr('id')+"-dateButton",
                buttonIcon: form.c.calendarButtonImage,
                onlyFutureEnabled: false,
                currentDateEnabled: true,
                activateOnFocus: false,
                errorClass: form.c.classNameByError,
                range: {from: null, upto: null}
            };
            this.dateFieldConfig = jQuery.extend(this.dateFieldConfig, options);
            calendar.init(this.dateFieldConfig);
            
            //slaveDateField
            jQuery(document).ready(function(){
                if ((typeof(self.options.slaveDateFieldSelector) != 'undefined') && (jQuery(self.options.slaveDateFieldSelector).length > 0)) {
                    jQuery(self.obj).bind('change', function(){
                    
                        //dateFieldConfig von slaveDateField ermitteln
                        var slaveObj = null;
                        for (var i in form.element) {
                            if (form.element[i].selector == self.options.slaveDateFieldSelector) slaveObj = form.element[i];
                        }
                        
                        if (slaveObj != null) {
                            slaveObj.dateFieldConfig.range.from = self.obj.value;
                            slaveObj.dateFieldConfig.defaultDate = self.obj.value;
                            slaveObj.obj.value = '';
                            calendar.init(slaveObj.dateFieldConfig);
                        }
                        
                    });
                }
            });
            
            break;
            
        default :
            this.markObj = this.obj;
            break;
    }
    
    if (typeof(options.dependencies) != 'undefined') {
        var dependenciesProcessor = new DependenciesProcessor(selector, type, options.dependencies);
    }    
    
    this.checkElement = function(){
        
        var valid = true;
        if (this.mandatory == false) return true;
        else {
            valid = this.isValid();
            if (valid) this.clearLabelElement();
            else this.markLabelElement();
        }
        return valid;        
        
    };
    
    
    this.isValid = function(){
        
        var valid = true;
        switch(this.type){
            case "string" :
            case "text" :
                valid = this.checkTextElement();
                break;
            case "radio":
                valid = this.checkRadioElement();
                break;
            case "email":
                valid = this.checkEmailElement();
                break;
            case "checkbox":
                valid = this.checkCheckboxElement();
                break;
            case "textarea":
                valid = this.checkTextareaElement();
                break;
            case "select":
                valid = this.checkSelectElement();
                break;
            case "pattern":
                valid = this.checkPatternElement();
                break;
            case "date":
                valid = this.checkDateElement();
                break;
            case "daterange":
                break;
             default:
                valid = false;
                break;
        };
        return valid;
        
    };    
    
    
    this.checkTextElement = function(){
        if ((this.obj.value != "") && (jQuery.trim(this.obj.value) != this.tipText)) return true;
        else return false;
    };
    
    this.checkRadioElement = function(){
        var valid = false;
        for (var i=0; i< this.obj.length; i++){
            if (this.obj.get(i).checked == true) {
                    valid = true;
            }
        }
        return valid;
    };
    
    this.checkEmailElement = function(){
        if (!(this.obj.value.search(/[@.]/) >= 0) || !(this.obj.value.search(/.+@..+\...+/) >= 0) || !(this.obj.value.length >= 8)) return false;
        else return true;
    };
    
    this.checkCheckboxElement = function(){
        if (this.obj.checked != false) return true;
        else  return false;
    };
    
    this.checkTextareaElement = function(){
        if ((this.obj.value != "") && (jQuery.trim(this.obj.value) != this.tipText)) return true;
        else  return false;
    };
    
    this.checkSelectElement = function(){
        if (this.obj.value != "") return true;
        else  return false;
    };
    
    this.checkPatternElement = function(){
        if (!this.pattern.test(this.obj.value)) return false;
        else return true;
    };
    
    this.checkDateElement = function(){
       
        var strDate =  calendar.normalizeDateString(this.obj.value);
        var isDateValid = calendar.validateDate(this.dateFieldConfig, strDate);
       
        if (!isDateValid) return false;
        else return true;
    };    
    
    this.markLabelElement = function(){
        if (!form.c.isSkinning) jQuery(this.markObj).addClass(form.c.classNameByError);
        else {
            switch(this.type){
                case "string" :
                case "text" :
                case "email":
                case "pattern":
                case "date":
                    jQuery(this.markObj).parents('.jqTransformInputWrapper').addClass(form.c.classNameByError);
                    break;
                case "textarea":
                    jQuery(this.markObj).parents('.jqTransformTextarea').addClass(form.c.classNameByError);
                    break;
                case "select":
                    jQuery(this.markObj).parents('.jqTransformSelectWrapper').addClass(form.c.classNameByError);
                    break;
                case "radio":
                case "checkbox":
                    jQuery(this.markObj).addClass(form.c.classNameByError);
                    break;
            }            
        }
    };
    
    this.clearLabelElement = function(){
        if (!form.c.isSkinning) jQuery(this.markObj).removeClass(form.c.classNameByError);
        else {
            switch(this.type){
                case "string" :
                case "text" :
                case "email":
                case "pattern":
                    jQuery(this.markObj).parents('.jqTransformInputWrapper').removeClass(form.c.classNameByError);
                    break;
                case "textarea":
                    jQuery(this.markObj).parents('.jqTransformTextarea').removeClass(form.c.classNameByError);
                    break;
                case "select":
                    jQuery(this.markObj).parents('.jqTransformSelectWrapper').removeClass(form.c.classNameByError);
                    break;
                case "radio":
                case "checkbox":
                    jQuery(this.markObj).removeClass(form.c.classNameByError);
                    break;
            }
        }               
    };
    
    if (this.obj) return this;
    else return false;
}
function validateForm(){
    return form.validateForm();
}
function DependenciesProcessor(selector, elementType, dependencies){
    this.selector = selector;
    this.elementType = elementType;
    this.dependencies = dependencies;
    
    this.init = function(){
        
        var self = this;
        
        switch (elementType) {
            
            case 'radio':
                var jMaster = jQuery('input[type="radio"][name="'+this.selector+'"]');
            break;
            
            default:
                var jMaster = jQuery(this.selector);
            break;
            
        }
        
        jMaster.bind('change', function(){
            
        
            for (var i in self.dependencies) {
                
                switch (self.dependencies[i].type) {
                    case 'visibility':

                        //set default state
                        self.changeSlaveState(self.dependencies[i].slaveSelector,self.dependencies[i].defaultSlaveState);
                        
                        for (var dataIndex in self.dependencies[i].data) {
                            
                            switch (self.elementType) {
                                case 'radio':
                                    if ((this.checked) && (this.value == self.dependencies[i].data[dataIndex].masterValue))
                                        self.changeSlaveState(self.dependencies[i].slaveSelector, self.dependencies[i].data[dataIndex].slaveState);
                                break;
                                case 'checkbox':
                                    var value = (this.checked) ? this.value : '';
                                    if (value == self.dependencies[i].data[dataIndex].masterValue)
                                        self.changeSlaveState(self.dependencies[i].slaveSelector, self.dependencies[i].data[dataIndex].slaveState);
                                break;
                                default:
                                    if (this.value == self.dependencies[i].data[dataIndex].masterValue) {
                                        self.changeSlaveState(self.dependencies[i].slaveSelector, self.dependencies[i].data[dataIndex].slaveState);
                                    }
                                break;
                            }
                        }
                    
                    break;
                    
                    case 'changeValue':
                        for (var dataIndex in self.dependencies[i].data) {
                            
                            switch (self.elementType) {
                                case 'radio':
                                    if ((this.checked) && (this.value == self.dependencies[i].data[dataIndex].masterValue))
                                        self.changeSlaveValue(self.dependencies[i].slaveSelector, self.dependencies[i].slaveType, self.dependencies[i].data[dataIndex]);
                                break;
                                case 'checkbox':
                                    var value = (this.checked) ? this.value : '';
                                    if (value == self.dependencies[i].data[dataIndex].masterValue)
                                        self.changeSlaveValue(self.dependencies[i].slaveSelector, self.dependencies[i].slaveType, self.dependencies[i].data[dataIndex]);
                                break;
                                default:
                                    if (this.value == self.dependencies[i].data[dataIndex].masterValue) {
                                        self.changeSlaveValue(self.dependencies[i].slaveSelector, self.dependencies[i].slaveType, self.dependencies[i].data[dataIndex]);
                                    }
                                break;
                            }
                        }
                        
                    break;
                    
                    case 'changeValueSet':
                        
                        for (var dataIndex in self.dependencies[i].data) {
                            if ((this.value == self.dependencies[i].data[dataIndex].masterValue) && (this.checked)) {
                                self.changeSlaveValueSet(self.dependencies[i].slaveSelector, self.dependencies[i].slaveType, self.dependencies[i].data[dataIndex].slaveSet);
                            }
                        }
                        
                    break;
                }                
                
                
            }
        
        });
        
        jQuery(document).ready(function(){
            switch (self.elementType) {
                case 'radio':
                    var jMaster = jQuery('input[type="radio"][name="'+self.selector+'"]');
                break;
                default:
                    var jMaster = jQuery(self.selector);
                break;
            }        
            jMaster.change();
        });
        
    };
    
    this.changeSlaveState = function(slaveSelector, slaveState){
        
        if ((typeof(slaveState) != 'object') && (typeof(slaveState) != 'array')) return;
        
        for (var stateIndex in slaveState) {
            
            var state = slaveState[stateIndex];
            
            for (var propertyName in state) {
                
                switch (propertyName) {
                    case 'display':
                        jQuery(slaveSelector).css('display', state[propertyName]);
                    break;
                    case 'readonly':
                        if (state[propertyName] == 'true') jQuery(slaveSelector).attr('readonly','readonly');
                        else jQuery(slaveSelector).removeAttr('readonly');
                    break;
                    case 'disabled':
                        if (state[propertyName] == 'true') jQuery(slaveSelector).attr('disabled','disabled');
                        else jQuery(slaveSelector).removeAttr('disabled');
                    break;
                
                }
            }
        }
    };
    
    this.changeSlaveValue = function(slaveSelector, slaveType, data){
        
        switch (slaveType) {
            
            case 'text': 
            case 'string':
            case 'email':
            case 'date':
            case 'textarea': 
            case 'pattern':
                jQuery(slaveSelector).attr('value', data.slaveValue);
            break;
            
            case 'radio':
                jQuery('input[type="radio"][name="'+slaveSelector+'"]').each(function(){
                    if (this.value == data.slaveValue) this.checked = true;
                });
            break;
        
            case 'select':
                jQuery(slaveSelector).each(function(){
                    var selectedIndex = null;
                    for (var i=0; i<this.options.length; i++) {
                        if (this.options[i].value == data.slaveValue) selectedIndex = i;
                    }
                    if (selectedIndex != null) this.selectedIndex = selectedIndex;
                });
            break;
            
            case "checkbox":
                jQuery(slaveSelector).each(function(){
                    if (data.slaveValue == 'checked') this.checked = true;
                    else this.checked = false;
                });
            break;
        
        }
        
    };
    
    this.changeSlaveValueSet = function(slaveSelector, slaveType, slaveSet) {
        switch (slaveType) {
            case 'select':
                jQuery(slaveSelector).each(function(){
                    
                    while (this.options.length != 0) {
                        this.options[0] = null;
                    }
                    for (var i in slaveSet) {
                        jQuery(this).append(slaveSet[i]);
                    }
                });            
            break;
        }
    
    }
    
    this.init();
    
    return this;
};
function formGroup(groupName, mandatory, rule){
    this.classNameByError = 'red';
    this.element = new Array();
    this.groupName = null;
    this.mandatory = false;
    this.rule = null;
    this.selectorMarkContainer = '.mark-container';
    
    this.init = function(groupName, mandatory, rule){
        this.groupName = groupName;
        this.mandatory = mandatory;
        this.rule = rule;
    };
    
    this.addElement = function(selector, type, options){
        var pattern = null;
        type = (type.substr(0,1) == "/") ? eval(type) : type; 
        var typeOfType = typeof type;
        if ((typeOfType.toLowerCase() == "object") || (typeOfType.toLowerCase() == "function")) {
            pattern = type;
            type = 'pattern';
        }
        var mandatory = (typeof(options.mandatory)!='undefined') ? options.mandatory : false;
        
        var element = new formElement(selector, type, mandatory, pattern, options);
        if (element) this.element.push(element);
        
        return element;
        
    };
    
    this.isValid = function(){
        
        if (this.mandatory == false) return true;
        
        if (this.rule == 'AND') {
            var valid = true;
            if (this.element != null)
                for(var i=0; i < this.element.length; i++){
                    if ((this.element[i].mandatory == true) && (this.element[i].isValid() == false)) valid = false;
                }
        
        } else { //OR
        
            var valid = false;
            if (this.element != null)
                for(var i=0; i < this.element.length; i++){
                    if ((this.element[i].mandatory == true) && (this.element[i].isValid() == true)) valid = true;
                }
        }
        return valid;
    };
    
    this.markGroupContainer = function(){
        if (jQuery('.'+this.groupName+'.'+this.selectorMarkContainer).length == 0) jQuery(this.selectorMarkContainer+'.'+this.groupName).addClass(this.classNameByError);
        else jQuery('.'+this.groupName+'.'+this.selectorMarkContainer).addClass(this.classNameByError);
    };
    this.clearGroupContainer = function(){
        if (jQuery('.'+this.groupName+'.'+this.selectorMarkContainer).length == 0) jQuery(this.selectorMarkContainer+'.'+this.groupName).removeClass(this.classNameByError);
        else jQuery('.'+this.groupName+'.'+this.selectorMarkContainer).removeClass(this.classNameByError);
    };
    
    
    this.checkGroup = function(){
        
        var valid = this.isValid();
        
        if ( valid == false)  this.markGroupContainer();
        else this.clearGroupContainer();
        
        return valid;
    }
    
    
    this.init(groupName, mandatory, rule);
};
