/**
 * @fileoverview This script offers all needed methods to put
 * Google Maps Marker into a category. You can then hide and
 * show Marker in a specific category
 * 
 * @version 1.0
 * @author Ihsan Baris Bikmaz (namics ag)
 * @requires jquery
 */
 
 
	/* GLOBALS TO MAKE A XHR CALL ONLY ONE TIME */
	var blnPoisLoaded 	= blnReportsLoaded = false;
	var mapCategory 	= new Category();
		
	/**
	 * Creates a new category object to handle 
	 * marker which belong to different categories.
	 * 
	 * @class Category
	 * @constructor
	 */	

	function Category()
	{
		mySelf				= this;
		this.gmarkers 		= {};				// contains all marker
		this.iMarkerCount 	= 0;
		this.selectedMarkers= {};		// contains only selected marker
		
		this.init = function( jsonMarkers )
		{
			mySelf.gmarkers 	= new Array();
			mySelf.gmarkers 	= jsonMarkers;
			mySelf.iMarkerCount = jsonMarkers.length;
		}
	}
	
	
	/**
	 * This function shows a spefific point that has
	 * a unique id.
	 * 
	 * @class Category
	 * @param {string}	
	 * 		ID of the marker
	 * @return { GMarker }
	 * 		Found Google Maps Marker
	 */	
	Category.prototype.showPointWithID = function( intID )
	{
		var arrCollect  		= new Array();
		var i 					= this.iMarkerCount - 1;
		var myMarker			= null;
		var foundMarker			= null;
		this.selectedMarkers	= new Array();
		
		
		if ( i < 0 ) return;
		do{
			myMarker = this.gmarkers[i];
			if ( intID == myMarker.id )
			{
				// if marker already added to the map
				if ( myMarker.inMap == true )
          			myMarker.show();
          		else
          		{
					arrCollect.push( myMarker );
					localVar.mapGlobal.addOverlays( arrCollect );					
          		}
				var latLng = myMarker.getLatLng();
		 		localVar.mapGlobal.setCenter(latLng);
		 		foundMarker = myMarker;		 		
			}
			else if ( myMarker.inMap == true )
			{
          		myMarker.hide();
			}

        }while( i-- );			
        
        return foundMarker;
	}


	/**
	 * This function shows all marker in the given categories.
	 * Here we make an AND to all selected categories. This means
	 * The marker must be in all the selected categories
	 *
	 * @class Category
	 * @param {array}	
	 * 			Name of the categories and values
	 * 			['color'][0] = red; [color][1] = green
         * @param rezoom
         *                      true if map should rezoom, if false the standard zoom is used
	 */	
	Category.prototype.showCategory = function (arrCategories, rezoom)
	{  
            if(typeof rezoom=="undefined"){
                rezoom = true;
            }
		var arrCollect  		= new Array();
		var i 					= this.iMarkerCount - 1;
		var bounds 				= new GLatLngBounds;		
		var maxLng, minLng; 
		var maxLat, minLat;
				
		this.selectedMarkers	= new Array();		
		maxLng = maxLat = 0
		minLng = minLat = 10000;
		
		if ( i < 0 ) return;
		do{
			var blnAcceptMarker = false;

			for (var x in arrCategories)
			{ 
                             
				if ( arrCategories[x].inArray( this.gmarkers[i][x] ) )
				{ 
                                     blnAcceptMarker = true;
                                     //eclude pois in france
//                                     if(this.gmarkers[i].state == "F"){
//					 blnAcceptMarker = false;
//                                         break;
//                                     }
				}else{
					 blnAcceptMarker = false;
					 break;
				}
			}
			
			// if marker is in category
          	if ( blnAcceptMarker )
		    {
		    	this.selectedMarkers.push( this.gmarkers[i] );

		  		if (this.gmarkers[i].inMap != true)
		  		{
	  				this.gmarkers[i].inMap = true;
	  				arrCollect.push(this.gmarkers[i])
	  			}
	  			else
	  			{
        			this.gmarkers[i].show();
	  			}	  			  			 
				bounds.extend(this.gmarkers[i].getPoint());
 
	        }
	        else
	    	{
	    		if (this.gmarkers[i].inMap == true) this.gmarkers[i].hide();
	    	}
	        
        }while( i-- );
        
		// add Marker to the map
        localVar.mapGlobal.addOverlays( arrCollect );
         
        // check the zoom level and center map
        // if Zoomlevel is higher the swiss than
        // zoom down to swiss.
        var intZoomLevel = localVar.mapGlobal.getBoundsZoomLevel(bounds);
        if (intZoomLevel > 7) intZoomLevel = 7;
        
        if(rezoom){
            if ( intZoomLevel < (localVar.centerCoords[2] -1 ))
                    localVar.mapGlobal.setCenter(new GLatLng(localVar.centerCoords[0],localVar.centerCoords[1]),localVar.centerCoords[2]);
            else
                    localVar.mapGlobal.setCenter(bounds.getCenter(),intZoomLevel); 
	} else{localVar.centerCoords
            localVar.mapGlobal.setCenter(new GLatLng(localVar.centerCoords[0],localVar.centerCoords[1]),localVar.centerCoords[2]);
        }
    }

	/**
	 * This function shows all marker in the current map..
	 */
	Category.prototype.showAllMarker= function ()
	{
		var arrCollect  		= new Array();
		var i 					= this.iMarkerCount - 1;
		
		this.selectedMarkers	= new Array();	

		
		if ( i < 0 ) return;
		do{

		    this.selectedMarkers.push( this.gmarkers[i] );

	  		if (this.gmarkers[i].inMap != true)
	  		{
  				this.gmarkers[i].inMap = true;
  				arrCollect.push(this.gmarkers[i])
  			}
  			else
  			{
    			this.gmarkers[i].show();
  			}	  			  			 
 
        }while( i-- );
        
		// add Marker to the map
        localVar.mapGlobal.addOverlays( arrCollect );
       	localVar.mapGlobal.setCenter(new GLatLng(localVar.centerCoords[0],localVar.centerCoords[1]),localVar.centerCoords[2]);

	}


	/**
	 * This function hides all marker in the current map..
	 */
	Category.prototype.hideAllMarker = function ()
	{
		if (typeof this.gmarkers == 'undefined') return;
		
		var markers = this.gmarkers;
		var i 		= markers.length - 1;
		
		do{
            markers[i].hide();
        }while( i-- );
	}
	
		
	/**
	 * This function shows the selected marker.
	 * 
	 */		
	Category.prototype.showSelectedMarker = function ()
	{
		var arrCollect  = new Array();
		var mLength 	= this.selectedMarkers.length - 1;
		
		for (i = 0; i <= mLength; i++)
		{
			if (this.selectedMarkers[i].inMap != true)
			{
				this.selectedMarkers[i].inMap = true;
				arrCollect.push(this.selectedMarkers[i])
			}
			else
			{
				this.selectedMarkers[i].show();
			} 	
        }
        
        localVar.mapGlobal.addOverlays( arrCollect );
	}
	
	
	/**
	 * This function hides all marker in the same category.
	 * @param {string}
	 * 		Name of the category
	 * @param {string}
	 * 		Value of the category
	 * 
	 * @example hideCategory('animals', 'cat')
	 */	
	Category.prototype.hideCategory = function (catName, catValue)
	{
		var gmarkers = localVar.markers;
		var i 		 = gmarkers.length - 1;
		
		do{
          if (gmarkers[i][catName] == catValue)
		  {
            gmarkers[i].hide();
          }
        }while( i-- );
	}
		

	/**
	 * This function maps the name of category fields
	 * to names which accept the icon.
	 * @param {string}
	 * 		Name of the category
	 * @return {string}
	 * 		Mapped name
	 */	
	Category.prototype.mapCategoryName = function( sName )
	{
		sName = sName.toUpperCase();
		var hashMapCategory = {
			'EIGEN'	        : '0',
			'WASSER'        : '1',
			'KERN'		: '2',
			'DE'		: 'Deutschland',
			'_F'		: 'Frankreich',
			'AG'		: 'Aargau',
			'ZH'		: 'Z&uuml;rich',
			'SO'		: 'Solothurn',
			'ZG'		: 'Zug',
			'UR'		: 'Uri',
			'LU'		: 'Luzern',
			'SG'		: 'St. Gallen',
			'SH'		: 'Schaffhausen',
			'GR'		: 'Graub&uuml;nden',			
			'BE'		: 'Bern',
			'SZ'		: 'Schwyz',
			'OW'		: 'Obwalden',
			'VS'		: 'Wallis',
			'TI'		: 'Tessin',
			'TG'		: 'Thurgau',
			'GL'		: 'Glarus',
			'NW'		: 'Niedwalden',
			'FR'		: 'Freiburg',
			'BL'		: 'Basel-Landschaft',
			'BS'		: 'Basel-Stadt',
			'VD'		: 'Waadt',
			'GE'		: 'Genf',
			'NE'		: 'Neuenburg',
			'AR'		: 'Appenzell Ausserrhoden',
			'AI'		: 'Appenzell Innerrhoden'			
		}
		
		var cName = hashMapCategory[sName];
		if(cName!=null && cName != "")
		{
			return cName;
		}
		
		return sName;
	}


	
	// ============================================================================================
	// Bindings
	// ============================================================================================

	/**
	 * Bind events to the buttons. To change the
	 * performed action by clicking on button
	 * change these functions..	
	 * 
	 */	
	function load_Bindings()
	{
		// make labels clickable
		$('label').click( function() { click_Label(this) } );
		
		objParent = $("#poiselection");
		
		// check all when loading site
		$(":checkbox", objParent).each( function(){
			this.checked = true;
		});
		
		// bind functions
		$(":checkbox", objParent).click( function() 
		{
			showSelectedMarker();
			if (GLOBALS.blnAllFilled == false) fillCompanyDropDown( 'all' );
			$("#sel_kanton").get(0).selectedIndex = 0;
			$("#sel_kraftwerk").get(0).selectedIndex = 0;
					
		});
		
		// Drop down Kanton
		$("#sel_kanton").change( function()
		{	 	
			ew.hide();// close if an info window is open
			var arrCategory = {};
			arrCategory['state'] = new Array;
			var selectedValue = this.options[ this.selectedIndex ].value;
			if (selectedValue == 'all')
			{
				mapCategory.showAllMarker();
			}
			else
			{
				arrCategory['state'].push( selectedValue );
				mapCategory.showCategory( arrCategory );
			}
			fillCompanyDropDown( selectedValue );
		});
		
		// Drop down Kraftwerk
		$("#sel_kraftwerk").change( function()
		{       
                        // not necessary because google closes the other windows before opening a new one
			//ew.hide();		// close if an info window is open
			var myMarker;
			var selectedValue = this.options[ this.selectedIndex ].value;
                         
			if (selectedValue == 'all') 
			{       
                            if($("#sel_kanton").get(0).value == 'all'){
                                showSelectedMarker();
                            }else{
				var objSelect = $("#sel_kanton").get(0);
				selectedValue = objSelect.options[objSelect.selectedIndex].value;
				var arrCategory = {};
				arrCategory['state'] = new Array( selectedValue );
                                ew.hide();
                                mapCategory.showCategory( arrCategory );
                            }
                                 
                            fillCompanyDropDown( selectedValue );
                            return;
			}
			
			myMarker = mapCategory.showPointWithID( selectedValue );
			GEvent.trigger(myMarker, "click");
		});
	}
		
	
	// ============================================================================================
	// Extended functions for specific projects
	// ============================================================================================

	/**
	 * Fills the dropdowns with the specific values
	 * 
	 */		
	function fillDropDowns()
	{
		// pois is a global variable containing the poi data
		var iLength 	= pois.length;		
		var poiState, poiCompany;
		var arrStates 	= new Array();
		var iLat, iLng, intID;
		var strOptions	= '';
		
		for (var i=0; i < iLength; i++)
		{
			if ( typeof pois[i] == "undefined") continue;
			if ( typeof pois[i]['state']== "undefined" ) continue;
			if ( typeof pois[i]['city']== "undefined" ) continue;
			if ( pois[i]['state']== "" )pois[i]['state'] = "DE";			
			
			poiState 	= pois[i]['state'];	
			poiTitle	= pois[i]['title'];
			iLat		= pois[i]['lat'];	
			iLng		= pois[i]['lng'];
			intID		= iLat+"_"+iLng;
			
			if (typeof GLOBALS.hashKanton[ poiState ] == 'undefined')
			{
				GLOBALS.hashKanton[ poiState ] = new Array();
				arrStates.push( poiState );
			}

			if (! GLOBALS.hashKanton[ poiState ].inArray(poiTitle) )
			{
				GLOBALS.hashKanton[ poiState ].push( poiTitle + '#' + intID );					
			}
								
			GLOBALS.arrCompanies.push( poiTitle + '#' + intID );

		}
		
		arrStates.sort();
		var c 		= 0;
		var delimiter = true;
		var iLength = arrStates.length;
		for (var i=0; i < iLength; i++)
		{
			strKanton    = arrStates[i];
			if(strKanton.indexOf("_")>=0 && delimiter)
			{
				strOptions += '<option disabled="disabled">---</option>'
				delimiter = false;
			} 
			strOptions += '<option value="' + strKanton + '">' + mapCategory.mapCategoryName(strKanton) + "</option>"
			
		}
		
		$('#sel_kanton').append( strOptions ).get(0).selectedIndex = 0;
		GLOBALS.arrCompanies.sort();
		fillCompanyDropDown( 'all' );
	}

	/**
	 * Fills the company dropdown with the
	 * values of the companies for a selected
	 * state.
	 * @param {string}
	 * 		Name of the state or 'all'
	 */	
	function fillCompanyDropDown( strSelectedKanton )
	{	
		var arrOptions 		= $('#sel_kraftwerk option').get();
		var iLength 		= arrOptions.length;
		var arrIDs 			= new Array();
		var strOptionGroup  = '<option  value="all">alle</option>';

		$('#sel_kraftwerk option').remove();

		if ( strSelectedKanton == 'all')
		{
			var iLength = GLOBALS.arrCompanies.length;		
			for (var i=0; i < iLength; i++)
			{
				arrCompanyAndID = GLOBALS.arrCompanies[i].split("#");
				strOptionGroup += '<option value="' + arrCompanyAndID[1] + '">' + arrCompanyAndID[0] + "</option>";			
			}	
			GLOBALS.blnAllFilled = true;					
		}
		else
		{
			var arrCompanies = GLOBALS.hashKanton[ strSelectedKanton ];
			var iLength 	 = arrCompanies.length;
			for (var i=0; i < iLength; i++)
			{
				arrCompanyAndID = arrCompanies[i].split("#");
				strOptionGroup += '<option value="' + arrCompanyAndID[1] + '">' + arrCompanyAndID[0] + "</option>";				
			}
			GLOBALS.blnAllFilled = false;
		}
		
		$('#sel_kraftwerk').append(strOptionGroup).get(0).selectedIndex = 0
	}

	/**
	 * Sets the Google Maps zoom level
	 * 
	 */		
	function setZoom( intZoomLevel )
	{
		localVar.mapGlobal.setZoom( intZoomLevel );
	}
	
	
	/**
	 * This function hides all marker and shows only
	 * the selected ones.
	 */	
	function showSelectedMarker()
	{
		// close if an info window is open
		ew.hide();
		
		// Get all selected category values
		// and save them in the array arrCategory
		var arrCategory = {};			
		
		$(":checkbox").each(function(){
			if (this.checked)
			{
				var catName  = this.className;
				var catValue = mapCategory.mapCategoryName( this.name );
				
				if (typeof arrCategory[catName] == 'undefined') arrCategory[catName] = new Array();
			 	arrCategory[catName].push(catValue);
			}
		});
		
		mapCategory.showCategory( arrCategory, false);
	}
	
	/**
	 * This function makes label or input elements clickable.
	 * Therefor the <label> must have a for attribute with
	 * the same name of the element.
	 * @param {object}	
	 * 			Pointer to DOM Label Object
	 */
	function click_Label( me )
	{
		strID 	= $(me).attr('for');
		obj 	= $('input[@name='+strID+']').get(0);

		if ( obj.checked )
			obj.checked = false;
		else
			obj.checked = true;
			
		showSelectedMarker();
	}
