function BuildLocationPicker(url_locationSuggestion, url_locationDetail, url_mapFlashFile , controlID, showFlashMap, showTooltip) {
		
	$('#' + controlID).SetupLocationPicker({	    
	    maxResults: 6, 
		mapColors: {
			background_idle: '0xFFFFFF',
			background_hover: '0xE4E4E4',
			background_active: '0xFBBD84',
			outline: '0xF0812F'
			},
        databaseHandler_URLs: {
            locationSuggestion: url_locationSuggestion,
            locationDetail: url_locationDetail,
            mapFlash: url_mapFlashFile
        },
        showFlashMap: showFlashMap,
        showTooltip: showTooltip
	});
	
}

//Receive Data from Flash
function ReceiveData(value) {
	$('#dLocationPicker').trigger('TransferLocationFromFlash', value);
}

/* @@ Textbox & Autocomplete
   ==================================================================== */
   
(function($) {
    $.fn.SetupLocationPicker = function(pluginSettings) {
        var defaultSettings = {
            parameter: 'parameter_value',
            databaseHandler_URLs: {
                locationSuggestion: 'App_Handlers/Location/suggestions.ashx',
                locationDetail: 'App_Handlers/Location/detail.ashx',
                mapFlash: ''
            },
            queryDelay: 200, 		// milisegundos
            requestTimeout: 20000, 	//milisegundos
            mininumChars: 3, 	// valor tido em conta apenas para o primeiro request de localizações.
            maxResults: 6,
            showFlashMap: 'true',
            showTooltip: 'true',
            locationInfo: {
                defaultLocation: '/1/',
                maxDephts: 3
            },
            currentItem_class: 'current',
            dicionary: {
                add: 'Adicionar',
                remove: 'Remover'
            },
            mapInfo: {
                filesPath: 'App_Themes/propertykingdom/images/locationpicker/maps/',
                mainFile: 'mapa.swf',
                flashMinVersion: '8.0.0.0',
                flashvars: false,
                params: {
                    quality: 'high',
                    wmode: 'transparent',
                    bgcolor: '#f1f1f1'
                },
                attributes: {
            }
            },
            mapColors: {
                background_idle: '0xFFFFFF',
                background_hover: '0xE4E4E4',
                background_active: '0xFBBD84',
                outline: '0xF0812F'
            },
            mapDimensions: {
                width: 290,
                height: 230
            }
    };
    var $settings = $.extend(defaultSettings, pluginSettings);

    return this.each(function() {

        $settings.mapInfo.filesPath = $settings.databaseHandler_URLs.mapFlash;

        // ============================================================================================
        // ============================================================================================
        // ============================================================================================

        // INDEX

        // DECLARATIONS
        // INIT
        // TEXT INPUT
        // SUGGESTIONS
        // LOCATION PIECES (legos)
        // FLASH MAP
        // TOOLTIP	

        // ============================================================================================
        // ============================================================================================
        // ============================================================================================







        // ============================================================================================
        // ============================================================================================
        // ============================================================================================

        // @@ DECLARATIONS

        // ============================================================================================
        // ============================================================================================
        // ============================================================================================

        var $textbox = $('#txtLocationPicker', $(this)),
				$suggestionsDiv = $('#dSuggestions', $(this)),
				$loader = $('.loader', $(this)),
				$notfound = $('.notfound', $(this)),
				$error = $('.error', $(this)),
				$pickedID = $('#dPickedID input', $(this)),
				$pickedLocationsDiv = $('#dPickedLocations', $(this)),
				$dLocationPickerDiv = $($(this)),
				$dMapFlashDiv = $('#dFlashMap', $(this)),
				$tooltip = $('#locationTooltip', $(this));

        var _delayID = -1;
        var _keyboard = { left: 37, up: 38, right: 39, down: 40, enter: 13, escape: 27, backspace: 8 };


        var currentIndex = -1,
				currentID = '',
				currentName = '';

        var _mapLoaded = false;
        
        var _ajaxRequest = null;


        // ============================================================================================
        // ============================================================================================
        // ============================================================================================

        // @@ INIT

        // ============================================================================================
        // ============================================================================================
        // ============================================================================================

        // 1. configurar a defualt location
        $pickedID.val($settings.locationInfo.defaultLocation);

        // 2. create a dummy location object to request images from server, so they can be ready when needed
        $(this).append('<a href="#" class="pickedLocation" title="" style="display:none"><span></span></a>');

        // 3. carregar mapa
        if($settings.showFlashMap == 'true')
        {
            LoadFlashMap();
        }
        else{
            $dMapFlashDiv.remove();
        }
        
        // 4. Remover tooltip se necessário
        if($settings.showTooltip == 'false'){
            $tooltip.remove();
        }


        // ============================================================================================
        // ============================================================================================
        // ============================================================================================

        // @@ TEXT INPUT

        // ============================================================================================
        // ============================================================================================
        // ============================================================================================

        // ----------------------------------------------------------------------
        // > Ao escrever na caixa de texto, solicito à BD os dados adequados
        $textbox.keyup(function(event) {
            $error.hide();
            // 1. obter o token introduzido na textbox
            var token = $textbox.val();

            // 2. apenas invocar a base de dados se: for um caracter válido + houverem caracteres suficientes
            if (IsIgnoredKey(event.keyCode) == false) {
                if (HasEnoughChars(token) == true) {

                    // 2.1. apresentar o loader
                    $loader.show();

                    // 2.2. esconder o icon que indica não haverem sugestões 
                    $notfound.hide();

                    // 2.3. garantir que só são feitos pedidos à BD de x em x segundos

                    // 2.3.1. apagar possiveis timeouts a decorrer
                    if (_delayID != -1) {
                        clearTimeout(_delayID);
                    }

                    // 2.3.2 criar novo timeout
                    _delayID = setTimeout(function() {
                        RequestSuggestions(token);
                    }, $settings.queryDelay);

                }
                else {

                    // 2.4. apaga as sugestões
                    ClearSuggestions();
                }
            }

        });
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // > remover localizações c/ o backspace
        $textbox.keydown(function(event) {
            $error.hide();
            // 1. se estou a carregar no backspace... 
            if (event.keyCode == _keyboard.backspace) {
                // 1.1. se não há mais caracteres na caixa de texto...
                if ($textbox.val().length == 0) {
                    // 1.1.1 e há localizações (legos) seleccionadas...
                    if (GetNumberPickedLocations() > 0) {
                        //1.1.1.1 é porque quero remover essa localização!
                        UnPickLastActiveLocation();
                    }
                }
            }

        });
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // > evita que um clique em cima da caixa de texto, faça desaparecer as sugestões
        $textbox.click(function(event) {
            event.stopPropagation();
        });
        // ----------------------------------------------------------------------
        
        // ----------------------------------------------------------------------
        // > no focus escondo a tooltip
        $textbox.focus(function() {
            if($tooltip.is(':hidden')) {
                Tooltip_Show(GetCurrentLocationDepth());
            }
            $error.hide();
        });
        $textbox.blur(function() {
        
        });
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // > verifica se existem caracteres suficientes para iniciar uma pesquisa
        function HasEnoughChars(token) {

            // 1. Se já houverem localizações PAI
            if ($pickedLocationsDiv.children().length > 0) {
                // 1.1. ...basta existir apenas um caracter
                return (token.length >= 1);
            }
            else {
                // 1.2. ...é necessário pelo menos $settings.mininumChars caracteres
                return (token.length >= $settings.mininumChars);
            }

        };
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // > verifica se determinada tecla pressionada deve ser considerada para solicitar dados à BD
        function IsIgnoredKey(nKeyCode) {
            if ((nKeyCode == 9) || (nKeyCode == 13) || // tab, enter
    			        (nKeyCode == 16) || (nKeyCode == 17) || // shift, ctl
    			        (nKeyCode >= 18 && nKeyCode <= 20) || // alt, pause/break,caps lock
    			        (nKeyCode == 27) || // esc
    			        (nKeyCode >= 33 && nKeyCode <= 35) || // page up,page down,end
            /*(nKeyCode >= 36 && nKeyCode <= 38) || // home,left,up
            (nKeyCode == 40) || // down*/
    			        (nKeyCode >= 36 && nKeyCode <= 40) || // home,left,up, right, down
    			        (nKeyCode >= 44 && nKeyCode <= 45) || // print screen,insert
    			        (nKeyCode == 224) || // print screen,insert
    			        (nKeyCode == 229) // Bug 2041973: Korean XP fires 2 keyup events, the key and 229
    			    ) {
                return true;
            }
            return false;
        };
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        function CloseBecauseError() {

            // 1. Limpar a textbox
            $textbox.val('');
            //$textbox.attr('readonly', 'true');
            

            // 2. Limpar nodes existentes
            $pickedLocationsDiv.children().remove();
            $textbox.focus();
            // 3. Mostrar o icon de erro
            $error.show();
        }
        // ----------------------------------------------------------------------





        // ============================================================================================
        // ============================================================================================
        // ============================================================================================

        // @@ SUGGESTIONS

        // ============================================================================================
        // ============================================================================================
        // ============================================================================================


        // ----------------------------------------------------------------------
        // > Pedido de sugestões à BD
        function RequestSuggestions(locationToken, locationRoot) {
            
            Tooltip_Hide(); // &tooltip
            
            if (_ajaxRequest) {
                _ajaxRequest.abort();
            }

            // 0. faço o pedido assincrono ao handler
            _ajaxRequest = $.ajax({
                type: 'GET',
                timeout: $settings.requestTimeout,
                url: $settings.databaseHandler_URLs.locationSuggestion,
                processData: true,
                data: {
                    locationToken: encodeURI(locationToken),
                    maxResults: $settings.maxResults,
                    locationRoot: $pickedID.val()
                },
                dataType: 'json',
                error: function(request, status, error) {

                    // 1.1. apresento o erro
                    //alert('Error: ' + status);

                    // 1.2. escondo o loader
                    $loader.hide();

                },
                complete:function(jqXHR, textStatus){
                    if(textStatus=='error'){
                        //_ajaxRequest.abort();
                       RequestSuggestions(locationToken, locationRoot);
                    }
                
                },
                success: function(data) {

                    if (data.suggestions != null && data.suggestions !=undefined ) {
                                        
                        // 2.1. carrego as sugestões
                        DisplaySuggestions(data.suggestions, data.totals, locationToken);

                        // 2.2. escondo o loader
                        $loader.hide();
                        
                    }
                    

                }
            });



        };
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // > Apresento as sugestões, lista de DIVs
        function DisplaySuggestions(suggestions, totals, locationToken) {

            // 1. Apago as sugestões que possam existir na lista
            ClearSuggestions();

            // 2. Se existirem sgestões a apresentar
            if (suggestions.length > 0) {

                // 2.1 para cada uma delas
                $.each(suggestions, function(index, locationGroup) {

                    // 2.1.1. construo a descrição a apresentar por cada sugestão | ex.: Custóias, Matosinhos, Porto
                    var locationLine = '';
                    var activeLocations = $pickedLocationsDiv.children().length;                   
                    for (var i = activeLocations; i < locationGroup.locations.length; i++) { // loop made for inverted suggestion order
                        locationLine += ', ' + locationGroup.locations[i].desc;
                    }
                    
                    /*
                    for (var i = 0; i < (locationGroup.locations.length - activeLocations); i++) { // loop made for original suggestion order
                        locationLine += ', ' + locationGroup.locations[i].desc;
                    }
                    */
                    
                    locationLine = locationLine.substr(1);

                    // 2.1.2. construo o objecto (sugestão) a ser aidiconado à lista de sugestões
                    var linkTemplate = $('<a href="#">' + locationLine + '</a>');

                    // 2.1.3. anexo-lhe os dados (JSON) relativos à localização que ele representa
                    linkTemplate.data('locationGroupInfo', locationGroup);

                    // 2.1.4. anexo-lhe o indice da lista respectivo
                    linkTemplate.data('itemIndex', index);

                    // 2.1.5. preparo o efeito de hovering no objecto
                    linkTemplate.hover(
						   function() {

						       // 2.1.5.1. ao passar o rato por cima devo marcar o objecto como seleccionado
						       currentIndex = $(this).data("itemIndex");
						       SetSelected(currentIndex);
						       //$textbox.blur();

						   }, function() {

						       // 2.1.5.2. ao retirar o rato de cima devo desmarcá-lo como objecto seleccionado
						       linkTemplate.removeClass($settings.currentItem_class);
						       currentIndex = -1;
						       //$textbox.blur();
						   }
						);

                    // 2.1.6. preparo o click no objecto
                    linkTemplate.click(function(event) {

                        // 2.1.6.1. chamo a função de selecção de item
                        PickLocation(locationGroup, false);

                        // 2.1.6.2. evito a propagação do evento
                        event.stopPropagation();
                        return false;
                    });

                    // 2.1.7. sublinho a existencia do token especificado em cada sugestão
                    linkTemplate.highlight(locationToken);

                    // 2.1.8. adiciono o objecto ao div de sugestões
                    $suggestionsDiv.append(linkTemplate);

                });

                /*					
                if(suggestions.length < totals) {
                $suggestionsDiv.append('<a href="#">...</a>');	
                }
                */

                // 2.2. faço com que cada click fora da àrea de sugestões, as apage
                $('body').one('click', function() {
                    ClearTextbox();
                    ClearSuggestions();
                });

                // 2.4. depois de preparado, mostro o div de sugestões se no momento a caixa de texto tiver o minimo de caracteres
                if(HasEnoughChars($textbox.val())){
                    $suggestionsDiv.show();
                }
                else{
                    ClearSuggestions();
                }
                

            }
            else {

                // 2.1. se não houverem sugestões a apresentar apresento o icon de sugestões não encontradas
                $notfound.show();
            }

        };
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // > Limpa todas as sugestões activas
        function ClearSuggestions() {

            // 1. escondo o div com as sugestões
            $suggestionsDiv.hide();

            // 2. apago o seu conteudo, para na próxima vez que for apresentado, não levar com valores obsoletos
            $suggestionsDiv.children().remove();
        };
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // > Limpa a textbox
        function ClearTextbox() {

            // 1. retiro o focus da textbox, pois só assim consigo alterar o seu valor
            $textbox.blur();

            // 2. reset ao valor da textbox
            $textbox.val('');

            // 3. volto a atribuir o focus à textbox
            $textbox.focus();
        };
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // > Para cada tecla 
        $(document).keydown(function(e) {

            var pressed = false;

            // 1. Se estão a ser apresentadas localizações
            if ($suggestionsDiv.is(':visible')) {

                switch (e.keyCode) {

                    // up arrow                       
                    case _keyboard.up:
                        if ($loader.is(':visible')) return false;
                        Navigate('up');
                        pressed = true;
                        break;

                    // down arrow                       
                    case _keyboard.down:
                        if ($loader.is(':visible')) return false;
                        Navigate('down');
                        pressed = true;
                        break;

                    // enter key                       
                    case _keyboard.enter:
                        if ($loader.is(':visible')) return false;

                        // 1. Get location info JSON object
                        var locationInfo = $suggestionsDiv.children('a').eq(currentIndex).data('locationGroupInfo');

                        // 2. Pick Location
                        PickLocation(locationInfo, false);

                        pressed = true;
                        break;

                    // escape key                       
                    case _keyboard.escape:
                        ClearTextbox();
                        ClearSuggestions();
                        pressed = true;
                        break;

                }

            }

            if (pressed)
                return false;


        });
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        function Navigate(direction) {

            if ($suggestionsDiv.children('a').filter('.' + $settings.currentItem_class).size() == 0) {
                currentIndex = -1;
            }

            if (direction == 'up' && currentIndex != -1) {
                if (currentIndex != 0) {
                    currentIndex--;
                }
                else {
                    $suggestionsDiv.children('a').removeClass($settings.currentItem_class);
                    $textbox.focus();
                    currentIndex = -1;
                    return;
                }
            } else if (direction == 'down') {
                if (currentIndex != $suggestionsDiv.children('a').size() - 1) {
                    currentIndex++;
                }
            }

            SetSelected(currentIndex);

        };
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        function SetSelected(itemIndex) {
            if (itemIndex >= 0) {
                $suggestionsDiv.children('a').removeClass($settings.currentItem_class);
                $suggestionsDiv.children('a').eq(itemIndex).addClass($settings.currentItem_class);
            }
        };
        // ----------------------------------------------------------------------







        // ============================================================================================
        // ============================================================================================
        // ============================================================================================

        // @@ LOCATION PIECES (legos)

        // ============================================================================================
        // ============================================================================================
        // ============================================================================================


        // ----------------------------------------------------------------------
        function PickLocation(locationInfo, pickedInMap) {
            // 0. Limpar nodes existentes
            $pickedLocationsDiv.children().remove();            
            
            // 1. Construo as objectos (legos) das localizações
            if (locationInfo.locations.length > 0) {
                
                // 1.2. Copiar para o $pickedID o ID da localização seleccionada
                $pickedID.val(locationInfo.locations[locationInfo.locations.length - 1].id);
                
                
                   
                // 1.3. Contruir objectos(legos) para as localizações
                $.each(locationInfo.locations, function(index, location) {

                    // 1.3.1. construir o template do item
                    var itemTemplate = $('<a href="#" class="pickedLocation"><span></span></a>');

                    // 1.3.2. customizar descrição
                    itemTemplate.children('span').text(location.desc);

                    // 1.3.3. construir tooltip | Ex.: "Remover [location] + [child locations]"
                    var tooltip = ' + [' + location.desc + ']'; 
                    if (index + 1 < locationInfo.locations.length) { // if+for made for inverted suggestion order
                        for (var i = index + 1; i < locationInfo.locations.length; i++) {
                             tooltip += ' + [' + locationInfo.locations[i].desc + ']';
                        }
                    }                    
                    
                    /*
                    if (index > 0) { // if+for made for original suggestion order
                        for (var i = index - 1; i >= 0; i--) {
                            tooltip += ' + [' + locationInfo.locations[i].desc + ']';
                        }
                    }
                    */
                    itemTemplate.attr('title', $settings.dicionary.remove + ' ' + tooltip.substr(3));

                    // 1.3.4. attach de toda a informação relativa à localização
                    itemTemplate.data('locationItemInfo', location);

                    // 1.3.5. obter o id da localização pai
                    var parentID = $settings.locationInfo.defaultLocation;  
                    if (index - 1 >= 0) { // loop made for inverted suggestion order
                        parentID = locationInfo.locations[index - 1].id;
                    }
                    /*
                    if (index < locationInfo.locations.length - 1) { // if made for original suggestion order
                        parentID = locationInfo.locations[index + 1].id;
                    }
                    */
                    
                    // 1.3.6. bind do evento click
                    itemTemplate.click(function() {
                        UnPickLocation($(this), parentID);
                        return false;
                    });

                    // 1.3.7. atribuir ao href o parentID para uso posterior por outros métodos
                    itemTemplate.attr('href', parentID);

                    // 1.3.8. append ao div de localizações pickadas
                    $pickedLocationsDiv.prepend(itemTemplate);

                });
                
                // 1.3.8. Apagar sugestões
                ClearSuggestions();
                ClearTextbox();

                // 1.3.10. comunicar ao flash o novo ID, caso este ainda não saiba (pickedInMap = false)
                if(_mapLoaded){
                    if (!pickedInMap) {
                        TransferLocationToFlash(locationInfo.locations[locationInfo.locations.length-1].id);    // for inverted suggestion order
                        //TransferLocationToFlash(locationInfo.locations[0].id);    // for original suggestion order
                    }
                }
                

            }

            // 2. ajustar positionamento da textbox
            AdjustTextboxPosition();
            
            if($settings.showTooltip == 'true'){
                Tooltip_Show(GetCurrentLocationDepth()); // &tooltip
            }
            

        };
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        function UnPickLocation(item, parentID) {

            // 1. atribuir o ID
            $pickedID.val(parentID);

            // 2. remover todos os nós-localização filhos (anteriores no html)
            item.prevAll().remove();

            // 3. remover o próprio nó-localização
            item.remove();

            // 4. ajustar positionamento da textbox
            AdjustTextboxPosition();

            // 5. reatribuir o focus à textbox
            ClearSuggestions();
            ClearTextbox();

            // 6. comunicar ao flash o novo ID
            if(_mapLoaded){
                TransferLocationToFlash(parentID);
            }
            
            if($settings.showTooltip == 'true'){
                Tooltip_HideAndShow(GetCurrentLocationDepth());
            }
            

        }
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // > remove a localização activa mais profunda
        function UnPickLastActiveLocation() {

            // 1. obter item a ser removido
            var $item = $pickedLocationsDiv.children('a').first();
            
            // 2. obter o seu nome
            var itemName = $item.children('span').text();

            // 3. obter o seu parentID
            var itemParentID = $settings.locationInfo.defaultLocation;
            if ($item.next().size() > 0) {
                // 3.1 se existe pelo menos um pai deste node obtenho o seu parentID, que está armazenado no href do próprio
                itemParentID = $item.attr('href');
            }
            
            // 4. pedir confirmação de remoção
            var unpickConfirmed = confirm($settings.dicionary.remove + ' [' + itemName + ']?');
            if (unpickConfirmed) {
                // 4.1 remover
                UnPickLocation($item, itemParentID);
            }
            
        }
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // retorna o numero de localizações pickadas no momento
        function GetNumberPickedLocations() {
            return $pickedLocationsDiv.children('a').length;
        };
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // > Re-posiciona a textbox na área, de acordo com o espaço disponibilizado pelos objectos de localização activos
        function AdjustTextboxPosition() {

            // 1. obter dimensões
            var dimensions = {
                // 1.1. obter a largura máxima para a textbox
                totalWidth: $dLocationPickerDiv.width(),
                // 1.2. obter a largura ocupada pelas objectos de localização existentes
                usedWidth: $pickedLocationsDiv.width(),
                // 1.3. calcular a largura disponível
                availableWidth: 0,
                // 1.4. reservar um padding
                padding: 10
            };

            // 1.3. calcular a largura disponível
            dimensions.availableWidth = dimensions.totalWidth - dimensions.usedWidth,

            // 2. atribuir nova largura para à textbox
            $textbox.width(dimensions.availableWidth - (dimensions.padding * 2));

            // 3. atribuir novo padding-left à textbox
            $textbox.css('margin-left', Number(dimensions.usedWidth + dimensions.padding) + 'px');

            // 4. verifica se o utilizador ainda pode especificar mais localizações
            if (GetNumberPickedLocations() == $settings.locationInfo.maxDephts) {
                $textbox.attr('readonly', 'true');
            }
            else {
                $textbox.removeAttr('readonly');
            }
            
            // 5. verificar se os objectos não cairam para fora da area da textbox
            while (dimensions.availableWidth - dimensions.padding <= 0) {

                var numChars = 6;

                // 5.1 percorrer cada objecto (lego) e retirar-lhe x caracteres
                for (var i = 0; i < $pickedLocationsDiv.children('a').length; i++) {
                    var $label = $pickedLocationsDiv.children('a').eq(i).children('span');

                    var currentText = $label.text();
                    currentText = currentText.substr(0, currentText.length - numChars) + '...';

                    $label.text(currentText);
                }

                // 5.2 recalcular espaço disponível
                dimensions.usedWidth = $pickedLocationsDiv.width();
                dimensions.availableWidth = dimensions.totalWidth - dimensions.usedWidth;
            }

        }
        // ----------------------------------------------------------------------




        // ============================================================================================
        // ============================================================================================
        // ============================================================================================

        // @@ FLASH MAP

        // ============================================================================================
        // ============================================================================================
        // ============================================================================================


        // ------------------------------------------------			
        // > Carrega o mapa flash
        function LoadFlashMap() {

            try {

                // 1. preparar o url do mapa para fazer o embeed				
                var embedURL = $settings.mapInfo.filesPath + $settings.mapInfo.mainFile
							 + '?bg_idle=' + $settings.mapColors.background_idle
							 + '&bg_over=' + $settings.mapColors.background_hover
							 + '&bg_active=' + $settings.mapColors.background_active
							 + '&outline=' + $settings.mapColors.outline
							 + '&filespath=' + $settings.mapInfo.filesPath
							 + '&limit=true';

                // 2. obter o htmlNode onde o flash vai ser carregado
                var flashHolder = $dMapFlashDiv.attr('id');

                // 3. carregar o flash
                swfobject.embedSWF(
					embedURL,
					flashHolder,
					$settings.mapDimensions.width,
					$settings.mapDimensions.height,
					$settings.mapInfo.flashMinVersion,
					'',
					$settings.mapInfo.flashvars,
					$settings.mapInfo.params,
					$settings.mapInfo.attributes,
					function(e) {
					    // 3.1. Verificar o sucesso do carregamento
					    _mapLoaded = e.success; //    !!!!!!!!!!!!!NÂO ESTÀ A FUNCIONAR.... DEVOLVE SEMPRE SUCESSO!!!!!!!
					    // 3.2. the div is now transformed in an object... 
					    if (_mapLoaded) {
					        // 3.2.1 should update the var $dMapFlashDiv for later correct use
					        $dMapFlashDiv = $('#' + flashHolder);
					    }
					});

            }
            catch (erro) {
                CloseBecauseError();
            }

        };
        // ------------------------------------------------	


        // ------------------------------------------------
        // > interpreta a nova localização enviada pelo flash e constrói os objectos adequados
        $(this).bind('TransferLocationFromFlash', function(event, id) {

            Tooltip_Hide(); // &tooltip
            
            $error.hide();
            $loader.show();

            $.ajax({
                type: 'GET',
                timeout: $settings.requestTimeout,
                url: $settings.databaseHandler_URLs.locationDetail,
                processData: true,
                data: {
                    locationID: encodeURI(id)
                },
                dataType: 'json',
                error: function(request, status, error) {

                    // 1.1. apresentar o erro
                    //alert('Error: ' + status);

                    // 1.2. esconder o loader
                    $loader.hide();

                    // 1.3. apresentar o icon de erro
                    CloseBecauseError();

                },
                success: function(data) {

                    // 1.1. Copiar para o $pickedID o ID da localização seleccionada
                    $pickedID.val(id);

                    // 1.2. carrego a localização
                    PickLocation(data, true);

                    // 1.3. esconder o loader
                    $loader.hide();                   

                }
            });

        });
        // ------------------------------------------------

        // ------------------------------------------------
        // > envia a nova localização para a o flash
        function TransferLocationToFlash(id) {

            if (_mapLoaded) {

                $dMapFlashDiv.externalInterface({
                    method: 'SendData',
                    param: id,
                    success: function(response) {
                        //  alert('flash says: ' + response);
                    },
                    error: function(error) {
                        _mapLoaded = false;
                        CloseBecauseError();
                    }
                });

            }

        };
        // ------------------------------------------------
        
        
        
        // ============================================================================================
        // ============================================================================================
        // ============================================================================================

        // @@ TOOLTIP

        // ============================================================================================
        // ============================================================================================
        // ============================================================================================
       
        var isIE;
        var tooltipTime;
       
        if ($.browser.msie != undefined) {
            isIE = true;
        } else {
            isIE = false;
        }
       
        var tooltipDelay = setTimeout(function(){
            Tooltip_Show(0);
            clearInterval(tooltipDelay);
        }, 2000);
                        
        function Tooltip_Hide() {
      
            if (isIE) { 
                $tooltip.hide(); 
            }
            else {
                $tooltip.fadeOut(2000);
            }
            
            
        };
        
        function Tooltip_HideAndShow(tooltipDepth) {

            if (isIE) { 
                $tooltip.hide(); 
                if (tooltipDepth >= 0) {
                    Tooltip_Show(tooltipDepth);
                }
            }
            else {
               $tooltip.fadeOut(function(){
                    if (tooltipDepth >= 0) {
                        Tooltip_Show(tooltipDepth);
                    }
                }); 
            } 
                
        };
        
        
        
        function Tooltip_Show(tooltipDepth) {

            var show = ($tooltip.children('span').eq(tooltipDepth).size() > 0);
                    
            $tooltip.children('span').hide();
            if (tooltipDepth != undefined) {
                if (show) {
                    $tooltip.children('span').eq(tooltipDepth).show(); 
                }
            }
                       
            if (isIE) { 
                if (show)    
                    $tooltip.show(); 
            }
            else {
                if (show)
                    $tooltip.fadeIn('slow');
            }
            
            // depois de um bocado, escondo
            tooltipTime = setTimeout(function(){
                Tooltip_Hide();
                clearInterval(tooltipTime);    
            }, 8000);
          
        };
        

        function GetCurrentLocationDepth() {
            
            var locationDepth = 0;
            var locationID = $pickedID.val();
            
            //setup location ID, remove initial and last /
            locationID = locationID.substr(1);
            locationID = locationID.slice(0,-1);
            
            var locationLevels = locationID.split('/');
            
            return locationLevels.length - 1;
        };


    });

};
})(jQuery);
























