var globalTimeout = null;
var KEY = {
    LEFT:37,
    UP: 38,
    RIGHT:39,
    DOWN: 40,
    DEL: 46,
    TAB: 9,
    RETURN: 13,
    ESC: 27,
    COMMA: 188,
    PAGEUP: 33,
    PAGEDOWN: 34,
    BACKSPACE: 8,
    SHIFT:16,
    CTRL:17,
    ALT:18
};
var CONFIG = {
    DELAY : 500,
    MIN_WIDTH: 240,
    CLASSES : {
        AJAX_LOADER:"ajaxLoader",
        DROPDOWN:"dropdownDiv",
        AUTOCOMPLETE:"autocomplete",
        ACTIVE:"active",
        ODD_ITEM:"odd",
        EVEN_ITEM:"even",
        INVALID:"validationError",
        AUTOCOMPLETE_BAR:"autocompleteBar",
        PHONE_CONFIRM:"balloon"
    },
    MESSAGES : {
        VALID:"Address has been validated",
        INVALID:"Address has not been validated",
        NOT_FOUND:"If your details are not found, please enter more details in this or other fields.",
        PHONE_CONFIRM:"Is this your correct phone number?"
    },
    SUGGEST_NAMES_URL : "/faces/ws/suggestnames.jsp",
    SUGGEST_ADDRESSES_URL : "/faces/ws/suggestaddresses.jsp",
    SELECT_ADDRESSES_URL : "/faces/ws/selectaddresses.jsp",
    PRICE_CALC_URL: "/faces/ws/calculateprice.jsp",
    TIMEOUT: 10000
}

function ActiveIndexWrapper(){
    this.value = 0;
}

//Escape character for jQuery selector
function jq(expression) {
    return "#" + expression.replace(/(:|\.)/g,'\\$1');
}

function registerSuggestNamesHandler(inputFieldId,searchType){
    var inputId = jq(inputFieldId);
    var activeIndex = new ActiveIndexWrapper();
    var lastTimestamp;

    function suggestNames(){
        var currentValue = jQuery(inputId).val();
        var autocompleteSelector = jQuery(inputId).siblings("." + CONFIG.CLASSES.DROPDOWN).find("." + CONFIG.CLASSES.AUTOCOMPLETE);
        if ( currentValue.length >= 2) {
            sendAjaxSuggestNamesRequest(escape('{"searchType":"' + searchType + '","name":"' + currentValue + '"}'));
        } else {
            clearValue(autocompleteSelector);
        }
    }

    function sendAjaxSuggestNamesRequest(name){
        var loaderSelector = jQuery(inputId).siblings("." + CONFIG.CLASSES.AJAX_LOADER);
        var requestTime;
        jQuery.ajax({
            url: CONFIG.SUGGEST_NAMES_URL,
            type: 'POST',
            data: 'name=' + name ,
            dataType: 'json',
            timeout: CONFIG.TIMEOUT,
            beforeSend: function(){
                loaderSelector.show();
                requestTime = new Date().getTime();
                lastTimestamp = requestTime;
            },
            success: function(data) {
                if(requestTime >= lastTimestamp && data != undefined){
                    var namesHtml = createNamesList(data);
                    var autocomplete = loaderSelector.siblings("." + CONFIG.CLASSES.DROPDOWN).find("." + CONFIG.CLASSES.AUTOCOMPLETE);
                    createAutocomplete(autocomplete, namesHtml);
                }
            },
            complete: function(){
                loaderSelector.hide();
            }
        });
    }

    function createAutocomplete(autocomplete,listHtml){
        autocomplete.empty();
        autocomplete.html(listHtml);
        autocomplete.find("li:odd").addClass(CONFIG.CLASSES.ODD_ITEM);
        autocomplete.find("li:even").addClass(CONFIG.CLASSES.EVEN_ITEM);
        var listItemsSelector = autocomplete.find("li");
        listItemsSelector.hover(function(){
            jQuery(this).addClass(CONFIG.CLASSES.ACTIVE);
            activeIndex.value = listItemsSelector.index(this);
            listItemsSelector.not(this).removeClass(CONFIG.CLASSES.ACTIVE);
            jQuery(this).attr('title',jQuery(this).text());
        },function(){/*Do nothing*/})
        .mousedown(function() {
            suggestNamesCallback();
            clearValue(autocomplete);
        });
        activeIndex.value = 0;
        listItemsSelector.slice(activeIndex.value, activeIndex.value + 1).addClass(CONFIG.CLASSES.ACTIVE);
        var autocompleteList = autocomplete.find("ul");
        autocompleteList.css({
            width: jQuery(inputId).innerWidth() < CONFIG.MIN_WIDTH?CONFIG.MIN_WIDTH:jQuery(inputId).innerWidth()
        }).hover(function() {
            autocomplete.attr('suggesting','true');
            jQuery(inputId).focus();
        },function() {
            autocomplete.removeAttr('suggesting');
            jQuery(inputId).focus();
        });
        if(autocompleteList.scroll) {
            autocompleteList.scrollTop(0);
        }
        autocomplete.show();
    }

    function suggestNamesCallback(){
        var autocompleteSelector = jQuery(inputId).siblings("." + CONFIG.CLASSES.DROPDOWN).find("ul");
        jQuery(inputId).val(autocompleteSelector.find("li:eq(" + activeIndex.value + ")").text());
    }
    registerEventHandlers(inputId,suggestNames,suggestNamesCallback,activeIndex);
}

