/**
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
* 
* © Copyright 2005 Richard Heyes
*/

    /**
    * Global vars
    */
    __AutoComplete = new Array();

    // Basic UA detection
    isIE = document.all ? true : false;
    isGecko = navigator.userAgent.toLowerCase().indexOf('gecko') != -1;
    isOpera = navigator.userAgent.toLowerCase().indexOf('opera') != -1;


    /**
    * Attachs the autocomplete object to a form element. Sets
    * onkeypress event on the form element.
    * 
    * @param string formElement Name of form element to attach to
    * @param array  data        Array of strings of which to use as the autocomplete data
    */
    function AutoComplete_Create (id, data)
    {
        __AutoComplete[id] = {'data':data,
                              'isVisible':false,
                              'element':document.getElementById(id),
                              'dropdown':null,
                              'highlighted':null};

        __AutoComplete[id]['element'].setAttribute('autocomplete', 'off');
        __AutoComplete[id]['element'].onkeydown  = function(e) {return AutoComplete_KeyDown(this.getAttribute('id'), e);}
        __AutoComplete[id]['element'].onkeyup    = function(e) {return AutoComplete_KeyUp(this.getAttribute('id'), e);}
        __AutoComplete[id]['element'].onkeypress = function(e) {if (!e) e = window.event; if (e.keyCode == 13 || isOpera) return false;}
        __AutoComplete[id]['element'].ondblclick = function() {AutoComplete_ShowDropdown(this.getAttribute('id'));}
        __AutoComplete[id]['element'].onclick    = function(e) {if (!e) e = window.event; e.cancelBubble = true; e.returnValue = false;}

        // Hides the dropdowns when document clicked
        var docClick = function()
        {
           for (id in __AutoComplete) {
               AutoComplete_HideDropdown(id);
           }
        }

        if (document.addEventListener) {
            document.addEventListener('click', docClick, false);
        } else if (document.attachEvent) {
            document.attachEvent('onclick', docClick, false);
        }


        // Max number of items shown at once
        if (arguments[2] != null) {
            __AutoComplete[id]['maxitems'] = arguments[2];
            __AutoComplete[id]['firstItemShowing'] = 0;
            __AutoComplete[id]['lastItemShowing']  = arguments[2] - 1;
        }
        
        AutoComplete_CreateDropdown(id);
        
        // Prevent select dropdowns showing thru
        if (isIE) {
            __AutoComplete[id]['iframe'] = document.createElement('iframe');
            __AutoComplete[id]['iframe'].id = id +'_iframe';
            __AutoComplete[id]['iframe'].style.position = 'absolute';
            __AutoComplete[id]['iframe'].style.top = '0';
            __AutoComplete[id]['iframe'].style.left = '0';
            __AutoComplete[id]['iframe'].style.width = '0px';
            __AutoComplete[id]['iframe'].style.height = '0px';
            __AutoComplete[id]['iframe'].style.zIndex = '98';
            __AutoComplete[id]['iframe'].style.visibility = 'hidden';
            
            __AutoComplete[id]['element'].parentNode.insertBefore(__AutoComplete[id]['iframe'], __AutoComplete[id]['element']);
        }
    }


    /**
    * Creates the dropdown layer
    * 
    * @param string id The form elements id. Used to identify the correct dropdown.
    */
    function AutoComplete_CreateDropdown(id)
    {
        var left  = AutoComplete_GetLeft(__AutoComplete[id]['element']);
        var top   = AutoComplete_GetTop(__AutoComplete[id]['element']) + __AutoComplete[id]['element'].offsetHeight;
        var width = __AutoComplete[id]['element'].offsetWidth;
    
        __AutoComplete[id]['dropdown'] = document.createElement('div');
        __AutoComplete[id]['dropdown'].className = 'autocomplete'; // Don't use setAttribute()
    
        __AutoComplete[id]['element'].parentNode.insertBefore(__AutoComplete[id]['dropdown'], __AutoComplete[id]['element']);
        
        // Position it
        __AutoComplete[id]['dropdown'].style.left       = left + 'px';
        __AutoComplete[id]['dropdown'].style.top        = top + 'px';
        __AutoComplete[id]['dropdown'].style.width      = width + 'px';
        __AutoComplete[id]['dropdown'].style.zIndex     = '99';
        __AutoComplete[id]['dropdown'].style.visibility = 'hidden';
    }
       
    /**
    * Shows the dropdown layer
    * 
    * @param string id The form elements id. Used to identify the correct dropdown.
    */
    function AutoComplete_ShowDropdown(id)
    {
        AutoComplete_HideAll();

		// check to make sure __AutoComplete is not null
		if (isNull(__AutoComplete[id]))
		{
			return;
		}

        var value = __AutoComplete[id]['element'].value;
		var toDisplay = new Array();
        var newDiv    = null;
        var text      = null;
        var numItems  = __AutoComplete[id]['dropdown'].childNodes.length;

        // Remove all child nodes from dropdown
        while (__AutoComplete[id]['dropdown'].childNodes.length > 0) {
            __AutoComplete[id]['dropdown'].removeChild(__AutoComplete[id]['dropdown'].childNodes[0]);
        }

/*
        // Go thru data searching for matches
        for (i=0; i<__AutoComplete[id]['data'].length; ++i) {
            if (__AutoComplete[id]['data'][i].substr(0, value.length) == value) {

				toDisplay[toDisplay.length] = __AutoComplete[id]['data'][i];
            }
        }
*/
        // Go thru data searching for matches
        for (i=0; i<__AutoComplete[id]['data'].length; ++i) 
		{
			if (value == "")
			{
				if (__AutoComplete[id]['data'][i].substr(0, value.length) == value) 
				{
					toDisplay[toDisplay.length] = __AutoComplete[id]['data'][i];
				}
			}
			else
			{
				if (__AutoComplete[id]['data'][i].substr(0, value.length).search(eval("/" + value + "/i")) != -1) 
				{
					toDisplay[toDisplay.length] = __AutoComplete[id]['data'][i];
				}
			}
        }

        // No matches?
        if (toDisplay.length == 0) {
            AutoComplete_HideDropdown(id);
            return;
        }

//alert('hi1'); 
        // Add data to the dropdown layer
        for (i=0; i<toDisplay.length; ++i) {
            newDiv = document.createElement('div');
            newDiv.className = 'autocomplete_item'; // Don't use setAttribute()
            newDiv.setAttribute('id', 'autocomplete_item_' + i);
            newDiv.setAttribute('index', i);
            newDiv.style.zIndex = '99';
            
             // Scrollbars are on display ?
            if (toDisplay.length > __AutoComplete[id]['maxitems'] && navigator.userAgent.indexOf('MSIE') == -1) {
                newDiv.style.width = __AutoComplete[id]['element'].offsetWidth - 22 + 'px';
            }

            newDiv.onmouseover = function() {AutoComplete_HighlightItem(__AutoComplete[id]['element'].getAttribute('id'), this.getAttribute('index'));};
            newDiv.onclick     = function() {AutoComplete_SetValue(__AutoComplete[id]['element'].getAttribute('id')); AutoComplete_HideDropdown(__AutoComplete[id]['element'].getAttribute('id'));}
            
            text   = document.createTextNode(toDisplay[i]);
            newDiv.appendChild(text);
            
            __AutoComplete[id]['dropdown'].appendChild(newDiv);
        }
//alert('hi2');         
        
        // Too many items?
        if (toDisplay.length > __AutoComplete[id]['maxitems']) {
            __AutoComplete[id]['dropdown'].style.height = (__AutoComplete[id]['maxitems'] * 15) + 2 + 'px';
        
        } else {
            __AutoComplete[id]['dropdown'].style.height = '';
        }

        
        /**
        * Set left/top in case of document movement/scroll/window resize etc
        */
        __AutoComplete[id]['dropdown'].style.left = AutoComplete_GetLeft(__AutoComplete[id]['element']);
        __AutoComplete[id]['dropdown'].style.top  = AutoComplete_GetTop(__AutoComplete[id]['element']) + __AutoComplete[id]['element'].offsetHeight;


        // Show the iframe for IE
        if (isIE) {
            __AutoComplete[id]['iframe'].style.top    = __AutoComplete[id]['dropdown'].style.top;
            __AutoComplete[id]['iframe'].style.left   = __AutoComplete[id]['dropdown'].style.left;
            __AutoComplete[id]['iframe'].style.width  = __AutoComplete[id]['dropdown'].offsetWidth;
            __AutoComplete[id]['iframe'].style.height = __AutoComplete[id]['dropdown'].offsetHeight;
            
            __AutoComplete[id]['iframe'].style.visibility = 'visible';
        }


        // Show dropdown
        if (!__AutoComplete[id]['isVisible']) {
            __AutoComplete[id]['dropdown'].style.visibility = 'visible';
            __AutoComplete[id]['isVisible'] = true;
        }

        
        // If now showing less items than before, reset the highlighted value
        if (__AutoComplete[id]['dropdown'].childNodes.length != numItems) {
            __AutoComplete[id]['highlighted'] = null;
        }
    }
    
    
    /**
    * Hides the dropdown layer
    * 
    * @param string id The form elements id. Used to identify the correct dropdown.
    */
    function AutoComplete_HideDropdown(id)
    {
        if (__AutoComplete[id]['iframe']) {
            __AutoComplete[id]['iframe'].style.visibility = 'hidden';
        }

        __AutoComplete[id]['dropdown'].style.visibility = 'hidden';
		__AutoComplete[id]['highlighted'] = null;
        __AutoComplete[id]['isVisible']   = false;
    }
    
    
    /**
    * Hides all dropdowns
    */
    function AutoComplete_HideAll()
    {
        for (id in __AutoComplete) {
            AutoComplete_HideDropdown(id);
        }
    }
    
    
    /**
    * Highlights a specific item
    * 
    * @param string id    The form elements id. Used to identify the correct dropdown.
    * @param int    index The index of the element in the dropdown to highlight
    */
    function AutoComplete_HighlightItem(id, index)
    {
        if (__AutoComplete[id]['dropdown'].childNodes[index]) {
            for (var i=0; i<__AutoComplete[id]['dropdown'].childNodes.length; ++i) {
                if (__AutoComplete[id]['dropdown'].childNodes[i].className == 'autocomplete_item_highlighted') {
                    __AutoComplete[id]['dropdown'].childNodes[i].className = 'autocomplete_item';
                }
            }
            
            __AutoComplete[id]['dropdown'].childNodes[index].className = 'autocomplete_item_highlighted';
            __AutoComplete[id]['highlighted'] = index;
        }
    }


    /**
    * Highlights the menu item with the given index
    * 
    * @param string id    The form elements id. Used to identify the correct dropdown.
    * @param int    index The index of the element in the dropdown to highlight
    */
    function AutoComplete_Highlight(id, index)
    {
        // Out of bounds checking
        if (index == 1 && __AutoComplete[id]['highlighted'] == __AutoComplete[id]['dropdown'].childNodes.length - 1) {
            __AutoComplete[id]['dropdown'].childNodes[__AutoComplete[id]['highlighted']].className = 'autocomplete_item';
            __AutoComplete[id]['highlighted'] = null;
        
        } else if (index == -1 && __AutoComplete[id]['highlighted'] == 0) {
            __AutoComplete[id]['dropdown'].childNodes[0].className = 'autocomplete_item';
            __AutoComplete[id]['highlighted'] = __AutoComplete[id]['dropdown'].childNodes.length;
        }

		// make sure that the dropdown is not null
		if (isNull(__AutoComplete[id]['dropdown'].childNodes[0]))
		{
			return;
		}

        // Nothing highlighted at the moment
        if (__AutoComplete[id]['highlighted'] == null) {
            __AutoComplete[id]['dropdown'].childNodes[0].className = 'autocomplete_item_highlighted';
            __AutoComplete[id]['highlighted'] = 0;

        } else {
            if (__AutoComplete[id]['dropdown'].childNodes[__AutoComplete[id]['highlighted']]) {
                __AutoComplete[id]['dropdown'].childNodes[__AutoComplete[id]['highlighted']].className = 'autocomplete_item';
            }

            var newIndex = __AutoComplete[id]['highlighted'] + index;

            if (__AutoComplete[id]['dropdown'].childNodes[newIndex]) {
                __AutoComplete[id]['dropdown'].childNodes[newIndex].className = 'autocomplete_item_highlighted';
                
                __AutoComplete[id]['highlighted'] = newIndex;
            }
        }
    }


    /**
    * Sets the input to a given value
    * 
    * @param string id    The form elements id. Used to identify the correct dropdown.
    */
    function AutoComplete_SetValue(id)
    {
        __AutoComplete[id]['element'].value = __AutoComplete[id]['dropdown'].childNodes[__AutoComplete[id]['highlighted']].innerHTML;
    }
    
    
    /**
    * Checks if the dropdown needs scrolling
    * 
    * @param string id    The form elements id. Used to identify the correct dropdown.
    */
    function AutoComplete_ScrollCheck(id)
    {
        // Scroll down, or wrapping around from scroll up
        if (__AutoComplete[id]['highlighted'] > __AutoComplete[id]['lastItemShowing']) {
            __AutoComplete[id]['firstItemShowing'] = __AutoComplete[id]['highlighted'] - (__AutoComplete[id]['maxitems'] - 1);
            __AutoComplete[id]['lastItemShowing']  = __AutoComplete[id]['highlighted'];
        }
        
        // Scroll up, or wrapping around from scroll down
        if (__AutoComplete[id]['highlighted'] < __AutoComplete[id]['firstItemShowing']) {
            __AutoComplete[id]['firstItemShowing'] = __AutoComplete[id]['highlighted'];
            __AutoComplete[id]['lastItemShowing']  = __AutoComplete[id]['highlighted'] + (__AutoComplete[id]['maxitems'] - 1);
        }
        
        __AutoComplete[id]['dropdown'].scrollTop = __AutoComplete[id]['firstItemShowing'] * 15;
    }


    /**
    * Function which handles the keypress event
    * 
    * @param string id    The form elements id. Used to identify the correct dropdown.
    */
    function AutoComplete_KeyDown(id)
    {
        // Mozilla
        if (arguments[1] != null) {
            event = arguments[1];
        }

        var keyCode = event.keyCode;

        switch (keyCode) {

            // Return/Enter
            case 13:
                if (__AutoComplete[id]['highlighted'] != null) {
                    AutoComplete_SetValue(id);
                    AutoComplete_HideDropdown(id);
                }
                
                event.returnValue = false;
                event.cancelBubble = true;
                break;

            // Escape
            case 27:
                AutoComplete_HideDropdown(id);
                event.returnValue = false;
                event.cancelBubble = true;
                break;
            
            // Up arrow
            case 38:
                if (!__AutoComplete[id]['isVisible']) {
                    AutoComplete_ShowDropdown(id);
                }
                
                AutoComplete_Highlight(id, -1);
                AutoComplete_ScrollCheck(id, -1);
                return false;
                break;
      
            // Tab
            case 9:
                if (__AutoComplete[id]['highlighted'] != null) 
				{
                    AutoComplete_SetValue(id);
                    AutoComplete_HideDropdown(id);
                }
                else if (__AutoComplete[id]['isVisible']) 
				{
                    AutoComplete_HideDropdown(id);
                }
                return;

            // Down arrow
            case 40:
                if (!__AutoComplete[id]['isVisible']) {
                    AutoComplete_ShowDropdown(id);
                }
                
                AutoComplete_Highlight(id, 1);
                AutoComplete_ScrollCheck(id, 1);
                return false;
                break;
        }
    }


    /**
    * Function which handles the keyup event
    * 
    * @param string id    The form elements id. Used to identify the correct dropdown.
    */
    function AutoComplete_KeyUp(id)
    {
        // Mozilla
        if (arguments[1] != null) {
            event = arguments[1];
        }

        var keyCode = event.keyCode;

        switch (keyCode) {
            case 13:
                event.returnValue = false;
                event.cancelBubble = true;
                break;

            case 27:
                AutoComplete_HideDropdown(id);
                event.returnValue = false;
                event.cancelBubble = true;
                break;
            
            case 38:
            case 40:
                return false;
                break;

            default:
                AutoComplete_ShowDropdown(id);
                break;
        }
    }
    
    /**
    * Returns whether the dropdown is visible
    * 
    * @param string id    The form elements id. Used to identify the correct dropdown.
    */
    function AutoComplete_isVisible(id)
    {
        return __AutoComplete[id]['dropdown'].style.visibility == 'visible';
    }

	// list of grocery names to auto suggest
    groceryNameAutoSuggest = ['apple', 'apple valley', 'asparagus', 'aluminium', 'air freshener', 
		'banana', 'blackberry', 'blueberry', 'bologna', 'baking soda', 'bacon', 'bathroom tissue', 'bathroom cleaner', 'butter', 'bocconcini',
		'cantaloupe', 'chicken breast', 'chicken drumettes', 'chicken drumstick', 'chicken leg quarter', 'chicken nugget', 'chicken strip', 'chicken thigh', 
		'cauliflower', 'cod', 'catelli', 'chocolate', 'champfleury', 'carrot', 'celery', 'coleslaw', 'cheesecake', 'coffee', 
		'cashew', 'coffee whitener', 'cranberry', 'compliments', 'chips', 'corned beef', 
		'chicken tournedo', 'cucumber', 'capocollo', 'cat litter', 
		'detergent', 'dish detergent', 'dishwasher detergent', 'disinfectant wipe', 'disinfectant spray', 'deep dish', 
		'english muffin', 'entree', 
		'frozen entree', 'fabric softener', 'facial tissue', 'french toast', 'french fries',
		'garbage bag', 'granola', 'glass cleaner', 'grapefruit',
		'haddock', 'halibut', 'honeydew',
		'ice cream',
		'kabob', 'kielbasa', 'kiwi', 'ketchup', 
		'lasagna', 'laundry detergent', 
		'macaroni & cheese dinner', 'mayonnaise', 'mussel', 'mineral water', 'mustard', 'mortadella', 'margarine', 
		'mushroom', 'mandarin orange', 'mango', 'mouthwash', 'muffin',
		'nectarine', 'nanaimo bar',
		'orange', 'orange juice', 'olive oil',
		'pineapple', 'pumpkin', 'potato', 'peach', 'pear', 'prosciutto', 'paper towel', 'pomegranate',
		'porchetta', 'pizza', 'provolone', 'pork chop', 'peameal bacon', 'pancake', 'popcorn',
		'royal gala', 'royale', 'romaine heart', 'ricotta', 'rice krispies square',
		'salad dressing', 'strawberry', 'sara lee', 'striploin', 'scallop', 'salmon', 'spinach', 'sausage', 'spring water', 'soft drink',
		'sparkling water', 'submarine', 'shepherd\'s pie',
		'tenderloin', 'toothpaste', 'tomato', 'tangerine', 'toothpaste', 'tilapia', 'tortilla', 'tissue', 'tournedo', 'trout',
		'toilet cleaner', 
		'vegetable', 
		'watermelon', 'weston', 'wiener', 'water', 'whipped cream',
		'yogurt', 'zucchini', 
		'aunt jemima', 'basics for less', 'beef beyond belief', 'betty crocker', 'black diamond', 'blue water', 'bittner\'s', 'bolthouse farms', 
		'campbell\'s', 'chef boyardee', 
		'danone', 'del monte', 'dempster\'s', 'dr. oetker', 'electrasol', 'equality', 'farmer\'s market', 'five alive', 'fruitopia', 
		'gatorade', 'general mills', 'high liner', 'heinz', 'habitant', 
		'i can\'t believe it\'s not butter!', 'irresistibles', 'johnsonville', 'kellogg\'s', 'kool-aid', 'knorr', 'lipton',
		'mariposa', 'mccain',  'maple lodge', 'maple leaf', 'marc angelo', 'master choice', 'minute maid', 
		'nature valley', 'nestle', 'neilson', 'no name', 
		'orville redenbacher\'s', 
		'philadelphia', 'pepperidge farms', 'piller\'s', 'pillsbury', 'powerade', 'president\'s choice', 'purina', 
		'real canadian', 
		'san daniele prosciutto', 'schneiders', 'snuggle', 'spongetowels', 'stove top', 'sunlight', 'sunshine', 
		'tostitos', 'tre stelle', 'tropicana', 'yoplait', 'ziggy\'s'].sort();

	cityAutoSuggest = new Array();
	
	cityAutoSuggest['AB'] = ['Airdrie', 'Brooks', 'Calgary', 'Camrose', 'Cold Lake', 'Edmonton', 'Fort Saskatchewan', 
		'Grande Prairie', 'Leduc', 'Lethbridge', 'Lloydminster', 'Medicine Hat', 'Red Deer', 'Spruce Grove', 'St. Albert', 'Wetaskiwin'];
	
	cityAutoSuggest['BC'] = ['Abbotsford', 'Armstrong', 'Burnaby', 'Campbell River', 'Castlegar', 'Chilliwack', 'Colwood', 'Coquitlam', 
		'Courtenay', 'Cranbrook', 'Dawson Creek', 'Duncan', 'Enderby', 'Fernie', 'Fort St. John', 
		'Grand Forks', 'Greenwood', 'Kamloops', 'Kelowna', 'Kimberley', 'Kitimat', 'Langford', 
		'Langley', 'Merritt', 'Nanaimo', 'Nelson', 'New Westminster', 'North Vancouver', 'Parksville', 
		'Penticton', 'Pitt Meadows', 'Port Alberni', 'Port Coquitlam', 'Port Moody', 'Powell River', 
		'Prince George', 'Prince Rupert', 'Quesnel', 'Revelstoke', 'Richmond', 'Rossland', 'Salmon Arm', 
		'Surrey', 'Terrace', 'Trail', 'Vancouver', 'Vernon', 'Victoria', 'White Rock', 'Williams Lake'];

	cityAutoSuggest['MB'] = ['Brandon', 'Dauphin', 'Flin Flon', 'Portage la Prairie', 'Selkirk', 'Steinbach', 
		'Thompson', 'Winkler', 'Winnipeg'];

	cityAutoSuggest['NB'] = ['Bathurst', 'Campbellton', 'Dieppe', 'Edmundston', 'Fredericton', 'Miramichi', 
		'Moncton', 'Saint John'];

	cityAutoSuggest['NL'] = ['Corner Brook', 'Mount Pearl', 'St. John\'s'];

	cityAutoSuggest['NS'] = ['Halifax', 'Sydney', 'Dartmouth'];

	cityAutoSuggest['NT'] = ['Yellowknife'];

	cityAutoSuggest['NU'] = ['Iqaluit'];

	cityAutoSuggest['ON'] = ['Barrie', 'Belleville', 'Brampton', 'Brant', 'Brantford', 'Brockville', 'Burlington', 
		'Cambridge', 'Chatham-Kent', 'Clarence-Rockland', 'Cornwall', 'Dryden', 'Elliot Lake', 
		'Greater Sudbury', 'Guelph', 'Haldimand County', 'Hamilton', 'Kawartha Lakes', 
		'Kenora', 'Kingston', 'Kitchener', 'Lambton Shores', 'London', 'Mississauga', 
		'Niagara Falls', 'Norfolk County', 'North Bay', 'Orillia', 'Oshawa', 'Ottawa', 'Owen Sound', 
		'Pembroke', 'Peterborough', 'Pickering', 'Prince Edward County', 'Port Colborne', 
		'Quinte West', 'Sarnia', 'Sault Ste. Marie', 'St. Catharines', 'St. Thomas', 'Stratford', 
		'Temiskaming Shores', 'Thorold', 'Thunder Bay', 'Timmins', 'Toronto', 'Vaughan', 
		'Waterloo', 'Welland', 'Windsor', 'Woodstock'];

	cityAutoSuggest['OT'] = ['Thunder Bay'];

	cityAutoSuggest['PE'] = ['Charlottetown', 'Summerside'];

	cityAutoSuggest['QC'] = ['Acton Vale', 'Alma', 'Amos', 'Amqui', 'L\'Ancienne-Lorette', 'L\'Assomption', 'Asbestos', 
		'Baie-Comeau', 'Baie-d\'Urfé', 'Baie-Saint-Paul', 'Barkmere', 'Beaconsfield', 'Beauceville', 
		'Beauharnois', 'Beaupré', 'Bécancour', 'Bedford', 'Belleterre', 'Beloeil', 'Berthierville', 
		'Blainville', 'Bois-des-Filion', 'Boisbriand', 'Bonaventure', 'Boucherville', 'Bromont', 
		'Brossard', 'Brownsburg-Chatham', 'Cabano', 'Candiac', 'Cap-Chat', 'Cap-Santé', 'Carignan', 
		'Carleton-sur-mer', 'Causapscal', 'Chambly', 'Chandler', 'Chapais', 'Charlemagne', 'Châteauguay', 
		'Château-Richer', 'Chibougamau', 'Clermont', 'Coaticook', 'Contrecoeur', 'Cookshire-Eaton', 
		'Côte-Saint-Luc', 'Cowansville', 'Danville', 'Daveluyville', 'Dégelis', 'Delson', 'Desbiens', 
		'Deux-Montagnes', 'Disraeli', 'Dolbeau-Mistassini', 'Dollard-des-Ormeaux', 'Donnacona', 
		'Dorval', 'Drummondville', 'Dunham', 'Duparquet', 'East Angus', 'L\'Épiphanie', 'Estérel', 
		'Farnham', 'Fermont', 'Forestville', 'Fossambault-sur-le-Lac', 'Gaspé', 'Gatineau', 
		'Gracefield', 'Granby', 'Grande-Rivière', 'Hampstead', 'Hudson', 'Huntingdon', 
		'L\'Île-Cadieux', 'L\'Île-Dorval', 'L\'Île-Perrot', 'Joliette', 'Kingsey Falls', 'Kirkland', 
		'Lac-Brome', 'Lac-Delage', 'Lac-Mégantic', 'Lac-Saint-Joseph', 'Lac-Sergent', 'Lachute', 
		'Laval', 'Lavaltrie', 'Lebel-sur-Quévillon', 'Léry', 'Lévis', 'Longueuil', 'Lorraine', 
		'Louiseville', 'Macamic', 'Magog', 'Malartic', 'La Malbaie', 'Maniwaki', 'Marieville', 
		'Mascouche', 'Matagami', 'Matane', 'Mercier', 'Métabetchouan–Lac-à-la-Croix', 'Métis-sur-Mer', 
		'Mirabel', 'Mont-Joli', 'Mont-Laurier', 'Mont-Royal', 'Mont-Saint-Hilaire', 'Mont-Tremblant', 
		'Montmagny', 'Montreal', 'Montréal-Est', 'Montréal-Ouest', 'Murdochville', 'Neuville', 
		'New Richmond', 'Nicolet', 'Normandin', 'Notre-Dame-de-l\'Île-Perrot', 
		'Notre-Dame-des-Prairies', 'Notre-Dame-du-Lac', 'Otterburn Park', 'Paspébiac', 'Percé', 
		'Pincourt', 'Plessisville', 'La Pocatière', 'Pohénégamook', 'Pointe-Claire', 'Pont-Rouge', 
		'Port-Cartier', 'Portneuf', 'La Prairie', 'Princeville', 'Prévost', 'Quebec City', 
		'Repentigny', 'Richelieu', 'Richmond', 'Rimouski', 'Rivière-du-Loup', 'Rivière-Rouge', 
		'Roberval', 'Rosemère', 'Rouyn-Noranda', 'Saguenay', 'Sainte-Adèle', 'Sainte-Agathe-des-Monts', 
		'Sainte-Anne-de-Beaupré', 'Sainte-Anne-de-Bellevue', 'Sainte-Anne-des-Monts', 'Sainte-Anne-des-Plaines', 
		'Saint-Augustin-de-Desmaures', 'Saint-Basile', 'Saint-Basile-le-Grand', 'Saint-Bruno-de-Montarville', 
		'Sainte-Catherine', 'Sainte-Catherine-de-la-Jacques-Cartier', 'Saint-Césaire', 'Saint-Constant', 
		'Saint-Eustache', 'Saint-Félicien', 'Saint-Gabriel', 'Saint-Georges', 'Saint-Hyacinthe', 'Saint-Jean-sur-Richelieu', 
		'Saint-Jérôme', 'Saint-Joseph-de-Beauce', 'Saint-Joseph-de-Sorel', 'Sainte-Julie', 'Saint-Lambert', 
		'Saint-Lazare', 'Saint-Lin-Laurentides', 'Saint-Marc-des-Carrières', 'Sainte-Marguerite-du-Lac-Masson', 
		'Sainte-Marie', 'Sainte-Marthe-sur-le-Lac', 'Saint-Ours', 'Saint-Pamphile', 'Saint-Pascal', 
		'Saint-Pie', 'Saint-Raymond', 'Saint-Rémi', 'Saint-Sauveur', 'Sainte-Thérèse', 'Saint-Tite', 
		'Salaberry-de-Valleyfield', 'La Sarre', 'Schefferville', 'Scotstown', 'Senneterre', 'Sept-Îles', 
		'Shawinigan', 'Sherbrooke', 'Sorel-Tracy', 'Stanstead', 'Sutton', 'Témiscaming', 'Terrebonne', 
		'Thetford Mines', 'Thurso', 'Trois-Pistoles', 'Trois-Rivières', 'La Tuque', 'Val-d\'Or', 
		'Valcourt', 'Varennes', 'Vaudreuil-Dorion', 'Victoriaville', 'Ville-Marie', 'Warwick', 
		'Waterloo', 'Waterville', 'Westmount', 'Windsor'];

	cityAutoSuggest['SK'] = ['Estevan', 'Flin Flon', 'Humboldt', 'Lloydminster', 'Melfort', 'Melville', 'Moose Jaw', 
		'North Battleford', 'Prince Albert', 'Regina', 'Saskatoon', 'Swift Current', 'Weyburn', 'Yorkton'];

	cityAutoSuggest['YT'] = ['Whitehorse'];

	cityAutoSuggest['-1'] = cityAutoSuggest['AB'].concat(cityAutoSuggest['BC'], cityAutoSuggest['MB'], 
		cityAutoSuggest['NB'], cityAutoSuggest['NL'], cityAutoSuggest['NS'], cityAutoSuggest['NT'], 
		cityAutoSuggest['NU'], cityAutoSuggest['ON'], cityAutoSuggest['PE'], cityAutoSuggest['QC'], 
		cityAutoSuggest['SK'], cityAutoSuggest['YT']).sort();