/* @ AUXILIAR PLUGINS
   ==================================================================== */

	// ------------------------------------------------
	(function ($) {
		$.fn.highlight = function(pat) {
			function innerHighlight(node, pat) {
				var skip = 0;
			 	if (node.nodeType == 3) {
			 		var pos = node.data.toUpperCase().indexOf(pat);
			 		if (pos >= 0) {
			 			var spannode = document.createElement('span');
			 			spannode.className = 'highlight';
			 			var middlebit = node.splitText(pos);
			 			var endbit = middlebit.splitText(pat.length);
			 			var middleclone = middlebit.cloneNode(true);
			 			spannode.appendChild(middleclone);
			 			middlebit.parentNode.replaceChild(spannode, middlebit);
			 			skip = 1;
			 		}
			 	}
			 	else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
			  		for (var i = 0; i < node.childNodes.length; ++i) {
			   			i += innerHighlight(node.childNodes[i], pat);
			  		}
			 	}
			 	return skip;
			}
			return this.each(function() {
				innerHighlight(this, pat.toUpperCase());
			});
		};
	})(jQuery);
	// ------------------------------------------------
	(function ($) {
	    $.fn.externalInterface = function (args) {
	        return this.each(function () {
	            if (typeof (args.method) != 'undefined') {
	                try {
	                    if (typeof (args.param) != 'undefined') {
	                        var data = this[args.method](args.param);                 
	                    }
	                    else {
	                        var data= this[args.method]();
	                    }
	                    if (typeof (args.success) != 'undefined') {
	                        args.success(data);
	                    }
	                }
	                catch (error) {
	                    if (typeof (args.error) != 'undefined') {
	                        args.error(error);
	                    }
	                }
	            }
	        });
	    };
	})(jQuery);
	// ------------------------------------------------