function registerSuggestAddressesHandler(inputFieldId,searchType,lastName,fieldIdOptions){
    var inputId = jq(inputFieldId);
    var addressId = jq(fieldIdOptions.address);
    var addressOptionalId = jq(fieldIdOptions.addressOptional);
    var postcodeId = jq(fieldIdOptions.postcode);
    var suburbId = jq(fieldIdOptions.suburb);
    var stateId = jq(fieldIdOptions.state);
    var mobileId = jq(fieldIdOptions.mobile);
    var phoneCodeId = jq(fieldIdOptions.phoneAreaCode);
    var phoneNoId = jq(fieldIdOptions.phoneNo);
    var dpidId = jq(fieldIdOptions.dpid);
    var resultId = jq(fieldIdOptions.result);
    var activeIndex = new ActiveIndexWrapper();
    var jsonData;
    var lastTimestamp;

    jQuery(inputId).focus(function(){
        var listSelector = jQuery(inputId).siblings("." + CONFIG.CLASSES.DROPDOWN).find("ul");
        if(!isVisible(listSelector) && jQuery.trim(jQuery(this).val()).length == 0){
            sendAjaxSuggestAddressesRequest(createJSONAddressSearch(getName(lastName)));
        }
    });

    function suggestAddresses(){
        var currentValue = jQuery(inputId).val();
        var autocompleteSelector = jQuery(inputId).siblings("." + CONFIG.CLASSES.DROPDOWN).find("." + CONFIG.CLASSES.AUTOCOMPLETE);
        if ( currentValue.length >= 2) {
            sendAjaxSuggestAddressesRequest(createJSONAddressSearch(getName(lastName)));
        } else {
            clearValue(autocompleteSelector);
        }
    }

    function sendAjaxSuggestAddressesRequest(search){
        var loaderSelector = jQuery(inputId).siblings("." + CONFIG.CLASSES.AJAX_LOADER);
        var requestTime;
        jQuery.ajax({
            url: CONFIG.SUGGEST_ADDRESSES_URL,
            type: 'POST',
            data: 'search=' + search,
            dataType: 'json',
            timeout: CONFIG.TIMEOUT,
            beforeSend: function(){
                loaderSelector.show();
                requestTime = new Date().getTime();
                lastTimestamp = requestTime;
                showInvalidMessage(resultId,dpidId);
            },
            success: function(data) {
                if(requestTime >= lastTimestamp && data != undefined){
                    var suggestedAddressesHtml = createAddressesList(data);
                    var autocomplete = loaderSelector.siblings("." + CONFIG.CLASSES.DROPDOWN).find("." + CONFIG.CLASSES.AUTOCOMPLETE);
                    createAutocomplete(autocomplete, suggestedAddressesHtml, suggestAddressesCallback);
                    jsonData = data;
                }
            },
            complete: function(){
                loaderSelector.hide();
            }
        });
    }

    function sendAjaxSelectAddressesRequest(addressSuggestion){
        var loaderSelector = jQuery(inputId).siblings("." + CONFIG.CLASSES.AJAX_LOADER);
        var strJSON = escape(JSON.stringify(addressSuggestion));
        jQuery.ajax({
            url: CONFIG.SELECT_ADDRESSES_URL,
            type: 'POST',
            data: 'suggestion=' + strJSON,
            dataType: 'json',
            timeout: CONFIG.TIMEOUT,
            beforeSend: function(){
                loaderSelector.show();
                showInvalidMessage(resultId,dpidId);
            },
            success: function(data) {
                if(data != undefined){
                    var completedAddressesHtml = createCompletedAddressesList(data);
                    var autocomplete = loaderSelector.siblings("." + CONFIG.CLASSES.DROPDOWN).find("." + CONFIG.CLASSES.AUTOCOMPLETE);
                    bindData(data.formattedAddress,data.streetNumber,data.streetName,data.streetType,data.postcode, data.suburb, data.state, data.phoneNumber,data.subPremise,data.buildingName,data.dpid);
                    createAutocomplete(autocomplete, completedAddressesHtml, selectAddressesCallback);
                    if(autocomplete.find("li").size() > 0){
                        //Reset active index;
                        activeIndex.value = 0;
                        jsonData = data;
                    }else{
                        showValidMessage(resultId);
                    }
                }
            },
            complete: function(){
                loaderSelector.hide();
            }
        });
    }

    function createAutocomplete(autocomplete,listHtml,callback){
        autocomplete.empty();
        autocomplete.html(listHtml);
        autocomplete.find("li:odd").addClass(CONFIG.CLASSES.ODD_ITEM);
        autocomplete.find("li:even").addClass(CONFIG.CLASSES.EVEN_ITEM);
        var listItemsSelector = autocomplete.find("li");
        listItemsSelector.hover(function(){
            jQuery(this).addClass(CONFIG.CLASSES.ACTIVE);
            activeIndex.value = listItemsSelector.index(this);
            listItemsSelector.not(this).removeClass(CONFIG.CLASSES.ACTIVE);
            jQuery(this).attr('title',jQuery(this).text());
        },function(){/*Do nothing*/})
        .mousedown(function() {
            callback.call(callback);
            clearValue(autocomplete);
        });
        activeIndex.value = 0;
        listItemsSelector.slice(activeIndex.value, activeIndex.value + 1).addClass(CONFIG.CLASSES.ACTIVE);
        var autocompleteList = autocomplete.find("ul");
        var autocompleteWidth = jQuery(inputId).innerWidth() < CONFIG.MIN_WIDTH?CONFIG.MIN_WIDTH:jQuery(inputId).innerWidth();
        autocompleteList.css({
            width: autocompleteWidth
        }).hover(function() {
            autocomplete.attr('suggesting','true');
            jQuery(inputId).focus();
        },function() {
            autocomplete.removeAttr('suggesting');
            jQuery(inputId).focus();
        });
        if(autocompleteList.scroll) {
            autocompleteList.scrollTop(0);
        }
        if(jQuery(dpidId).val().length <= 0){
            autocomplete.append('<div><a></a></div>');
            autocomplete.find('div').addClass(CONFIG.CLASSES.AUTOCOMPLETE_BAR).css({
                width: autocompleteWidth
            }).prepend('<span>' + CONFIG.MESSAGES.NOT_FOUND + '</span>');
            autocomplete.find("a").attr("href","javascript:void(0)").click(function(){
                clearValue(autocomplete);
            }).text('Close');
        }
        autocomplete.show();
    }

    function addressesCallback(){
        if(typeof(jsonData.resultList)!== "undefined" && typeof(jsonData.resultList[activeIndex.value])){
            suggestAddressesCallback();
        }else if(typeof(jsonData.detailList) !== "undefined" && typeof(jsonData.detailList[activeIndex.value])){
            selectAddressesCallback();
        }
    }

    function suggestAddressesCallback(){
        if(jsonData.resultList[activeIndex.value]){
            sendAjaxSelectAddressesRequest(jsonData.resultList[activeIndex.value]) ;
        }
    }

    function selectAddressesCallback(){
        if(jsonData.detailList[activeIndex.value]){
            var data = jsonData.detailList[activeIndex.value];
            bindData(data.formattedAddress,data.streetNumber,data.streetName,data.streetType,data.postcode, data.suburb, data.state, data.phoneNumber,data.subPremise,data.buildingName,data.dpid);
            showValidMessage(resultId);
        }
    }

    function createJSONAddressSearch(name){
        var jsonSearchStr = "{";
        jsonSearchStr += '"formattedAddress":"' + jQuery(addressId).val() + '"';
        jsonSearchStr += ',"formattedAddressIncludesPostcode":false';
        jsonSearchStr += ',"formattedAddressIncludesState":true';
        jsonSearchStr += ',"formattedAddressIncludesSuburb":true';
        jsonSearchStr += ',"name":"' + name + '"';
        jsonSearchStr += ',"postcode":"' + jQuery(postcodeId).val() + '"';
        jsonSearchStr += ',"searchType":"' + searchType + '"';
        jsonSearchStr += ',"state":"' + jQuery(stateId).val() + '"';
        jsonSearchStr += ',"suburb":"' + jQuery(suburbId).val() + '"';
        jsonSearchStr += "}";
        return escape(jsonSearchStr);
    }

    function bindData(formattedAddress,streetNumber,streetName,streetType,postcode,suburb,state,phone,subPremise,buildingName,dpid){
        var formattedAddressVal = getValue(formattedAddress);
        var streetNumberVal = getValue(streetNumber);
        var streetNameVal = getValue(streetName);
        var streetTypeVal = getValue(streetType);
        var subPremiseVal = getValue(subPremise);
        var buildingNameVal = getValue(buildingName);
        var postcodeVal = getValue(postcode);
        var suburbVal = getValue(suburb);
        var phoneVal = getValue(phone);
        var stateVal = getValue(state);
        var phoneCodeVal = phoneVal.replace(/-/g,'').substring(phoneVal.indexOf("(") + 1, phoneVal.indexOf(")")).replace(' ','');
        var phoneNoVal = phoneVal.replace(/-/g,'').substring(phoneVal.lastIndexOf(")") + 1).replace(' ','');
        var dpidVal = getValue(dpid);
        formattedAddressVal = formattedAddressVal.substring(0,formattedAddressVal.lastIndexOf((",")));
        jQuery(addressId).val(jQuery.trim(formattedAddressVal.substring(0,formattedAddress.indexOf(","))));
        jQuery(addressOptionalId).val(jQuery.trim(formattedAddressVal.substring(formattedAddress.indexOf(",") + 1)));
        jQuery(postcodeId).val(postcodeVal);
        jQuery(suburbId).val(suburbVal);
        jQuery(stateId).val(stateVal);
        if(phoneNoVal.length > 0){
            jQuery(phoneCodeId).val(phoneCodeVal);
            //This variable is for creating popup confirmation message for the correct phone number
            var boundPhoneId;
            if(phoneCodeVal.length == 0){
                jQuery(mobileId).val(phoneNoVal);
                jQuery(phoneNoId).val('').siblings("." + CONFIG.CLASSES.PHONE_CONFIRM).remove();
                boundPhoneId = mobileId;
                //Switch to the mobile tab
                if(fieldIdOptions.mobileTab){
                    jQuery(jq(fieldIdOptions.mobileTab)).click();
                }
            }else{
                jQuery(phoneNoId).val(phoneNoVal);
                boundPhoneId = phoneNoId;
                //Switch to the corresponding phone tab
                if(fieldIdOptions.phoneTab){
                    jQuery(jq(fieldIdOptions.phoneTab)).click();
                }
            }
            var boundPhone = jQuery(boundPhoneId);
            boundPhone.siblings("." + CONFIG.CLASSES.PHONE_CONFIRM).remove();
            var parent = boundPhone.parent().prepend(createPhoneConfirmBalloon());
            var balloon = jQuery("." + CONFIG.CLASSES.PHONE_CONFIRM,parent);
            balloon.attr('for',boundPhoneId);
            boundPhone.bind("focus", function(){
                if(isVisible(balloon)){
                    balloon.remove();
                }
                jQuery(this).unbind("focus");
            });
            balloon.find("a[name=yes]").click(function(){
                balloon.remove();
                boundPhone.unbind("focus");
            });
            balloon.find("a[name=no]").click(function(){
                if(phoneCodeVal.length > 0){
                    jQuery(phoneCodeId).val('');
                }
                jQuery(boundPhoneId).val('').focus();
                balloon.remove();
                boundPhone.unbind("focus");
            });
        }
        jQuery(dpidId).val(dpidVal);
    }

    function getName(nameParam){
        var nameSel = jQuery(jq(nameParam));
        if(nameSel.length > 0){
            return nameSel.val();
        }else{
            return nameParam;
        }
    }

    function createPhoneConfirmBalloon(){
        var out =  '<div class="' + CONFIG.CLASSES.PHONE_CONFIRM + '"><div>' + CONFIG.MESSAGES.PHONE_CONFIRM + '<br/><br/>';
        out += '<a href="javascript:void(0)" name="yes">Yes</a> | ';
        out += '<a href="javascript:void(0)" name="no">No</a></div>';
        out += '<img src="/images/arrowdown.gif"></img></div>';
        return out;
    }

    registerEventHandlers(inputId,suggestAddresses,addressesCallback,activeIndex);
}

