/*
* Validator Controller
* Parameter 
* @ formName : Validator 을 실행할 form 태그의 name 속성 값
* @ defaultMessageType : 메세지 출력 방식. 기본값은 alert 형태
*/
function Validator(formName) {
    this.formName = formName;
    this.formElements = new Array();
    this.defaultErrorMessage = "Not valid";
    this.defaultValidMessage = "";
    this.defaultMessageType = "alert";
    
    this.addValidate = function(elemId, eventName, condition, messageType, errorMessage, validMessage, focusElement) {

        var index = this.findFormElementIndex(elemId, eventName);
        var elem = index > -1 ? this.formElements[index] : new FormElement(elemId, eventName);
        
        if (condition.constructor != Array) {
            condition = [condition];
        }

        errorMessage = errorMessage || this.defaultErrorMessage;
        validMessage = validMessage || this.defaultValidMessage;
        messageType = messageType || this.defaultMessageType;
        focusElement = focusElement || elem.objForm;


        for( var i=0; i<condition.length; i++) {
        	elem.addValidationCondition(condition[i], errorMessage, validMessage, focusElement, messageType);
            //elem.addValidationCondition(condition[i], errorMessage, validMessage, elem.objForm, messageType);
        }

        if (index == -1) {
            this.formElements.push(elem);
        } else {
            this.formElements.splice(index,1,elem);
        }
    };

    this.findFormElementIndex = function(elemId, eventName) {
        var elems = this.formElements;

        for (var i=0; i<elems.length; i++) {
            if (elems[i].id == elemId && 
                elems[i].eventName == eventName) {
                return i;
            }
        }

        return -1;
    };

    this.registEvent = function(elem) {
        var execute = function() { elem.validate(); };

        if (document.all) {
            elem.objForm.attachEvent(elem.eventName, execute);
        } else {
            elem.objForm.addEventListener(elem.eventName.replace("on",""), execute, false);
        }
    };

    this.startEventListner = function(executeValidate) {
        var elems = this.formElements;
        var executeValidate = executeValidate == null ? true : executeValidate;
        for (var i=elems.length-1; i >= 0; i--) {
            this.registEvent(elems[i]);
        }
        
        if (executeValidate) {
            return this.validate();
        }

    };

    this.validate = function() {
        var elems = this.formElements;
        var result = true;
//        for (var i=0; i<elems.length; i++) {
      for (var i=elems.length-1; i >= 0; i--) {
            if (!elems[i].validate()) {
                result = false;
                break;
            }
        }
        return result;
    }

    this.submit = function(useValidation) {

        useValidation = useValidation || true;
        if (useValidation && !this.validate()) {
            return false;
        }

        document.forms[this.formName].submit();
    }
}


/*
* FormElement
* Form Object 와 Event 로 구성된 클래스
* Form Object 와 Event 를 key 로 같은 key 에 여러개의 ValidationCondition 을 등록 할 수 있다
*
* Parameter 
* @ elemId : Form Object 의 id 속성
* @ eventName : 해당 Form Object 의 event. 이 파라메터에 해당하는 이벤트에 등록된 Validation 이 실행됨
*/
function FormElement(elemId, eventName) {
    this.id = elemId;
    this.objForm = document.getElementById(elemId);
    this.eventName = eventName;
    this.validationCondition = new Array();
    
    this.addValidationCondition = function(condition, errorMessage, validMessage, focusElement, messageType) {
        this.validationCondition.push(new ValidationCondition(condition, errorMessage, validMessage, focusElement, messageType));
    }

    this.validate = function() {
        var result = true;
        var message = "";
        var messageType = "";
        var focusElement;
     
        for (var i=0; i<this.validationCondition.length; i++) {
            var condition = this.validationCondition[i];

            if (condition.condition.constructor == Function) {
                result = condition.condition.apply();
            } else if (condition.condition.constructor == String) {
                result = executeValidate(condition.condition, this.objForm);
            }

            messageType = condition.messageType;

            if (result) {
                message = condition.validMessage;
            } else {
            	
                message = condition.errorMessage;
                focusElement = condition.focusElement;
                break;
            }
        }
        outputMessage(message, messageType, result);
		if (!result) { 
			focusElement.focus();
		}
        return result;
    };
}


