expediaNS.namespace("expediaNS.cx.wizard");

expediaNS.cx.wizard.VALIDATIONTYPE = {
    isOrigNotEmpty : 0,
    isDestNotEmpty : 1,
    isOrigValid : 2,
    isDestValid : 3,
    isStartDateValid : 4,
    isEndDateValid : 5,
    isEndDateAfterStartDate : 6,
    areDatesValid: 7,    
    isEmailValid: 8,
    isMultiFlightOriginValid : 9,
    isMultiFlightDestinationValid : 10,
    isMultiFlightOriginNotEmpty : 11,
    isMultiFlightDestinationNotEmpty : 12,
    isMultiFlightDateValid : 13,
    isEndDateAfterOrEqualStartDate : 14
}

expediaNS.cx.wizard.FIELDTYPE = {
    any : 0,
    nbAdults : 1,
	nbSeniors : 2,
	nbChildren : 3,
	childrenAge : 4,
	origin : 5,
	destination : 6,
	previousOrigin : 7,
	previousDestination : 8,
	date : 9
}

expediaNS.cx.wizard.DATEFORMAT = {
    EU : 0,
    US : 1,
	SE: 2
}

expediaNS.cx.wizard.VValidationAgent = function() {
    var obj = {};
    
    var p_errController = null;
    var p_messages = null;
    var p_vDatesRegEx = null;
    var p_useUSDtFmt = false;
    var p_dateFormat = null;
    var validations = new Array();
    var isFormValid = true;
    var messagesShown = new Array();
    
    obj.reset = function(){
        p_errController.reset(validations);
        validations = new Array();
    }
    
    obj.register = function(valObj){
        validations.push(valObj);
    }
    
    obj.unRegister = function(idToRemove){
        for(var i=0; i < validations.length; i++) {
            var id = validations[i].getId();
            if (id == idToRemove) {
                expediaNS.cx.util.array.remove(validations, i);
                return;
            }
        }
    }
    
    obj.validate = function(){
        
        isFormValid = true;
        
        p_errController.reset(validations);
        messagesShown = new Array();
        
        for(var i=0; i < validations.length; i++)
        {
            if(!validations[i].doValidation(p_dateFormat)){
                isFormValid = false;
                var msg = validations[i].getMessage();
                if (!expediaNS.cx.util.array.exists(messagesShown, msg)) {
                    p_errController.showErrorMessage(msg);
                    messagesShown.push(msg);
                }
                p_errController.highlightError(validations[i]);
            }
        }

        return isFormValid;
    }
    
    obj.setMessages = function (vMessages) {
        p_messages = vMessages;
    }
    
    obj.setErrorController = function(vErrMsgCtrl) {
        p_errController = vErrMsgCtrl;
    }
    
    obj.setDateFormat = function(dateFormat) {        
        switch (dateFormat)
	    {
	        case expediaNS.cx.wizard.DATEFORMAT.US:
                p_dateFormat = "mmddyy";
                return;            
	        case expediaNS.cx.wizard.DATEFORMAT.SE:
                p_dateFormat = "yymmdd";                
                return;
            case expediaNS.cx.wizard.DATEFORMAT.EU:
            default :
                p_dateFormat = "ddmmyy";         
        }    
    }
    
    var init = function() {
    }
	
    init();
	
    return obj;
}

