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

/**
 * HyperCities Main Application
 *
 * @author    Chen-Kuei Lee
 * @copyright (c) 2008, by HyperCities Tech Team
 * @date      2008-12-12
 * @version   0.7
 *
 */

// create applicatio namespace


HyperCities = function() {
    // do NOT access javascript generated DOM from here; elements don't exist yet

    // private variables
    var _id      = "[HyperCities] ";
    var MAP_WIDTH = 315 ;
    var SIDEBAR_WIDTH = 315 ;

    // private functions

    // check browser cookie is enabled
    var _checkEnv = function() {

		var isIE = false;
		jQuery.each(jQuery.browser, function(i, val) {
				if (i == "msie" && val == true) isIE = true;
			});

        if (!navigator.cookieEnabled) {
            $("#warningMessage").html("You must enable Cookies!");
            return false;
		} else if (isIE) {
			$("#warningMessage").html('HyperCities is optimized to work in Firefox or Safari.<br/> If you do not have Firefox installed, you can download it <a href="http://www.mozilla.com/firefox">here</a>.');
			return false;
        } else if (!GBrowserIsCompatible()) {
            $("#warningMessage").html("Sorry, your broswer is not GMap Compatible!");
            return false;
        } else // Remove the Javascript warning message since we can execute js
            $("#warningMessage").remove();

        return true;
    };

    // Add Event Listener to the sidebar tab
    var _initSideBarTabs = function() {

        $("#sidebarWrapper:first").resizable({
                handles: "w",
                helper: "proxy",
                resize: function(e, ui) {
                    var defaultWidth  = SIDEBAR_WIDTH;
                    var mapWidth      = MAP_WIDTH;
                    var tolerance     = 100;
                    var viewportWidth = $(window).width();

                    if ( ui.size.width < defaultWidth ) { // Sidebar too small, close sidebar
                        ui.helper.css("left",'');

                        if ( ((ui.originalSize.width < defaultWidth) && (ui.size.width > tolerance)) ||
                             ((ui.originalSize.width >= defaultWidth) && (ui.size.width >= (defaultWidth - tolerance))) ) {
                            ui.helper.css("right", defaultWidth + "px");
                        } else {
                            ui.helper.css("right", "0px");
                        }

                        ui.helper.css("border-left", "0px");
                        ui.helper.css("border-right", "6px solid #CCCCCC");
                    } else if ( viewportWidth - ui.size.width < mapWidth ){ // Map too small, close map
                        if ( ((ui.originalPosition.left < mapWidth) && (ui.position.left > tolerance )) ||
                             ((ui.originalPosition.left >= mapWidth) && (ui.position.left >= (mapWidth - tolerance))) ) {
                            ui.helper.css("left", mapWidth + "px");
                        } else {
                            ui.helper.css("left", "0px");
                        }

                        ui.helper.css("border-left", "6px solid #CCCCCC");
                        ui.helper.css("border-right", "0px");

                    } else {
                        ui.helper.css("border-left", "6px solid #CCCCCC");
                        ui.helper.css("border-right", "0px");
                    }
                },

                stop: function(e, ui) {
                    var defaultWidth  = SIDEBAR_WIDTH - 5;
                    var mapWidth      = MAP_WIDTH;
                    var tolerance     = 100;
                    var viewportWidth = $(window).width();

                    $(this).css("height",'');
                    $(this).css("left",'');
                    $(this).css("position",'');
                    $(".ui-resizable-handle").css("width", "6px");
                    if ( $(this).width() < defaultWidth ) {
                        if ( ((ui.originalSize.width < defaultWidth) && (ui.size.width > tolerance)) ||
                             ((ui.originalSize.width >= defaultWidth) && (ui.size.width >= (defaultWidth - tolerance))) ) {
                            $(this).css("width", defaultWidth + "px");
                        } else {
                            $(this).css("width","0px");
                            $(".ui-resizable-handle").css("width", "10px");
                        }
                    } else if ( ui.position.left < mapWidth ) {
                        if ( ((ui.originalPosition.left < mapWidth) && (ui.position.left < tolerance )) ||
                             ((ui.originalPosition.left >= mapWidth) && (ui.position.left <= (mapWidth - tolerance))) ) {
                            $(this).css("width", viewportWidth - 10 + "px");
                        } else {
                            $(this).css("width", viewportWidth - mapWidth - 10 + "px");
                        }
                    }

                    HyperCities.adjustLayout();
                }
        });

        $("#worldMapTab").click(function () {
                $(this).blur();

                if ( $(this).parent().hasClass('highlight') ) return false;

                // set up the selected class
                $(".topTab").removeClass('highlight');
                $(this).parent().addClass('highlight');

                $("#loadingMessage").fadeIn("fast");
		
		
                $("#topPanel").fadeOut("normal", function() {
                    $("#worldMapPanel").fadeIn("normal", function() {
                            $("#loadingMessage").fadeOut("slow");
                        });
                    });
            });

        $("#searchTab").click(function () {
                $(this).blur();

                if ( $(this).parent().hasClass('highlight') ) return false;

                // set up the selected class
                $(".topTab").removeClass('highlight');
                $(this).parent().addClass('highlight');

                $("#loadingMessage").fadeIn("fast");
                $.ajax( { url: "searchForm.html",
                          cache: false,
                          success: function(message) {
                              $("#topPanel").fadeOut("normal", function() {
                                  $("#worldMapPanel").fadeOut("normal", function() {
                                      $("#topPanel").empty().append(message).fadeIn("normal", function() {
                                          // enable search function
                                          if ( $("#gotoBtn").length > 0 ) {
                                              $("#gotoBtn").click(HyperCities.search.searchAddress);
                                              $("#address").focus();
                                          }

                                          if ( $("#keywordSearchForm #resetBtn").length > 0 ) {
                                              $("#keywordSearchForm #resetBtn").click(HyperCities.search.resetKeyword);
                                          }

                                          if ( $("#keywordSearchForm #searchBtn").length > 0 ) {
                                              $("#keywordSearchForm #searchBtn").click(HyperCities.search.searchKeyword);
                                          }

                                          $("#loadingMessage").fadeOut("slow");
                                      });
                                  });
                              });
                          }
                        });
            });

        $("#loginTab").click(function () {
                $(this).blur();

                if ( $(this).parent().hasClass('highlight') ) return false;

                // set up the selected class
                $(".topTab").removeClass('highlight');
                $(this).parent().addClass('highlight');

                $("#loadingMessage").fadeIn("fast");
                $.ajax( { url: "loginForm.php",
                          cache: false,
                          success: function(message) {
                              $("#topPanel").fadeOut("normal", function() {
                                  $("#worldMapPanel").fadeOut("normal", function() {
                                      $("#topPanel").empty().append(message).fadeIn("normal", function() {

                                          HyperCities.user.init();

                                          $("#loadingMessage").fadeOut("slow");
                                      });
                                  });
                              });
                          }
                        });
            });

        $("#mapTab").click(function () {
                $(this).blur();

                var latLonBox, zoom;

                latLonBox = HyperCities.mainMap.getBounds();
                zoom = HyperCities.mainMap.getZoom();

                if ( $(this).parent().hasClass('highlight') ) return false;

                // set up the selected class
                $(".intelliTab").removeClass('highlight');
                $(".intelliTab span").unbind().remove();
                $(this).parent().addClass('highlight');

                $("#loadingMessage").fadeIn("fast");
                $("#intelliList").fadeOut("normal", function() {
                        HyperCities.intelliList.reset();
                        $("#intelliList").show();
                        HyperCities.mapList.update(latLonBox, zoom, true);
//                      HyperCities.mapList.update({bounds: latLonBox, zoom: zoom, renderList: true});
                    });

                return false;
            });

        $("#collectionTab").click(function () {
                $(this).blur();

                var latLonBox, zoom;

                latLonBox = HyperCities.mainMap.getBounds();
                zoom = HyperCities.mainMap.getZoom();

                if ( $(this).parent().hasClass('highlight') ) return false;

                // set up the selected class
                $(".intelliTab").removeClass('highlight');
                $(this).parent().addClass('highlight');

                $("#loadingMessage").fadeIn("fast");
                $("#intelliList").fadeOut("normal", function() {
                        HyperCities.intelliList.reset();
                        $("#intelliList").show();
                        HyperCities.collectionList.update(latLonBox, zoom, true);
                        /*
                        $("#intelliList").append("Load Collection List Here").fadeIn("normal", function() {
                            $("#loadingMessage").fadeOut("slow");
                        });*/
                    });

                return false;
            });

        $("#intelliSync").bind("click", function($event) {
                $(this).toggleClass("syncMap");

              HyperCities.collectionList.syncWithMap($(this).hasClass("syncMap"));

              HyperCities.mapList.syncWithMap($(this).hasClass("syncMap"));
            });

        // Hide Tool Panel When Mouse Leave
        $("#toolPanelWrapper").bind("mouseleave", function ($event) {
    //            $(this).fadeOut();
            });
        $("#loadingMessage").click(function ($event) {
            setTimeout (function () {
                $("#loadingMessage").fadeOut("normal");
            }, 5000);
        })
    };

    var _initTimebar = function()
    {
    	var result = HyperCities.timebar.init($("#timebarWrapper"));

		if (!result)
		{
			var errorMessage = "<table width='100%' height='100%'><tr><td align=center valign=center>";
			errorMessage += "Do not have correct Adobe Flash Player version.<br><br>";
			errorMessage += "Please download Adobe Flash Player:<br><a href='http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash' target='_blank'>http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash</a><br>";
			errorMessage += "</td></tr></table>";

			$('#warningMessage').html(errorMessage);
		}
    };

    // public space
	return {
		// public properties
		config: {},			// HyperCities Global Configuration
		mainMap: {},        // Main Google Map Object Wrapper
		miniMap: {},        // World Map Object Wrapper
		mapList: {},        // MapList Wrapper
		intelliList: {},    // IntelliList Wrapper
		dhtmlWindow: [],	// HTML Window For Image Display
		dhtmlManager: null, // HTML Window Manager For Image Display
		dhtmlStacked: 0,    // HTML Window Stack Counter For Image Display
		city: {},           // City List Object Wrapper
		session: {},
		search: {},
		group: {},
		user: {},
                // David, 07-20-09: 'Permalink' name changed to 'linkController'
                // because it manages more than permalinks.
                linkController: {}, // Handles permalinks and URL bar

        // public methods
        init: function() {
            try {

                // Check necessary environments were enabled (Javascript & Cookie)
                if (!_checkEnv()) return;

                // Checkout Session Variable to get default Value
                HyperCities.getDefault();

				// Instantiate and configure YUI Loader:
			    var yuiLoader = new YAHOO.util.YUILoader({
								        base: "http://ajax.googleapis.com/ajax/libs/yui/2.6.0/build/",
								        require: ["container","dragdrop","resize","slider"],
								        loadOptional: true,
								        combine: false,
								        filter: "MIN",
								        allowRollup: true,
								        onSuccess: function() {}
						    });
			    // Load the files using the insert() method.
			    yuiLoader.insert();
				
				//init user data, this must be done first because following steps requires user infomation
				HyperCities.user.sync();

                // Permalink handling
                // David, 07-16-09: Permalink is handled in a separate pseudo-thread
                // which is initialized by HyperCities.linkController.init();
                HyperCities.linkController.init();
                // Init GMap
                // Example: HyperCities.mainMap.init("#map", {lat:34.070826, lng: -118.463646, zoom:7});
                HyperCities.mainMap.init("#map");
                HyperCities.miniMap.init("#worldMapPanel");

                // Init city object to get feature city list
                HyperCities.city.init();

                // Init Sidebar Tabs
                _initSideBarTabs();

                // Highlight the default Tab
                var url = document.location.toString();
                var tabAnchor = "#worldMapTab";           // Default Tab is World Map
                if ( url.match('#') ) {                   // check if the URL contains an anchor
                    tabAnchor = url.split('#')[1];

                    if ( $('#' + tabAnchor + "Tab").length > 0 )
                        tabAnchor = '#' + tabAnchor + 'Tab';
                    else
                        tabAnchor = "#worldMapTab";
                }

                $(tabAnchor).click();

                //initial timebar
                _initTimebar();
				
                //initialize style marker by calling labeledMarker contructor
				var markeroptions = {};
				var icon = G_DEFAULT_ICON;
				var icontype = "style";

				if (icontype == "style") {
					icon.image = 'images/HCMarker.png';
					//icon.iconSize = new GSize(24, 32);
					icon.iconSize = new GSize(40, 50);
					icon.iconAnchor = new GPoint(12, 32);
					icon.shadow = "images/HCMarkerShadow.png";
					icon.shadowSize = new GSize(53, 36);
					icon.infoWindowAnchor = new GPoint(16, 6);
					icon.imageMap = [0,0, 50,0, 50,50, 0,50];
					markeroptions.labelOffset = new GSize(-3, -19);
				}

				markeroptions.clickable = true ;
				var m = new LabeledMarker(new GLatLng(0, 0), markeroptions);
				
				// Permalink handling
				// David, 07-16-09: version 2.0
				// Permalink is handled in a separate pseudo-thread
                                HyperCities.linkController.init();
				
            }
            catch(e) {
                alert(e);
            }
        },

        // Adjust the layout by current viewport
        adjustLayout: function($opt) {

			var options = $opt || {};
			var doSync  = true;

            var viewportHeight = $(window).height();
            var viewportWidth  = $(window).width();
            var intelliListTop = $("#intelliListWrapper").position().top;
            var paddingButtom  = 5;
            var sidebarWidth   = $('#sidebarWrapper').width();
            var timebarHeight  = $('#timebarWrapper').height();

            $('#intelliListWrapper').css("height", viewportHeight - intelliListTop - paddingButtom);
            $('#intelliListWrapper > .jScrollPaneContainer').css("width", "auto");
            $('#intelliList').css("height", viewportHeight - intelliListTop - paddingButtom);
            if ( viewportWidth - sidebarWidth - 10 < MAP_WIDTH ) {
                sidebarWidth = SIDEBAR_WIDTH;
			}
            $('#contentWrapper').css("right", sidebarWidth + 10 + "px");
            $('#GTimeControl').css("width", (viewportWidth - sidebarWidth - 230) + "px");
            $('#GTCSlider').css("width", (viewportWidth - sidebarWidth - 345) + "px");
			$('#map').css("min-height", (viewportHeight - timebarHeight) + "px");
			$('#map').css("height", (viewportHeight - timebarHeight) + "px");

            HyperCities.mainMap.checkResize();

			if ( typeof(options.sync) === "boolean" ) {
				if ( options.sync === false ) {
					doSync = false ;
				}
			}

			if ( HyperCities.session.get("mode") === HyperCities.config.MODE_NARRATIVE ) {
				doSync = false ;
				HyperCities.narrativePanel.checkResize();
			}

			if ( doSync ) {
	            HyperCities.syncSession();
			}
        },

        getDefault: function() {
            HyperCities.util.debug(_id + "Get Default value from server session variable");

            // Disable MapSync By default
            $("#intelliSync").removeClass("syncMap");

			// Find Client Geo Location
			if (google.loader.ClientLocation) {
//				HyperCities.util.debug("visitor_lat = "+google.loader.ClientLocation.latitude);
//				HyperCities.util.debug("visitor_lon = "+google.loader.ClientLocation.longitude);
//				HyperCities.util.debug("visitor_city = "+google.loader.ClientLocation.address.city);
//				HyperCities.util.debug("visitor_region = "+google.loader.ClientLocation.address.region);
//				HyperCities.util.debug("visitor_country = "+google.loader.ClientLocation.address.country);
//				HyperCities.util.debug("visitor_countrycode = "+google.loader.ClientLocation.address.country_code);
			}
 
        },

        syncSession: function() {

            HyperCities.util.debug(_id + "Doing Sync Here");
			var latLonBox, zoom, center, timespan;
			

			center = HyperCities.mainMap.getCenter();	
            latLonBox = HyperCities.mainMap.getBounds();
            zoom      = HyperCities.mainMap.getZoom();
			
			 timespan = HyperCities.mainMap.getTimespan();	
		
			 if(!HyperCities.session.isEqualSession(latLonBox,timespan))	{

			try{
				// Previous timespan and bounds
				var previousTimespan = HyperCities.session.get("currentTimespan"),
					previousLatLonBox = HyperCities.session.get("currentBounds");


				
				
				// If the current bounds is different from the previuos one, then store it.
				HyperCities.session.set("currentBounds", latLonBox);	
					
					//For debugging purposes
				HyperCities.debug("Changed bounds from:  "+previousLatLonBox+" to "+latLonBox);
				HyperCities.session.set("currentTimespan", timespan);
					
				// For debugging
				var previousMin = previousTimespan.min,  previousMax = previousTimespan.max;
				
					HyperCities.debug("Changed timespan from: "+previousMin+" to "+timespan.min+", and "+previousMax+" to "+timespan.max+".");
 			
			
				}catch(e){
					HyperCities.debug("Error in syncing: "+e);

				}	
		
				// Update _zoom and _center
			   
			try{
					HyperCities.session.set("center", center);
					HyperCities.session.set("zoom",zoom);	
			}catch(e){
				HyperCities.debug("Error in setting zoom and center!");
			}
				//HyperCities.debug("latLonBox.getSouthWest() ="+latLonBox.getSouthWest() );
				//HyperCities.debug("latLonBox.getNorthEast() ="+latLonBox.getNorthEast() );
				//HyperCities.debug("zoom="+zoom);
			//HyperCities.util.debug("latLonBox.getSouthWest() ="+latLonBox.getSouthWest() );
			//HyperCities.util.debug("latLonBox.getNorthEast() ="+latLonBox.getNorthEast() );
			//HyperCities.util.debug("zoom="+zoom);
            // Sync City Information based on current View and Zoomlevel
				if ( zoom >= HyperCities.config.ZOOM_THRESHOLD )
                	HyperCities.session.set("city", HyperCities.city.findCity(HyperCities.mainMap.getCenter()));
           		 else
                	HyperCities.session.set("city", null);

            // Update Map List / Collection List
            	if (HyperCities.session.get("mode") !== HyperCities.config.MODE_NARRATIVE) {
                if ( $("#mapTab").parent().hasClass('highlight') ) { // Update Map List
    //				HyperCities.util.debug(_id + "Update Map List");
                    HyperCities.mapList.update(latLonBox, zoom, true, true);
                }
                else if ( $("#collectionTab").parent().hasClass('highlight') ) { // Update Collection List
    //				HyperCities.util.debug(_id + "Update Collection List");
                                    HyperCities.mapList.update(null, null, false); // Update Map List, but no render
                    HyperCities.collectionList.update(latLonBox, zoom, true);
                }
            }



			} // end if for the duplicate session checking.
			else{
				HyperCities.debug("Same session, did not sync");
			}
        },

        // David, 08-25-09: Possible candidate for inclusion in HyperCities.util object
        freeze: function () {
            $("#loadingMessage").fadeIn("fast");
        },

        unfreeze: function () {
            $("#loadingMessage").fadeOut("slow");
        },

        // This function is deprecated, use HyperCities.util.debug instead.
		// Keep for backward compatibility.

        debug: function($obj) {
			/*
            if (window.console && window.console.log) {
                window.console.log("Warning: HyperCities.debug() is deprecated, use HyperCities.util.debug() instead.");
			}
			*/
			HyperCities.util.debug($obj);
        },

        // detach all the event listeners and unload Google Map resources
        unload: function() {
            if(GUnload) {
                GUnload();
			}
        }
    };
}(); // end of application

// initialize application when DOM is ready
$(document).ready(HyperCities.init);

// Reset Layout when window resize
$(window).resize(HyperCities.adjustLayout);

// free GMap resources and event listeners
$(window).unload(HyperCities.unload);

// end of file
