var SmartCheck = window.SmartCheck || {};
(function(NS){
    NS.FunctionManager = function (){
        if(this.constructor.instance){
        }else{
            this.constructor.instance = this;
            this.name = "niuniu";
            this.functionLib = {
                text    :   {
                    isEmail :   function(){
                                    var emailFormat = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
                                    for(var i=0;i<this.itemGroup.length;i++){
                                        if(!emailFormat.test(this.itemGroup[i].value)){
                                            return false;
                                        }
                                    }
                                    return true;
                                },
                    hasFilled   :   function(){
                                        for(var i=0;i<this.itemGroup.length;i++){
                                            if(this.itemGroup[i].value == ""){
                                                return false;
                                            }
                                        }
                                        return true;
                                    },
                    isNum   :   function(){
                                    var numFormat = /^-?[0-9]+\.?[0-9]*$/;
                                    for(var i=0;i<this.itemGroup.length;i++){
                                        if(!numFormat.test(this.itemGroup[i].value)){
                                            return false;
                                        }
                                    }
                                    return true;
                                },
                    isBiggerThan    :   function(){
                                            var numFormat = /^-?[0-9]+\.?[0-9]*$/;
                                            for(var i=0;i<this.itemGroup.length;i++){
                                                if(!numFormat.test(this.itemGroup[i].value)){
                                                    return false;
                                                }
                                                if(this.itemGroup[i].value<=arguments[0]){
                                                    return false;
                                                }
                                            }
                                            return true;
                                        },
                    isSmallerThan    :   function(){
                                            var numFormat = /^-?[0-9]+\.?[0-9]*$/;
                                            for(var i=0;i<this.itemGroup.length;i++){
                                                if(!numFormat.test(this.itemGroup[i].value)){
                                                    return false;
                                                }
                                                if(this.itemGroup[i].value>=arguments[0]){
                                                    return false;
                                                }
                                            }
                                            return true;
                                        },
                    isBetween   :   function(){
                                        var numFormat = /^-?[0-9]+\.?[0-9]*$/;
                                        for(var i=0;i<this.itemGroup.length;i++){
                                            if(!numFormat.test(this.itemGroup[i].value)){
                                                return false;
                                            }
                                            if(this.itemGroup[i].value<=arguments[0]||this.itemGroup[i].value>=arguments[1]){
                                                return false;
                                            }
                                        }
                                        return true;
                                    }
                },
                "select-one"  :   {
                    hasSelected :   function(){
                                        for(var i=0;i<this.itemGroup.length;i++){
                                            if(this.itemGroup[i].selectedIndex==0){
                                                return false;
                                            }
                                        }
                                        return true;
                                    },
                    isSelected  :   function(){
                                        var needNum = arguments.length;
                                        for(var i=0;i<this.itemGroup.length;i++){
                                            for(var j=0;j<arguments.length;j++){
                                                if(this.itemGroup[i].selectedIndex==arguments[j]){
                                                    needNum--;
                                                }
                                            }
                                        }
                                        return needNum==0;
                                    }
                },
                checkbox    :   {
                    hasChecked  :   function(){
                                        for(var i=0;i<this.itemGroup.length;i++){
                                            if(this.itemGroup[i].checked){
                                                return true;
                                            }
                                        }
                                        return false;
                                    },
                    hasCheckedMoreThan  :   function(){
                                                var needNum = arguments[0];
                                                for(var i=0;i<this.itemGroup.length;i++){
                                                    if(this.itemGroup[i].checked){
                                                        needNum--;
                                                    }
                                                }
                                                return needNum<0;
                                            },
                    hasCheckedLessThan  :   function(){
                                                var needNum = arguments[0];
                                                for(var i=0;i<this.itemGroup.length;i++){
                                                    if(this.itemGroup[i].checked){
                                                        needNum--;
                                                    }
                                                }
                                                return needNum>0;
                                            },
                    hasCheckedOnly  :   function(){
                                            var needNum = arguments[0];
                                            for(var i=0;i<this.itemGroup.length;i++){
                                                if(this.itemGroup[i].checked){
                                                    needNum--;
                                                }
                                            }
                                            return needNum==0; 
                                        },
                    isChecked   :   function(){
                                        for(var i=0;i<arguments.length;i++){
                                            if(!this.itemGroup[arguments[i]].checked){
                                                return false;
                                            }
                                        }
                                        return true;
                                    }
                },
                radio   :   {
                    hasChecked  :   function(){
                                        for(var i=0;i<this.itemGroup.length;i++){
                                            if(this.itemGroup[i].checked){
                                                return true;
                                            }
                                        }
                                        return false;
                                    },
                    isChecked  :   function(){
                                        if(this.itemGroup[arguments[0]].checked){
                                            return true;
                                        }else{
                                            return false;
                                        }
                                    }
                },
                textarea    :   {
                    hasFilled   :   function(){
                                        for(var i=0;i<this.itemGroup.length;i++){
                                            if(this.itemGroup[i].value==""){
                                                return false;
                                            }
                                        }
                                        return true;
                                    }
                },
                
                checkItemGroup  :   function(){
                                        for(var checkTypeName in this.checkType){
                                            if(!this[checkTypeName].apply(this,this.checkType[checkTypeName])){
                                                if(this.options.showMsg){
                                                    this.showMessage(this.checkType[checkTypeName][this.checkType[checkTypeName].length-1]||"Check failed!");
                                                }
                                                return false;
                                            }
                                        }
                                        return true;
                                    },
                
                checkForm   :   function(){
                                    for(var itemName in this.checkList){
                                        for(var checkTypeName in this.checkList[itemName].checkType){
                                            if(!this.checkList[itemName][checkTypeName].apply(this.checkList[itemName],this.checkList[itemName].checkType[checkTypeName][0]||[])){
                                                if(this.options.showMsg){
                                                    this.showMessage(this.checkList[itemName].checkType[checkTypeName][1]||"Form check failed!");
                                                }
                                                this.errItemName = itemName;
                                                return false;
                                            }
                                        }
                                    }
                                    return true;
                                },
                showMessage     :   function(msg){
                                        alert(msg);
                                    }
            
            };
            this.initialize();
        }
        
        
        return this.constructor.instance;
    };
    NS.FunctionManager.prototype.initialize = function(){
        var instance = this;
    }
    
    NS.FunctionManager.prototype.getItemFunction = function (){
        var instance  = this;
        var itemFunctionLib = {};
        if(typeof arguments[1] != "undefined"){
            itemFunctionLib[arguments[1]] = instance.functionLib[arguments[0]][arguments[1]];
        }else{
            itemFunctionLib.showMessage = instance.functionLib.showMessage;
            itemFunctionLib.checkItemGroup = instance.functionLib.checkItemGroup;
        }
        return itemFunctionLib;
    };
    NS.FunctionManager.prototype.getFormFunction = function (){
        var instance  = this;
        var formFunctionLib = {};
        
        formFunctionLib.checkForm = instance.functionLib.checkForm;
        formFunctionLib.showMessage = instance.functionLib.showMessage;
        
        
        return formFunctionLib;
    };
    NS.FunctionManager.prototype.getFunction = function (){
        var instance  = this;
        var libDirectory = instance.functionLib[argument[0]];
        for(var i=1;i<arguments.length;i++){
            libDirectory = libDirectory[argument[i]];
        }
        
        return libDirectory;
    };
    
    NS.MessageManager = function(){
        this.constructor.instance = this.constructor.instance || this ;
        this.messageLib = {
                            en  :   {
                                is  :   "is not",
                                has :   "has not"
                            },
                            ch  :   {
                                is  :   "不是",
                                has :   "没有"
                            }
        };
        this.initialize();
        
        return this.constructor.instance;
    }
    NS.MessageManager.prototype.initialize = function(){
    };
    NS.MessageManager.prototype.getItemMessage = function(){
    };
    NS.MessageManager.prototype.getFormMessage = function(){
    };
    NS.MessageManager.prototype.getSystemMessage = function(){
    };
    
    NS.Form = function(){
        this.formID = arguments[0]||"";
        this.checkList = {};
        this.options = arguments[1]||{};
        this.functionManager = new NS.FunctionManager(); 
        this.errItemName = "";
        //initialize form;
        try{
            this.initialize();
        }catch(err){
            return {};
        }
    };
    NS.Form.prototype.initialize = function(){
        var instance = this;
        
        instance.options.autoSubmit  =   typeof instance.options.autoSubmit == "undefined" ? false : instance.options.autoSubmit,
        instance.options.showMsg =   typeof instance.options.showMsg == "undefined" ? false : instance.options.showMsg,
        instance.options.withInnerItems   =   typeof instance.options.withInnerItems == "undefined" ? false : instance.options.withInnerItems,
        instance.options.withDefaultCheck   =   typeof instance.options.withDefaultCheck == "undefined" ? false : instance.options.withDefaultCheck;
        
        var formFunctionLib = instance.functionManager.getFormFunction();
        for(key in formFunctionLib){
            instance[key] = formFunctionLib[key];
        }
        if(instance.options.autoSubmit){
            instance.addEventListener();
        }
        
        //initialize default checkType for each itemGroup
        if(instance.options.withInnerItems){
            for(var i = 0;i < document.getElementById(instance.formID).elements.length;i++){
                var newItemGroup = new NS.ItemGroup(document.getElementById(instance.formID).elements[i].name,{withDefaultCheck:instance.options.withDefaultCheck});
                if(newItemGroup.itemName){
                    instance.addItemGroup(newItemGroup);
                }
            }
        }
    };
    NS.Form.prototype.addItemGroup = function(){
        var instance = this;
        var itemName;
        var newItemGroup;
        if(typeof arguments[0] == "string"){
            itemName = arguments[0];
            newItemGroup = new NS.ItemGroup(arguments[0],{withDefaultCheck:instance.options.withDefaultCheck});
        }
        if(arguments[0] instanceof NS.ItemGroup){
            itemName = arguments[0].itemName;
            newItemGroup = arguments[0];
        }
        
        instance.checkList[itemName] = newItemGroup;
        
        return instance;
    };
    NS.Form.prototype.addEventListener = function(){
        var instance = this;
        
        //addEventListener attachEvent is better
        document.getElementById(instance.formID).onsubmit = function(){
            return instance.checkForm.apply(instance);
        }
    };
    
    
    
    
    
    NS.ItemGroup = function(){
        this.itemName = arguments[0]||"";
        this.checkType = {};
        this.options = arguments[1]||{};
        
        this.functionManager = new NS.FunctionManager(); 
        //rest job do here
        try{
            this.initialize();
        }catch(err){
            return {};
        }
    };
    
    NS.ItemGroup.prototype.addCheckType = function(){
        var instance = this;
        //turn to real array;
        var options = [];
        for(var i = 0;i<arguments.length;i++){
            options.push(arguments[i]);
        }
        
        instance[options[0]] = instance.functionManager.getItemFunction(instance.itemType,options[0])[options[0]];
        instance.checkType[options.shift()] = options;

        return instance;
    }
    NS.ItemGroup.prototype.setCheckType = function(){
        var instance = this;
        
        instance.checkType = arguments[0]||instance.checkType;
        
        return instance;
    }
    NS.ItemGroup.prototype.deleteCheckType = function(){
        var instance = this;
        
        for(var i = 0;i<arguments.length;i++){
            if(typeof instance.checkType[arguments[i]] != "undefined"){
                delete instance.checkType[arguments[i]];
                delete instance[arguments[i]];
            }
        }
        
        return instance;
    }
    
    NS.ItemGroup.prototype.initialize = function(){
        var instance = this;
        
        instance.options.withDefaultCheck = typeof instance.options.withDefaultCheck == "undefined" ? false : instance.options.withDefaultCheck ;
        instance.options.showMsg    =   typeof instance.options.showMsg == "undefined" ? false : instance.options.showMsg ;
        
        instance.itemName = instance.constructor.arguments[0];
        //accept form id
        if(instance.constructor.arguments[1]&&instance.constructor.arguments[1].formID){
            instance.itemGroup = document.getElementById(instance.constructor.arguments[1].formID)[instance.constructor.arguments[0]];
        }else{
            instance.itemGroup = document.getElementsByName(instance.constructor.arguments[0]);
        }
        
        //prepare all the item into array or pseudo array
        if(typeof(instance.itemGroup.length)=="undefined"){
            instance.itemGroup = [instance.itemGroup];
        }
        
        instance.itemType = instance.itemGroup[0].type;
        var defaultFunctionMap = {
            "text"    :   "hasFilled",
            "select-one"  :   "hasSelected",
            "checkbox"    :   "hasChecked",
            "radio"   :   "hasChecked",
            "textarea"    :   "hasFilled"
        };
        //prepare method for item
        var itemFunctionLib = instance.functionManager.getItemFunction(instance.itemType);
        for(key in itemFunctionLib){
            instance[key] = itemFunctionLib[key];
        }
        
        //set default checkType
        if(instance.options.withDefaultCheck){
            instance.addCheckType(defaultFunctionMap[instance.itemType]);
        }
    };
    
    
})(SmartCheck);