expediaNS.cx.wizard.VValidation = function(id, vElements, vType, message){

    var obj = {};    
    var p_vElements = null;
    var p_vType = null;
    var p_vErrMsg = null;
    var p_useUSDatefmt = false;
    var p_dateFormat = null;
    var p_dateRegEx = null;
    var p_id = null;
    var p_message = null;
    var p_dateFmt = null;
    
    var areNotEmpty = function() {
        var res = true;
        for (var i=0; i<p_vElements.length; i++) {
            if (p_vElements[i].isEmpty()){
                res = false;
                p_vElements[i].setHighlight(true);
            }
            else {
                p_vElements[i].setHighlight(false);
            }
        }
        return res;
    }
    
    var areValidLocations = function() {
        var res = true;
        for (var i=0; i<p_vElements.length; i++) {
            if (!isValidLocation(p_vElements[i])) {
                res = false;
                p_vElements[i].setHighlight(true);   
            }
            else {
                p_vElements[i].setHighlight(false);
            }
        }
        return res;
    }
    
    var areValidDates = function() {
        var res = true;
        for (var i=0; i<p_vElements.length; i++) {
            var result = p_vElements[i].isValidDate(p_dateRegEx);
            if (!result){
                res = false;
                p_vElements[i].setHighlight(true);
            }
            else {
                p_vElements[i].setHighlight(false);
            }
        }
        return res;
    }

    var isReturnDateAfterStartDate = function() {
        if (areValidDates()) {
            startDate = expediaNS.cx.util.date.newDate(p_vElements[0].getValue(), p_dateFmt);
            returnDate = expediaNS.cx.util.date.newDate(p_vElements[1].getValue(), p_dateFmt);
            p_vElements[0].setHighlight(true);
            p_vElements[1].setHighlight(true);
            return (returnDate > startDate);
        }
        else {
            return true;
        }
    }
    
   var isReturnDateAfterOrEqualStartDate = function() {
        if (areValidDates()) {
            startDate = expediaNS.cx.util.date.newDate(p_vElements[0].getValue(), p_dateFmt);
            returnDate = expediaNS.cx.util.date.newDate(p_vElements[1].getValue(), p_dateFmt);
            p_vElements[0].setHighlight(true);
            p_vElements[1].setHighlight(true);
            return (returnDate >= startDate);
        }
        else {
            return true;
        }
    }
   
    var areEmailsValid = function() {
	    var emailRegEx = new RegExp("^[\\w\\.=-]+@[\\w\\.-]+\\.[\\w]{2,3}$");
        var res = true;
        for (var i=0; i<p_vElements.length; i++) {
            var emailToTest = p_vElements[i].getValue();
            var result = emailRegEx.test(emailToTest);
            if (!result){
                res = false;
                p_vElements[i].setHighlight(true);
            }
            else {
                p_vElements[i].setHighlight(false);
            }
        }
        return res;
	}
	
	var isMultiFlightPlaceValid = function(typeOfPlaceToTest) {
	    var placeToTest = null;
	    var previousOrigin = null;
	    var previousDestination = null;
	    
	    for (var i=0; i<p_vElements.length; i++) {
	        if (p_vElements[i].getType() == typeOfPlaceToTest) {
	            placeToTest = p_vElements[i];
	        }
	        if (p_vElements[i].getType() == expediaNS.cx.wizard.FIELDTYPE.previousOrigin) {
	            previousOrigin = p_vElements[i];
	        }
	        if (p_vElements[i].getType() == expediaNS.cx.wizard.FIELDTYPE.previousDestination) {
	            previousDestination = p_vElements[i];
	        }
        }
        
        
        if (!previousOrigin.isEmpty() || !previousDestination.isEmpty()) {
            if (!placeToTest.isEmpty()) {
                return isValidLocation(placeToTest);
            }
        }
        return true;
	}	
	var isMultiFlightOriginValid = function() {
	    return isMultiFlightPlaceValid(expediaNS.cx.wizard.FIELDTYPE.origin);
	}
	var isMultiFlightDestinationValid = function() {
	    return isMultiFlightPlaceValid(expediaNS.cx.wizard.FIELDTYPE.destination);
	}
	
	var isMultiFlightPlaceNotEmpty = function(typeOfPlaceToTest) {
	    var placeToTest = null;
	    var oppositeField = null;
	    var typeOppositeField = null;
	    var previousOrigin = null;
	    var previousDestination = null;
	    
	    if (typeOfPlaceToTest == expediaNS.cx.wizard.FIELDTYPE.origin) {
	        typeOppositeField = expediaNS.cx.wizard.FIELDTYPE.destination;
	    }
	    else {
	        typeOppositeField = expediaNS.cx.wizard.FIELDTYPE.origin;
	    }
	    
	    for (var i=0; i<p_vElements.length; i++) {	    
	        if (p_vElements[i].getType() == typeOppositeField) {
	            oppositeField = p_vElements[i];
	        }
	        if (p_vElements[i].getType() == typeOfPlaceToTest) {
	            placeToTest = p_vElements[i];
	        }
	        if (p_vElements[i].getType() == expediaNS.cx.wizard.FIELDTYPE.previousOrigin) {
	            previousOrigin = p_vElements[i];
	        }
	        if (p_vElements[i].getType() == expediaNS.cx.wizard.FIELDTYPE.previousDestination) {
	            previousDestination = p_vElements[i];
	        }
        }
        if (!previousOrigin.isEmpty() || !previousDestination.isEmpty()) {
            if (!oppositeField.isEmpty()) {
                return !placeToTest.isEmpty();
            }
        }
        return true;
	}	
	var isMultiFlightOriginNotEmpty = function() {
	    return isMultiFlightPlaceNotEmpty(expediaNS.cx.wizard.FIELDTYPE.origin);
	}
	var isMultiFlightDestinationNotEmpty = function() {
	    return isMultiFlightPlaceNotEmpty(expediaNS.cx.wizard.FIELDTYPE.destination);
	}
	
	var isMultiFlightDateValid = function() {
	    var date = null;
	    var origin = null;
	    var destination = null;
	    var previousOrigin = null;
	    var previousDestination = null;
	    
	    for (var i=0; i<p_vElements.length; i++) {	    
	        if (p_vElements[i].getType() == expediaNS.cx.wizard.FIELDTYPE.date) {
	            date = p_vElements[i];
	        }
	        if (p_vElements[i].getType() == expediaNS.cx.wizard.FIELDTYPE.origin) {
	            origin = p_vElements[i];
	        }
	        if (p_vElements[i].getType() == expediaNS.cx.wizard.FIELDTYPE.destination) {
	            destination = p_vElements[i];
	        }
	        if (p_vElements[i].getType() == expediaNS.cx.wizard.FIELDTYPE.previousOrigin) {
	            previousOrigin = p_vElements[i];
	        }
	        if (p_vElements[i].getType() == expediaNS.cx.wizard.FIELDTYPE.previousDestination) {
	            previousDestination = p_vElements[i];
	        }
        }
        if (!previousOrigin.isEmpty() || !previousDestination.isEmpty()) {
            if (!origin.isEmpty() || !destination.isEmpty()) {
                return date.isValidDate(p_dateRegEx);
            }
        }
        return true;
	}

    var VDATEREGEXP = {
        USDateField: "^(?:0*[1-9]|1[012])[- /.](?:0*[1-9]|[12][0-9]|3[01])(?:[- /.](?:20)*\\d\\d)*$",
        EUDateField: "^(?:0*[1-9]|[12][0-9]|3[01])[- /.](?:0*[1-9]|1[012])(?:[- /.](?:20)*\\d\\d)*$",
        SEDateField: "^((19|20)*\\d\\d[- /.])*(0*[1-9]|1[012])[- /.](0*[1-9]|[12][0-9]|3[01])$"
    }
    
    var setDateRegEx = function(dateFormat) {
        switch (dateFormat)
	    {
	        case "mmddyy":
                p_dateRegEx = VDATEREGEXP.USDateField;        
                p_dateFmt = expediaNS.cx.util.DateFormat.US;
                return;    
	        case "yymmdd":
               p_dateRegEx = VDATEREGEXP.SEDateField;       
               p_dateFmt = expediaNS.cx.util.DateFormat.SE;
               return;
            case "ddmmyy":
            default :
                p_dateRegEx = VDATEREGEXP.EUDateField;       
                p_dateFmt = expediaNS.cx.util.DateFormat.EU;
        }    
    }
    
    var isValidLocation = function(vElement) {
        var VLOCREGEXP = "[a-zA-Z\-\s\'()!]{3,40}$";
        var locRegEx = new RegExp(VLOCREGEXP);
        return locRegEx.test(vElement.getValue());
    }
    
    obj.doValidation = function(dateFormat){
        setDateRegEx(dateFormat);
        switch (p_vType)
	    {
            case expediaNS.cx.wizard.VALIDATIONTYPE.isOrigNotEmpty :
            case expediaNS.cx.wizard.VALIDATIONTYPE.isDestNotEmpty :
                return areNotEmpty();

            case expediaNS.cx.wizard.VALIDATIONTYPE.isOrigValid :			
            case expediaNS.cx.wizard.VALIDATIONTYPE.isDestValid :
                return areValidLocations();

            case expediaNS.cx.wizard.VALIDATIONTYPE.isStartDateValid :
            case expediaNS.cx.wizard.VALIDATIONTYPE.isEndDateValid :
            case expediaNS.cx.wizard.VALIDATIONTYPE.areDatesValid :
                return areValidDates();

            case expediaNS.cx.wizard.VALIDATIONTYPE.isEndDateAfterStartDate :
                return isReturnDateAfterStartDate();
          
            case expediaNS.cx.wizard.VALIDATIONTYPE.isEndDateAfterOrEqualStartDate :
                return isReturnDateAfterOrEqualStartDate();

            case expediaNS.cx.wizard.VALIDATIONTYPE.isEmailValid:
                return areEmailsValid();
            
            case expediaNS.cx.wizard.VALIDATIONTYPE.isMultiFlightOriginValid:
                return isMultiFlightOriginValid();

            case expediaNS.cx.wizard.VALIDATIONTYPE.isMultiFlightOriginNotEmpty:
                return isMultiFlightOriginNotEmpty();

            case expediaNS.cx.wizard.VALIDATIONTYPE.isMultiFlightDestinationValid :
                return isMultiFlightDestinationValid();

            case expediaNS.cx.wizard.VALIDATIONTYPE.isMultiFlightDestinationNotEmpty :
                return isMultiFlightDestinationNotEmpty();

            case expediaNS.cx.wizard.VALIDATIONTYPE.isMultiFlightDateValid:
                return isMultiFlightDateValid();
                
            default :
                return true;
		}
    }

	obj.getVElements = function () {
	    return p_vElements;
	}
	
	obj.type = function() {
	    return p_vType;
    }
    
    obj.getId = function() {
        return p_id;
    }
    
    obj.getMessage = function() {
        return p_message;
    }
    
    var init = function(id, vElements, vType, message)
    {
        p_id = id;
        p_vElements = vElements;
        p_vType = vType;
        if (message) {
            p_message = message;
        }
    }
    
    init(id, vElements, vType, message);
    
    return obj;
}

