﻿$jq.namespace('MatchCore');

MatchCore.AjaxGeo = function() {
    var loadingOpt = { value: '', text: 'Loading...' };
    var countryCodesWithPostal = [1, 2, 224];

    var selectedCountryCode = -1;
    var selectedStateCode = -1;
    var selectedCityCodes = [];

    var _container = null;
    var countryList;
    var stateList;
    var cityList;
    var postalCodeField;

    var config = null;
    var countryFilledDelegate = new MatchCore.Delegate();

    var includeNoAnswer = {
        forCountry: false,
        aliasForCountry: "",
        forState: false,
        aliasForState: "",
        forCity: false,
        aliasForCity: ""
    };

    var countriesJson = null;
    var statesJson = null;

    var country_changed_handlers = [];

    var service = new MatchCore.ServiceProxy(MatchCore.Application.resolveUrl('~/rest/MainService.ashx'));

    var country_changed = function() {
		selectedCountryCode = get_selectedCountryCode();
        selectedStateCode = -1;
        selectedCityCodes = [];

        checkPostalVisibility();

        fillStateList();
    };

    var state_changed = function() {
		selectedStateCode = get_selectedStateCode();
        selectedCityCodes = [];
        fillCityList();
    };
    
    var city_changed = function() {
        selectedCityCodes = get_selectedCityCodes();
    };

    var get_selectedCountryCode = function() {
        var countryCode = $jq('option:selected', countryList).val();

        if (countryCode == null)	//get first value
            countryCode = $jq('option', countryList).val();

        return countryCode;
    };

    var get_selectedStateCode = function() {
        var stateCode = $jq('option:selected', stateList).val();

        if (stateCode == null)	//get first value
            stateCode = $jq('option', stateList).val();

        return stateCode;
    };
    
    var get_selectedCityCodes = function() {
		var temp = [];
		
        $jq('option:selected', cityList).each(function() {
			temp.push($jq(this).val());
        });
        
        return temp;
    };

    var fillCountryList = function() {
        if (countryList)
            service.invoke({
                method: 'GetAllCountries',
                success: handle_fillCountryList
            });
    };

    var checkPostalVisibility = function() {
        if (postalCodeField) {
            var countryCode = get_selectedCountryCode();
            var showPostal = false;

            for (var i = 0; i < countryCodesWithPostal.length; i++) {
                if (countryCode.toString() == countryCodesWithPostal[i].toString()) {
                    showPostal = true;
                    break;
                }
            }

            if (showPostal)
                $jq(postalCodeField).parents('.postalPane').show();
            else
                $jq(postalCodeField).parents('.postalPane').hide();
        }
    };

    var handle_fillCountryList = function(response) {
        $jq(countryList).clearOptions();

        if (response[0].Code) {
            countriesJson = response;

            if (includeNoAnswer.forCountry) {
                $jq(countryList).addOption(
					{ value: -1, text: includeNoAnswer.aliasForCountry, selected: (selectedCountryCode == -1) }
				);
            }

            for (var i = 0; i < response.length; i++) {
                var text = response[i].Name;
                if (config != null && config.CountryAbv)
                    text = response[i].ShortName;
                    
                $jq(countryList).addOption(
					{ value: response[i].Code, text: text, selected: (response[i].Code.toString() == selectedCountryCode.toString()) }
				);
            }

            countryFilledDelegate.fireAndPreserve();

            checkPostalVisibility();

            fillStateList();
        }
        else alert('Error loading countries');
    };

    var fillStateList = function() {
        if (stateList) {
            $jq(stateList).clearOptions();
            $jq(stateList).addOption(loadingOpt);

            $jq(cityList).clearOptions();
            $jq(cityList).addOption(loadingOpt);

            var countryCode = get_selectedCountryCode();

            var currentCountry = findCountry(countryCode);

            if (currentCountry != null) {
                if (currentCountry.HasStates) {
                    $jq(stateList).parents('.statePane').show();

                    service.invoke({
                        method: 'GetStatesByCountryCode',
                        data: {
                            'countryCode': countryCode
                        },
                        success: handle_fillStateList
                    });
                }
                else {
                    $jq(stateList).parents('.statePane').hide();

                    fillCityListNoStates();
                }
            }
            else {
                deactivateStatePane();
                deactivateCityPane();
            }
        }
    };

    var handle_fillStateList = function(response) {
        $jq(stateList).clearOptions();

        if (response[0].Code) {
            statesJson = response;

            if (includeNoAnswer.forState) {
                $jq(stateList).addOption(
					{ value: -1, text: includeNoAnswer.aliasForState, selected: (selectedStateCode == -1) }
				);
            }

            for (var i = 0; i < response.length; i++) {
                var text = response[i].Name;
                if (config != null && config.StateAbv)
                    text = response[i].Abbreviation;
                    
                $jq(stateList).addOption(
					{ value: response[i].Code, text: text, selected: (response[i].Code.toString() == selectedStateCode.toString()) }
				);
            }

            fillCityList();
        }
        else alert('Error loading states');
    };

    var fillCityList = function() {
        if (cityList) {
            $jq(cityList).clearOptions();
            $jq(cityList).addOption(loadingOpt);

            var countryCode = get_selectedCountryCode();
            var currentCountry = findCountry(countryCode);

            var stateCode = get_selectedStateCode();
            var currentState = findState(stateCode);

            if (currentCountry != null && currentState != null) {
                $jq(cityList).parents('.cityPane').show();

                service.invoke({
                    method: 'GetCitiesByStateCodeAndCountryCode',
                    data: {
                        'stateCode': stateCode,
                        'countryCode': countryCode
                    },
                    success: handle_fillCityList
                });
            }
            else {
                deactivateCityPane();
            }
        }
    };

    var fillCityListNoStates = function() {
        if (cityList) {
            var countryCode = $jq('option:selected', countryList).val();

            var countryCode = get_selectedCountryCode();
            var currentCountry = findCountry(countryCode);

            if (currentCountry != null) {
                $jq(cityList).parents('.cityPane').show();

                service.invoke({
                    method: 'GetCitiesByCountryCode',
                    data: {
                        'countryCode': countryCode
                    },
                    success: handle_fillCityList
                });
            }
            else {
                deactivateCityPane();
            }
        }
    };

    var handle_fillCityList = function(response) {
        $jq(cityList).clearOptions();

        if (includeNoAnswer.forCity) {
            $jq(cityList).addOption(
				{ value: -1, text: includeNoAnswer.aliasForCity, selected: (selectedCityCodes.length == 0) }
			);
        }

        for (var i = 0; i < response.length; i++) {
            $jq(cityList).addOption(
				{ value: response[i].Code, text: response[i].Name, selected: (isCityCodeSelected(response[i].Code)) }
			);
        }
    };

    var findCountry = function(code) {
        for (var i = 0; i < countriesJson.length; i++) {
            if (countriesJson[i].Code == code)
                return countriesJson[i];
        }

        return null;
    };

    var findState = function(code) {
        for (var i = 0; i < statesJson.length; i++) {
            if (statesJson[i].Code == code)
                return statesJson[i];
        }

        return null;
    };

    var isCityCodeSelected = function(cityCode) {
        for (var i = 0; i < selectedCityCodes.length; i++) {
            if (selectedCityCodes[i].toString() == cityCode.toString())
                return true;
        }

        return false;
    };

    var deactivateStatePane = function() {
        $jq(stateList).parents('.statePane').hide();
        $jq(stateList).clearOptions();
    };

    var deactivateCityPane = function() {
        $jq(cityList).parents('.cityPane').hide();
        $jq(cityList).clearOptions();
    };

    var self = {
        init: function(opts) {
            config = opts.meta;
            _container = opts.container;

            postalCodeField = $jq(config.postalField);
            countryList = (config.countryList != undefined) ? $jq(config.countryList) : $jq('.countryList', _container).get(0);
            stateList = (config.stateList != undefined) ? $jq(config.stateList) : $jq('.stateList', _container).get(0);
            cityList = (config.cityList != undefined) ? $jq(config.cityList) : $jq('.cityList', _container).get(0);

            if (config.selectedCountryCode)
                selectedCountryCode = config.selectedCountryCode;

            if (config.selectedCityCodes)
                selectedCityCodes = config.selectedCityCodes;

            if (config.selectedStateCode)
                selectedStateCode = config.selectedStateCode;

            if (config.includeNoAnswer)
                includeNoAnswer = config.includeNoAnswer;

            //wireup event handlers
            $jq(countryList).change(country_changed);
            $jq(stateList).change(state_changed);
            $jq(cityList).change(city_changed);
			
            self.render();
        },

        render: function() {
            //render waiting state

            $jq(countryList).addOption(loadingOpt);
            $jq(stateList).addOption(loadingOpt);
            $jq(cityList).addOption(loadingOpt);

            if (countryList)
                fillCountryList();
        },

        get_countryList: function() {
            return countryList;
        },

        CountryFilledEvent: function(handler) {
            countryFilledDelegate.add(handler);
        },
        
        setLocation : function (countryCode, stateCode, cityCodes) {
			if (arguments.length > 0 && countryCode != undefined) {
				selectedCountryCode = countryCode;
			}
			
			if (arguments.length > 1 && stateCode != undefined) {
				selectedStateCode = stateCode;
			}
			
			if (arguments.length > 2 && cityCodes != undefined) {
				selectedCityCodes = cityCodes;
			}
        },
        
        countryCode : function() {
			return (selectedCountryCode > -1) ? selectedCountryCode : null;
        },
        
        stateCode : function() {
			return (selectedStateCode > -1) ? selectedStateCode : null;
        },
        
        cityCodes : function() {
			return selectedCityCodes;
        }
    };

    return self;
};