function registerEventHandlers(inputId,action,callback,activeIndex){
    jQuery(document).ready(function(){
        jQuery(inputId).attr("autocomplete","off");
        jQuery(inputId).bind((jQuery.browser.opera ? "keypress" : "keydown"), function(event){
            var autocompleteSelector = jQuery(inputId).siblings("." + CONFIG.CLASSES.DROPDOWN).find("." + CONFIG.CLASSES.AUTOCOMPLETE);
            var listSelector = jQuery(inputId).siblings("." + CONFIG.CLASSES.DROPDOWN).find("ul");
            var listItemsSelector = listSelector.find("li");
            switch(event.keyCode){
                case KEY.LEFT:
                case KEY.RIGHT:
                case KEY.SHIFT:
                case KEY.CTRL:
                case KEY.ALT:
                    break;
                case KEY.UP:
                    event.preventDefault();
                    if (isVisible(listSelector)) {
                        previousItem();
                    }
                    break;
                case KEY.DOWN:
                    event.preventDefault();
                    if (isVisible(listSelector)) {
                        nextItem();
                    }
                    break;
                case KEY.PAGEUP:
                    event.preventDefault();
                    if (isVisible(listSelector)) {
                        pageUp();
                    }
                    break;
                case KEY.PAGEDOWN:
                    event.preventDefault();
                    if (isVisible(listSelector)) {
                        pageDown();
                    }
                    break;
                case KEY.TAB:
                case KEY.RETURN:
                    clearTimeout(globalTimeout);
                    // stop default to prevent a form submit
                    if(isVisible(listSelector)){
                        event.preventDefault();
                        selectCurrentItem();
                        return false;
                    }
                    break;
                case KEY.ESC:
                    clearValue(autocompleteSelector);
                    break;
                default:
                    clearTimeout(globalTimeout);
                    globalTimeout = setTimeout(action,CONFIG.DELAY);
                    break;
            }

            function nextItem() {
                moveSelect(1);
            }

            function previousItem() {
                moveSelect(-1);
            }

            function pageUp() {
                if (activeIndex.value != 0 && activeIndex.value - 6 < 0) {
                    moveSelect( -activeIndex.value );
                } else {
                    moveSelect(-6);
                }
            }

            function pageDown() {
                if (activeIndex.value != listItemsSelector.size() - 1 && activeIndex.value + 6 > listItemsSelector.size()) {
                    moveSelect( listItemsSelector.size() - 1 - activeIndex.value );
                } else {
                    moveSelect(6);
                }
            }

            function moveSelect(step){
                if(typeof(listSelector)!== "undefined" && typeof(listItemsSelector) !== "undefined" && listItemsSelector.size() > 0){
                    listItemsSelector.slice(activeIndex.value, activeIndex.value + 1).removeClass(CONFIG.CLASSES.ACTIVE);
                    movePosition(step);
                    var activeItem = listItemsSelector.slice(activeIndex.value, activeIndex.value + 1).addClass(CONFIG.CLASSES.ACTIVE);
                    if(listSelector.scroll) {
                        var offset = 0;
                        listItemsSelector.slice(0, activeIndex.value).each(function() {
                            offset += this.offsetHeight;
                        });
                        if((offset + activeItem[0].offsetHeight - listSelector.scrollTop()) > listSelector[0].clientHeight) {
                            listSelector.scrollTop(offset + activeItem[0].offsetHeight - listSelector.innerHeight());
                        } else if(offset < listSelector.scrollTop()) {
                            listSelector.scrollTop(offset);
                        }
                    }
                }
            }

            function movePosition(step) {
                activeIndex.value += step;
                if (activeIndex.value < 0) {
                    activeIndex.value = listItemsSelector.size() - 1;
                } else if (activeIndex.value >= listItemsSelector.size()) {
                    activeIndex.value = 0;
                }
            }

            function selectCurrentItem() {
                if(activeIndex.value >= 0){
                    callback.call(callback);
                }
                clearValue(autocompleteSelector);
            }
        })
        .blur(function() {
            var autocomplete = jQuery(inputId).siblings("." + CONFIG.CLASSES.DROPDOWN).find("." + CONFIG.CLASSES.AUTOCOMPLETE);
            if(!autocomplete.attr('suggesting')){
                clearTimeout(globalTimeout);
                clearValue(autocomplete);
            }
        });
    });
}
function createNamesList(data){
    var htmlOut;
    if(data.length > 0){
        htmlOut = "<ul>";
        for(var i = 0; i < data.length; i++){
            htmlOut += "<li>" + data[i] + "</li>";
        }
        htmlOut += "</ul>";
    }
    return htmlOut;
}