/*
* ValidationCondition
* Form Object 의 Validation 상태 
*
* Parameter 
* @ condition : Validation 검사를 할 조건
* @ errorMessage : Validation 검사를 통과하지 못했을 때 메세지
* @ validMessage : Validation 검사를 통과했을때 메세지
* @ focusElement : Validation 검사를 통과하지 못했을 때 포커스가 이동할 컨트롤
* @ messageType : 통과 혹은 에러시 메세지를 출력하는 방법 ( alert 혹은 div 에 출력 )
*/
function ValidationCondition(condition, errorMessage, validMessage, focusElement, messageType) {
    this.condition = condition;
    this.errorMessage = errorMessage;
    this.validMessage = validMessage;
    this.focusElement = focusElement;
    this.messageType = messageType;
}


function outputMessage(message, outputTarget, result) {
    if(!outputTarget.isEmpty() && outputTarget != "alert") {
        document.getElementById(outputTarget).innerHTML = message;
    } else {
        if (!result) {
            alert(message); 
        }
    }
}

String.prototype.isEmpty = function() {
    return isEmpty(this);
}

function isEmpty(str) {
    return str == null || str.trim() == "";
}

function executeValidate(condition, elem) {
    var delimit = findDelimit(condition);
    var type = condition.split(delimit)[0];
    var value = condition.split(delimit)[1];
    
    if (type == "required") {
        return checkRequired(elem.value);
    } else if (type == "length") {
        return eval(elem.value.trim().length + delimit + value);
    } else if (type == "byte") {
        return eval(getBytesLength(elem.value.trim()) + delimit + value);
    } else if (type == "value") {
        return checkEqual(elem.value, eval(value));
    } else if (type == "alphaNum") {
        return checkAlphaNum(elem.value);
    } else  if (type == "email") {
        return isEmail(elem.value);
    } else  if (type == "alpah") {
        return checkAlpah(elem.value);
    } else  if (type == "hangul") {
        return CheckHangul(elem.value.trim());
    } else  if (type == "phoneCheck") {
        return phoneCheck(elem.value);
    } else  if (type == "notHangul") {
        return checkAlpah2(elem.value);
    } else  if (type == "alpah3") {
        return checkAlpah3(elem.value);
    } else  if (type == "checkNum") {
        return phoneCheck(elem.value);
    } else  if (type == "hangul2") {
        return CheckHangul2(elem.value.trim());
    } else  if (type == "email") {
        return isEmail(elem.value);                                    
    }else  if (type == "emailEmpty") {
        return emailEmpty(elem.value);
    }else  if (type == "phoneEmpty") {
        return phoneEmpty(elem.value);
    }else {
        alert("존재하지 않는 유효식");
        return false;
    }
}

function findDelimit(str) {
    if (str.indexOf(">=") > 0) {
        return ">=";
    } else if (str.indexOf("<=") > 0) {
        return "<=";
    } else if (str.indexOf(">") > 0) {
        return ">";
    } else if (str.indexOf("<") > 0) {
        return "<";
    } else if (str.indexOf("=") > 0) {
        return "=";
    } else {
        return "\r";
    }
}

function checkRequired(value) {
    return value.trim() != "";
}

function checkGreaterThen(targetValue, compareValue) {
    return targetValue > compareValue;
}

function checkLessThen(targetValue, compareValue) {
    return targetValue < compareValue;
}

function checkEqual(targetValue, compareValue) {
    return targetValue == compareValue;
}

function checkAlpah(value) {
    return checkRegex(/^[a-zA-Z|\s]+$/i,value);
}

function checkAlphaNum(value) {
    return checkRegex(/^[a-zA-Z0-9|\s]+$/i, value);
}

function checkNum(value) {
    return checkRegex(/^[0-9]+$/i, value);
}

function checkRegex(pattern, value) {
    return pattern.test(value);
}

function getBytesLength(value) {
    return value.length+(escape(value)+"%u").match(/%u/g).length-1
}

String.prototype.trim = function() {
    return this.replace(/^\s+/,"").replace(/\s+$/,"");
}