expediaNS.cx.wizard.VElement = function(id, lblId, type){
    var obj = {};    
    var p_id = null;
    var p_lblid = null;
    var p_htmlType = null;
    var p_highlight = true;
    var p_type = null;
    var p_vErrCtrl = null;
        
    obj.getValue = function()
    {
        var elt = obj.getElement();
        if (elt) {
            return expediaNS.cx.util.html.value(elt);
        }
        else {
            return null;
        }
    }
    
    obj.isEmpty = function()
    {
        var val = expediaNS.cx.util.html.value(obj.getElement());
        if(val)
            return false;
        else
            return true;
    }
    
    obj.isValidDate = function(dateRegExPtrn) {
        var dateRegEx = new RegExp(dateRegExPtrn);
        return dateRegEx.test(obj.getValue());
    }
    
    obj.getElement = function() {
        return document.getElementById(p_id);
    }
    
    obj.getLblElement = function() {
        return document.getElementById(p_lblid);
    }
    
    obj.getHighlight = function() {
        return p_highlight;
    }

	obj.setHighlight = function(value) {
	    p_highlight = value;
	}
	
	obj.getType = function() {
	    return p_type;
	}

    var init = function(id, lblId, type) {
        p_id = id;
        p_lblid = lblId;
        if (type != undefined) {
            p_type = type;
        }
    }
    
    init(id, lblId, type);
    
    return obj;
};