function createAddressesList(data){
    var htmlOut;
    if(data.resultList && data.resultList.length > 0){
        htmlOut = "<ul>";
        for(var i = 0; i < data.resultList.length; i++){
            htmlOut += "<li>" + data.resultList[i].formattedAddress + "</li>";
        }
        htmlOut += "</ul>";
    }
    return htmlOut;
}

function createCompletedAddressesList(data){
    var htmlOut;
    if(data.detailList && data.detailList.length > 0){
        htmlOut = "<ul>";
        for(var i = 0; i < data.detailList.length; i++){
            htmlOut += "<li>" + data.detailList[i].formattedAddress + "</li>";
        }
        htmlOut += "</ul>";
    }
    return htmlOut;
}

function isVisible(obj){
    return typeof(obj) !== "undefined" && obj.is(":visible");
}

function clearValue(sel){
    sel.empty();
    sel.hide();
}

function getValue(obj){
    if(typeof(obj) !== "undefined"){
        return obj;
    }else{
        return "";
    }
}

function showValidMessage(resultId){
    jQuery(resultId).removeClass(CONFIG.CLASSES.INVALID);
    jQuery(resultId).html('<img src="/images/address_valid.gif" alt="Valid address"></img> ' + CONFIG.MESSAGES.VALID);
    jQuery(resultId).fadeIn();
}

