// vim: sw=4:ts=4:nu:nospell

/**
 * HyperCities city Objects
 *
 * @author    Chen-Kuei Lee
 * @copyright (c) 2008, by HyperCities Tech Team
 * @date      2008-12-22
 * @version   0.7
 *
 */
 
HyperCities.city = function() {
    // do NOT access javascript generated DOM from here; elements don't exist yet
    
    // Private variable goes here
    var _id          = "[HyperCities.city] ";
    var _cities      = new Array();
    var _defaultZoom = 14;
    var _defaultRadius = 100000;

    // Private method goes here
    var _parseCities = function($data) {
        HyperCities.debug(_id + "Parse Cities");
        
        // loop for each match on Cities/City
        $($data).find("City").each( function () {

                var cityId = $("id", this).text();

                _cities[cityId] = { id      : cityId,
                                    name    : $("city", this).text(),
                                    country : $("country", this).text(),
                                    neLat   : parseFloat($("neLat", this).text()),
                                    neLon   : parseFloat($("neLon", this).text()),
                                    swLat   : parseFloat($("swLat", this).text()),
                                    swLon   : parseFloat($("swLon", this).text()),
                                    //zoom    : _defaultZoom,
                                    zoom    : parseInt($("zoom", this).text()),
                                    radius  : _defaultRadius,
                                    marker  : null,
                                    center  : new GLatLng(parseFloat($("lat", this).text()),
                                                          parseFloat($("lon", this).text())),
                                    defaultCenter : new GLatLng(parseFloat($("lat", this).text()), 
                                                                parseFloat($("lon", this).text())),
                                    thumbnailUrl : $("thumbnail_url", this).text(),
                                    description  : $("description", this).text(),
                                    timespan     : { max: Date.today().set({day: 31, month: 11, 
                                                                            hour:23, minute:59, second:59}), 
                                                     min: Date.today().addYears(-300) }
                                  };

            });
		
		HyperCities.miniMap.addCities(_cities);		
		// handle permalinks to cities
		// NOTE: Exit point at the end of this IF statement
		// The function will exit here if a permalink to a city has been found
		if (HyperCities.session.get('city') != null) {
			HyperCities.debug(_id + "Trying new city parsing method");
			// 06-12-09: Added workaround for Jan's trip to Chicago 
			/*if (HyperCities.session.get('city') == 'Chicago') {
				city = new Object();
				city.defaultCenter = new GLatLng(-41.88215088, -87.62781143);
				city.zoom = 14;
			}
			else {*/
				var city = HyperCities.city.getCityByName(HyperCities.session.get('city'));
				HyperCities.session.set("city", city);
			//}
			if (city == null) alert ("Invalid City Name.");
			else {
				HyperCities.debug(_id + "City found" + city.name);
				HyperCities.mainMap.setCenter(city.defaultCenter, city.zoom);
				//HyperCities.mainMap.setCenter(center, zoom);
				return;
			}
		}

        //HyperCities.debug(_cities);
        HyperCities.mainMap.addCities(_cities);
        

        // Adjust Layout and Do the first time Sync  
        HyperCities.adjustLayout();
		
    };

    // Render Error Message in intelliList
    var _renderError = function() {

        var itemWrapper = $(document.createElement("div"));
        itemWrapper.attr("id","intelliItem_error");
        itemWrapper.attr("class","intelliItem");

        var itemImg = $(document.createElement("div"));
        itemImg.attr("id","intelliImg_error");
        itemImg.attr("class","intelliImg");
        itemImg.html('<img src="./images/thumbError.gif" ALT="No Featured City Available" />');

        var itemTitle = $(document.createElement("div"));
        itemTitle.attr("id","intelliTitle_error");
        itemTitle.attr("class","intelliTitle");
        itemTitle.html("<strong>Oops!&nbsp;</strong> No Featured City Available");

        var itemText = $(document.createElement("div"));
        itemText.attr("id","intelliText_error");
        itemText.attr("class","intelliText");
        //itemText.html("We don't have feature city for this region. Try zooming out for a broader look, or choosing one of our feature city from above mini map.");
        itemText.html("There are no featured cities in view. Try zooming out for a broader look, or choosing a featured city from the mini map.");

        itemWrapper.append(itemImg).append(itemTitle).append(itemText);
        $("#intelliList").append(itemWrapper);

    };

    var _clickCityItem = function() {
        var item = $(this);
        //HyperCities.debug("typeof(item)="+typeof(item));
        var cityId = item.attr('id').split('_')[1];

        HyperCities.debug(_id + "Click City Item " + item.attr('id'));
        GEvent.trigger(HyperCities.city.getMarker(cityId), "click"); 
    };

    return {
        
        // Initialize the city object
        init: function() {
            
            // Get city list and call _parseCities to render cities on mini map
            $.post("./citiesList.php", { func: "city.init" }, _parseCities, "xml");

        },

        setZoom: function($cityId, $zoom) {
            if( (typeof(_cities[$cityId]) === "undefined" ) || (typeof($zoom) !== "number" ) )
                return;

            _cities[$cityId].zoom = $zoom;
            //HyperCities.debug(_cities[$cityId]);
        },

        setCenter: function($cityId, $center) {
            if( (typeof(_cities[$cityId]) === "undefined" ) || (typeof($center) !== "object" ) )
                return;

            _cities[$cityId].center = $center;
            //HyperCities.debug(_cities[$cityId]);
        },

        // set marker object of the city
        setMarker: function($cityId, $marker) {
            if( (typeof(_cities[$cityId]) === "undefined" ) || (typeof($marker) !== "object" ) )
                return;

            _cities[$cityId].marker = $marker;
        },

        getMarker: function($cityId) {
            return (typeof(_cities[$cityId]) === "undefined" ) ? null : _cities[$cityId].marker;
        },

        // return the _cities array
        getCities: function() {
            return _cities;
        },

        // return the city object by given Id
        getCity: function($cityId) {
            return (typeof(_cities[$cityId]) === "undefined" ) ? null : _cities[$cityId];
        },
		
		getCityByName: function ($name) {
			HyperCities.debug(_id + "Getting City for " + $name + ".");
			for (i in _cities) {
				if (_cities[i].name == $name) return _cities[i];
			}
			return null;
		},

        // return the city object that cloest to the given point
        findCity: function($GLatLon) {

            var targetId    = null;
            var minDistance = null;
            var distance    = 0;

            if (typeof($GLatLon) !== 'object' )
                return;

            for( var i in _cities) {
                distance = $GLatLon.distanceFrom(_cities[i].defaultCenter);
                if ( (minDistance === null) || (distance < minDistance) ) { 
                    minDistance = distance;
                    targetId = i;
                }
            }

            if ( ( minDistance > _cities[targetId].radius ) && 
                 !HyperCities.mainMap.inMap(_cities[targetId].defaultCenter))
                return null;

            return _cities[targetId];
        },

        // render the city list to intelliList
        //jay
        renderList: function($bounds){

            HyperCities.debug(_id + "Render City List");
            HyperCities.intelliList.reset();

            for( var i in _cities ) {

				// Do not show the city in list if it's out of view or intended to hide
                if ( !HyperCities.mainMap.inMap(_cities[i].defaultCenter, $bounds) ||
					 ($.inArray(_cities[i].id, HyperCities.config.HIDDEN_CITIES) >= 0 )	)
                    continue;

                var itemWrapper = $(document.createElement("div"));
                itemWrapper.attr("id","intelliItem_"+i);
                itemWrapper.attr("class","intelliItem");
               
                var itemImg = $(document.createElement("div"));
                itemImg.attr("id","intelliImg_"+i);
                itemImg.attr("class","intelliImg");
                itemImg.html('<img src="'+_cities[i].thumbnailUrl+'" ALT="'+_cities[i].name+'" />');

                var itemTitle = $(document.createElement("div"));
                itemTitle.attr("id","intelliTitle_"+i);
                itemTitle.attr("class","intelliTitle");
                itemTitle.html("<strong>"+_cities[i].name+"</strong> "+_cities[i].country);

                var itemText = $(document.createElement("div"));
                itemText.attr("id","intelliText_"+i);
                itemText.attr("class","intelliText expand");
                itemText.html(_cities[i].description);

                itemText.wordWraps();
                itemWrapper.append(itemImg).append(itemTitle).append(itemText);

                // add event listener on item click
                itemWrapper.click(_clickCityItem);

                // add event listener on item hover
                itemWrapper.mouseover( function() {
                            var cityId = $(this).attr('id').split('_')[1];

                            GEvent.trigger(HyperCities.city.getMarker(cityId), "mouseover");
                        });
                itemWrapper.mouseout( function() {
                            var cityId = $(this).attr('id').split('_')[1];

                            GEvent.trigger(HyperCities.city.getMarker(cityId), "mouseout");
                        });

                $("#intelliList").append(itemWrapper);

                // Compute Height after DOM inserted, add expand link if necessary
                // itemText.attr("debug", itemWrapper.height());
                if ( itemWrapper.height() > 64 ) {
                    //HyperCities.debug(_id+"Need Expand link");

                    // Add Link
                    var itemExpand = $(document.createElement("div"));
                    itemExpand.attr("id","intelliExpand_"+i);
                    itemExpand.attr("class","intelliExpand");
                    itemExpand.html('<b>...</b> (<a href="#">more info</a>)');
                    itemWrapper.append(itemExpand);

                    // Bind Event Listener
                    itemExpand.click(HyperCities.intelliList.toggleIntelliText);
                }

                // Hide all intelliText beyond 3rd line
                itemText.removeClass("expand");
            }
            
            var allCities   = $(".intelliItem");
            var totalCities = allCities.length;

            if ( totalCities == 0 )
                _renderError();
                
            // Sort intelliItem Base on alphabetical ordering
            var sortMaps = $(".intelliItem").get();
            sortMaps.sort(function (a, b){ 
                    var keyA = $(a).children(".intelliTitle").text();
                    var keyB = $(b).children(".intelliTitle").text();
                    if (keyA < keyB) return -1
                    if (keyA > keyB) return 1
                    return 0 
                    });
            $.each(sortMaps, function(index, row) {
                    $("#intelliList").append(row);
                    });

            $("#mapTab").html("City ("+ totalCities +")");
            HyperCities.intelliList.render($(".intelliItem"));
        }
    };
}(); // end of Object

// end of file