function isEmail(s){
	if(s.search(/^\s*[\w\~\-\.]+\@[\w\~\-]+(\.[\w\~\-]+)+\s*$/g)>=0){
		return true;
	}else{
		return false;
	}	 
}
function CheckHangul(str) { 
    strarr = new Array(str.length); 
    schar = new Array('/','.','>','<',',','?','}','{',' ','\\','|','(',')','+','='); 
    flag = true; 

    for (i=0; i<str.length; i++) { 
    	if (escape(str.charAt(i)) == "%20") {
        	continue;
        }
        for (j=0; j<schar.length; j++) { 
            if (schar[j] ==str.charAt(i)) { 
                flag = false; 
            } 
        } 
        strarr[i] = str.charAt(i) 

        if ((strarr[i] >=0) && (strarr[i] <=9)) { 
            flag = false; 
        } else if ((strarr[i] >='a') && (strarr[i] <='z')) { 
            flag = false; 
        } else if ((strarr[i] >='A') && (strarr[i] <='Z')) { 
            flag = false; 
        } else if ((escape(strarr[i]) > '%60') && (escape(strarr[i]) <'%80') ) { 
            flag = false; 
        }
    } 
    if (flag) { 
    
        return true; 
    } else { 
    
        return false; 
    } 
     
}
function CheckHangul2(str) { 
    strarr = new Array(str.length); 
    schar = new Array('/','>','<',',','?','}','{',' ','\\','|','+','='); 
    flag = true; 

    for (i=0; i<str.length; i++) { 
    	if (escape(str.charAt(i)) == "%20") {
        	continue;
        }
        for (j=0; j<schar.length; j++) { 
            if (schar[j] ==str.charAt(i)) { 
                flag = false; 
            } 
        } 
        strarr[i] = str.charAt(i) 

        if ((strarr[i] >=0) && (strarr[i] <=9)) { 
            flag = false; 
        } else if ((strarr[i] >='a') && (strarr[i] <='z')) { 
            flag = false; 
        } else if ((strarr[i] >='A') && (strarr[i] <='Z')) { 
            flag = false; 
        } else if ((escape(strarr[i]) > '%60') && (escape(strarr[i]) <'%80') ) { 
            flag = false; 
        }
    } 
    if (flag) { 
        return true; 
    } else { 
        return false; 
    } 
}
function checkAlpah2(str) { 
    strarr = new Array(str.length); 
    schar = new Array('/','>','<',',','?','}','{',' ','\\','|','+','='); 
    flag = true; 

    for (i=0; i<str.length; i+1) { 
    	if (escape(str.charAt(i)) == "%20") {
        	continue;
        }
        for (j=0; j<schar.length; j+1) { 
            if (schar[j] ==str.charAt(i)) { 
                flag = false; 
            } 
        } 
        strarr[i] = str.charAt(i) 

        if ((strarr[i] >=0) && (strarr[i] <=9)) { 
            flag = false; 
            break;
        } else if ((strarr[i] >='a') && (strarr[i] <='z')) { 
            flag = true; 
        } else if ((strarr[i] >='A') && (strarr[i] <='Z')) { 
            flag = true; 
        } else if ((escape(strarr[i]) > '%60') && (escape(strarr[i]) <'%80') ) { 
            flag = false; 
            break;
        }
    } 
    return flag;
}
function checkAlpah3(value) {
    return checkRegex(/^\s*[a-zA-Z|\s\(\)]+\s*[\w\-\_\.\,\(\)\" "]+\s*$/i,value);
}
function isEmail(s){
	if(s.search(/^\s*[\w\~\-\_\.]+\@[\w\~\-]+(\.[\w\~\-\_]+)+\s*$/g)>=0){
		return true;
	}else{
		return false;
	}	 
}

function phoneCheck(nr1){
  flg=0;
  str="";
  spc=""
  arw="";
  for (var i=0;i<nr1.length;i++){
   cmp="-0123456789"
   tst=nr1.substring(i,i+1)
   if (cmp.indexOf(tst)<0){
    flg++;
    str+=" "+tst;
    spc+=tst;
    arw+="^";
   }
   else{arw+="_";}
  }
  if (flg!=0){
   if (spc.indexOf(" ")>-1) {
    str+=" and/or a space";
    }
   return false;
  }
  return true;
}
function phoneEmpty(value){
	return value.trim() != "--";
}
function emailEmpty(value){
	return value.trim() != "@";
}