function showInvalidMessage(resultId,dpidId){
    jQuery(resultId).addClass(CONFIG.CLASSES.INVALID);
    jQuery(resultId).html(CONFIG.MESSAGES.INVALID);
    if(jQuery(dpidId).val().length > 0){
        jQuery(resultId).show();
    }
    //Reset DPID value
    jQuery(dpidId).val('');
}

function isValidAddress(resultDivId){
    return !jQuery(jq(resultDivId)).hasClass(CONFIG.CLASSES.INVALID);
}

function calculatePriceKeyPress(postcode,keyCode,which,firstModel,secondModel,thirdModel)
{
    if(which == null) //IE Behaviour
    {
        if(keyCode == 13)
        {
            calculatePrice(postcode, firstModel, secondModel, thirdModel);
        }
    }
    else if(which > 0) //Firefox behaviour
    {
        if(which == 13)
        {     
            calculatePrice(postcode, firstModel, secondModel, thirdModel);
        }
    }
}

/* Drive Away Price calculation handler */
function calculatePrice(postcode,firstModel,secondModel,thirdModel){
    var firstModelId = jq(firstModel);
    var secondModelId = jq(secondModel);
    var thirdModelId = jq(thirdModel);
    /* State name dictionary */
    var stateName = {
        "ACT":"Australian Capital Territory",
        "NSW":"New South Wales",
        "NT":"Northern Territory",
        "QLD":"Queensland",
        "SA":"South Australia",
        "TAS":"Tasmania",
        "WA":"Western Australia",
        "VIC":"Victoria"
    }
    clearTimeout(globalTimeout);
    globalTimeout = setTimeout(sendAjaxCalcRequest,350);

    function sendAjaxCalcRequest(){
       // Get the postcode value
       var postcodeVal = getPostcode(postcode);
       if(postcodeVal.length < 4 || !validateNumber(postcodeVal)){
            jQuery(".message").show();
        }
        else{
            jQuery.ajax({
                url: CONFIG.PRICE_CALC_URL,
                type: 'POST',
                data: 'postcode=' + postcodeVal
                + '&first=' + jQuery(firstModelId).val()
                + '&second=' + jQuery(secondModelId).val()
                + '&third=' + jQuery(thirdModelId).val(),
                dataType: 'json',
                timeout: CONFIG.TIMEOUT,
                beforeSend: function(){
                    jQuery("#postcode_input").hide();
                    jQuery(".message").hide();
                    jQuery(".no_result").hide();
                    jQuery("#price_table").hide();
                    jQuery("#h2_drive_away_price").hide();
                    jQuery("#change_pcode").hide();
                    // Reset disclaimer's text visibility
                    jQuery("#disclaimer").find("p.state").removeAttr("style");
                    jQuery("#disclaimer").hide();
                    jQuery(".loader").show();
                },
                success: function(data) {
                    if(data != undefined && data[0] != null){
                        displayCalculationRs(postcodeVal,data);
                    }else {
                        jQuery(".no_result").html('Error processing request at the moment. Please try again later');
                        jQuery(".no_result").show();
                    }
                },
                error: function(){
                    jQuery(".no_result").html('Error processing request at the moment. Please try again later');
                    jQuery(".no_result").show();
                },
                complete: function(){
                    jQuery(".loader").hide();
                    jQuery("#change_pcode").show();
                    jQuery("#jModelComparisonFragment_div_Pricing").html(jQuery("#pricing").parent().html());
                }
            });
        }
    }

    function displayCalculationRs(postcodeVal,data)
    {
        var state = "";
        var priceTable = jQuery('#price_table');
        var disclaimer = jQuery('#disclaimer');
        var cellIndex = 0;
        for(var i = 0; i < data.length;i++){
            cellIndex = (i + 1);
            state = data[i].state;
            if (data[i].MLP) {
                priceTable.find("tr:eq(0) td:eq(" + cellIndex + ")").html(data[i].MLP).formatCurrency();
            } else {
                if (data[i].tba) {
                    priceTable.find("tr:eq(0) td:eq(" + cellIndex + ")").html('TBA');
                } else {
                    priceTable.find("tr:eq(0) td:eq(" + cellIndex + ")").html('-');
                }
            }
            if (data[i].dealerDeliveryFee) {
                priceTable.find("tr:eq(1) td:eq(" + cellIndex + ")").html(data[i].dealerDeliveryFee).formatCurrency();
            } else {
                if (data[i].tba) {
                    priceTable.find("tr:eq(1) td:eq(" + cellIndex + ")").html('TBA');
                } else {
                    priceTable.find("tr:eq(1) td:eq(" + cellIndex + ")").html('-');
                }
            }
            if(data[i].LCT){
                if(data[i].LCT > 0){
                    priceTable.find("tr:eq(2) td:eq(" + cellIndex + ")").html(data[i].LCT).formatCurrency();
                }
                else{
                    priceTable.find("tr:eq(2) td:eq(" + cellIndex + ")").html('-');
                }
            } else {
                if (data[i].tba) {
                    priceTable.find("tr:eq(2) td:eq(" + cellIndex + ")").html('TBA');
                } else {
                    priceTable.find("tr:eq(2) td:eq(" + cellIndex + ")").html('-');
                }
            }
            if(state == 'NSW' || state == 'QLD'){
                priceTable.find("tr:eq(3) td:eq(0)").html(state + ' Registration Costs');
                if (data[i].registrationAmount) {
                    priceTable.find("tr:eq(3) td:eq(" + cellIndex + ")").html(data[i].registrationAmount).formatCurrency();
                } else {
                    if (data[i].tba) {
                        priceTable.find("tr:eq(3) td:eq(" + cellIndex + ")").html('TBA');
                    } else {
                        priceTable.find("tr:eq(3) td:eq(" + cellIndex + ")").html('-');
                    }
                }
                priceTable.find("tr:eq(4) td:eq(0)").html(state + ' CTP');
                if (data[i].CTPAmount) {
                    priceTable.find("tr:eq(4) td:eq(" + cellIndex + ")").html(data[i].CTPAmount).formatCurrency();
                } else {
                    if (data[i].tba) {
                        priceTable.find("tr:eq(4) td:eq(" + cellIndex + ")").html('TBA');
                    } else {
                        priceTable.find("tr:eq(4) td:eq(" + cellIndex + ")").html('-');
                    }
                }
                priceTable.find("tr:eq(4)").show();
            } else {
                priceTable.find("tr:eq(3) td:eq(0)").html(state + ' Registration Costs');
                if (data[i].totalRegistration) {
                    priceTable.find("tr:eq(3) td:eq(" + cellIndex + ")").html(data[i].totalRegistration).formatCurrency();
                } else {
                    if (data[i].tba) {
                        priceTable.find("tr:eq(3) td:eq(" + cellIndex + ")").html('TBA');
                    } else {
                        priceTable.find("tr:eq(3) td:eq(" + cellIndex + ")").html('-');
                    }
                }
                priceTable.find("tr:eq(4) td:eq(" + cellIndex + ")").html('');
                priceTable.find("tr:eq(4)").hide();
            }
            priceTable.find("tr:eq(5) td:eq(0)").html(state + ' Stamp Duty');
            if (data[i].stampDuty) {
                priceTable.find("tr:eq(5) td:eq(" + cellIndex + ")").html(data[i].stampDuty).formatCurrency();
            } else {
                if (data[i].tba) {
                    priceTable.find("tr:eq(5) td:eq(" + cellIndex + ")").html('TBA');
                } else {
                    priceTable.find("tr:eq(5) td:eq(" + cellIndex + ")").html('-');
                }
            }
            if (data[i].vehicleDriveAwayPrice) {
                priceTable.find("tr:eq(6) td:eq(" + cellIndex + ")").html(data[i].vehicleDriveAwayPrice).formatCurrency();
            } else {
                if (data[i].tba) {
                    priceTable.find("tr:eq(6) td:eq(" + cellIndex + ")").html('TBA');
                } else {
                    priceTable.find("tr:eq(6) td:eq(" + cellIndex + ")").html('-');
                }
            }
        }
        if(priceTable.find("tr:eq(6) td:eq(1)").html() == ''){
            jQuery(".no_result").show();
            priceTable.hide();
            jQuery("#h2_drive_away_price").hide();
            disclaimer.hide();
        }
        else{
            jQuery(".no_result").hide();
            priceTable.show();
            jQuery("#h2_drive_away_price").show();
            //disclaimer.find("p." + state).show();
            disclaimer.show();
            //Write current postcode to cookie for later price retrieval
            createCookie("pricing_pcode",postcodeVal);
        }
        jQuery("#change_pcode > span.pricing_postcode").text(' ' + postcodeVal + " (" + stateName[state] + ")");
        jQuery("#calculation_result").show();
        jQuery.scrollTo(priceTable,600);
    }

    function getPostcode(postcodeParam){
        var postcodeSel = jQuery(jq(postcodeParam));
        if(postcodeSel.length > 0){
            return postcodeSel.val();
        }else{
            return postcodeParam;
        }
    }
}

function toggleInput(elementId){
    var elementSel = jQuery(jq(elementId));
    if(isVisible(elementSel)){
        elementSel.hide();
    }else{
        elementSel.show();
    }
}