expediaNS.cx.wizard.VErrorController = function(errMsgContainer){
    var obj = {}; 
    	
	var p_errMsgContainer;
	
	obj.cleanMsg = function() {
	    if (p_errMsgContainer){
		    p_errMsgContainer.innerHTML = '';
	    }
	}
	
	obj.reset = function(valObjs){
	    obj.cleanMsg();
	    if (valObjs) {
	        for(var i=0; i < valObjs.length; i++) {
                obj.cleanErrField(valObjs[i]);
            }
        }
	}
	
	obj.cleanErrField = function(valObj) {
        var velts = valObj.getVElements();
        for (var i = 0 ; i<velts.length; i++) {
            var velt = velts[i];
            var elt = velt.getElement();
            var lblElt = velt.getLblElement();
            resetField(elt, lblElt);
        }
	}
	
	obj.highlightError = function(valObj) {
        var velts = valObj.getVElements();
        for (var i = 0 ; i<velts.length; i++) {
            var velt = velts[i];
            if (velt.getHighlight()) {
                var elt = velt.getElement();
                var lblElt = velt.getLblElement();
                if (elt) {
                    elt.className += " errorField";
                }
                if (lblElt) {
                    lblElt.className += " errorField";
                }
            }
        }
	}
	
	obj.showErrorMessage = function(errMsg) {
	    if (p_errMsgContainer) {
            p_errMsgContainer.innerHTML = p_errMsgContainer.innerHTML + formatErr(errMsg);
        }
	}
	
	var resetField = function(elt, lblElt) {
        if (elt) {
            elt.className = elt.className.replace("errorField", "");
        }
        if (lblElt) {
            lblElt.className = lblElt.className.replace("errorField", "");
        }
	}
	
	var formatErr = function(errMsg) {
		return "<p class='errorMessage normalText'>" + errMsg + "</p>";
	}
	
	var init = function(errMsgContainer) {
        p_errMsgContainer = document.getElementById(errMsgContainer);
	}
	
	init(errMsgContainer);
	
    return obj;
}