var BC_CENTER ;
var BC_ZOOMLEVEL = 5;
var LEGEND_IMAGE = 'image/legend.gif';
var map ;
var datastore;
//var dsForIndivOutage;
var elementIdToOutageIdMap = new Array();

var mapIconOutageGroup ; 
var mapIconSingleOutage; 
var combo;
var mmStore;

var contentWithMediaMessages;
var contentNoMediaMessages;
var loadingIndicator;
var datastoreLoadingStateMap;

var searchAddressFlag = false;
var searchAddress = ""; //for displaying search address in pin description

var aJaxHttp = getXMLHttpObject();
var cacheUpdatedTime = "";

function resetMap(){
	map.SetCenterAndZoom(BC_CENTER, BC_ZOOMLEVEL);
}


function getCacheTime() {
	return cacheUpdatedTime;
}


function pageUnavailable(){
	 window.location = contextPath + '/orsUnavailable.jsp';
}

function zoomToArea(area){
      var tl;
      var br;
      var rect;
           
      if(area == 'Central'){
            tl = new VELatLong(54.80068486732233, -130.7373046875);
            br = new VELatLong(51.69979984974194, -119.88281250000001);

      }else if (area == 'LowerMainland') {
            tl = new VELatLong(50.387507803003146, -125.650634765625);
            br = new VELatLong(48.96579381461063, -121.59667968749998);

      }else if (area == 'Northern') {
            tl = new VELatLong(61.10078883158897, -135.74707031250003);
            br = new VELatLong(55.553495458453696, -117.48779296875);

      }else if (area == 'Okanagan') {
            tl = new VELatLong(51.91716758909015, -122.84912109375001);
            br = new VELatLong(49.83798245308484, -110.72021484375001);

      }else if (area == 'Thompson') {
            tl = new VELatLong(54.39974815563758, -125.12329101562501);
            br = new VELatLong(50.26827673727529, -114.01611328125);

      }else if (area == 'IslandNorth') {
            tl = new VELatLong(50.9618866513206, -128.92456054687503);
            br = new VELatLong(49.55728898983402, -124.7060546875003);

      }else if (area == 'IslandSouth') {
            tl = new VELatLong(49.72447918871298, -126.89208984375);
            br = new VELatLong(48.28319289548348, -122.838134765625);

      } else {
       		area = null;
            alert("Unknown Region.");
      }  
      
      if( area != null ){
	      rect = new VELatLongRectangle(tl, br);    	      	
	      map.SetMapView(rect); 
      }
}


function loadingStarted(storename){
  	loadingIndicator.show();
	datastoreLoadingStateMap[storename]=true;
}

function loadingEnded(storename){
	datastoreLoadingStateMap[storename]=false;
	
	for (var i in datastoreLoadingStateMap)
		if (datastoreLoadingStateMap[i] == true)
			return;
	
  	loadingIndicator.hide();
  	
	if (aJaxHttp != null) {
		var timestamp = new Date();
		var url = contextPath + '/mapOutageData?time=true';
		aJaxHttp.open('POST',url,true);
		aJaxHttp.onreadystatechange = function() {checkState();};
		aJaxHttp.send(null);
	}
  	
  	//focus cursor to the address search box
  	document.getElementById("addressField").focus();
  	
  	//if customer has searched for address, show the location and reset flag
  	if(searchAddressFlag == true) {
  		addAddressPin();
  		searchAddressFlag = false;
  	}
  	
  	//check if map is in default view.  If yes then show the legend box
  	var currCenter;
  	var currLat;
  	var currLong;
  	currCenter = map.GetCenter();
  	currLat = currCenter.Latitude;
  	currLong = currCenter.Longitude;
  	if( (currLat < (BC_CENTER.Latitude + 0.25))  && (currLat > (BC_CENTER.Latitude - 0.25)) &&
		(currLong < (BC_CENTER.Longitude + 0.25)) && (currLong > (BC_CENTER.Longitude - 0.25)) &&
		(map.GetZoomLevel() == 5)){

		var legend = new VEShape(VEShapeType.Pushpin, new VELatLong(56, -143));

		var spec = new VECustomIconSpecification();
				
		spec.Image = LEGEND_IMAGE;
		legend.SetCustomIcon(spec);
		map.AddShape(legend);

	}
		
}

function getXMLHttpObject() {
	var xmlHttp=null;
	try {
		// Firefox, Opera 8.0+, Safari
		xmlHttp=new XMLHttpRequest();
	} catch (e) {
		// Internet Explorer
		try {
			xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
			} catch (e) {
			xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
	    }
	}
	return xmlHttp;
}
	
function checkState() {
	if (aJaxHttp.readyState == 4) {
		var resp = aJaxHttp.responseText;
		cacheUpdatedTime = resp;
		
		document.getElementById("updateTime").innerHTML = "Last Updated: " + cacheUpdatedTime;
	}
}

function addAddressPin(){
	var youAreHerePin = new VEShape(VEShapeType.Pushpin, map.GetCenter());
	youAreHerePin.SetTitle("You are here");
	youAreHerePin.SetDescription(searchAddress);
	map.AddShape(youAreHerePin);
	
	//reset searchAddress
	searchAddress = "";
}

/**
	Map Related Callback Handlers	
**/
function refreshDataStoreFromMapBounds(){
   var z = map.GetZoomLevel();

   var view = map.GetMapView();
   var topleft = view.TopLeftLatLong;
   var bottomright = view.BottomRightLatLong;
   var pixelBR = map.LatLongToPixel(bottomright);
   var width = pixelBR.x;
   var height = pixelBR.y;
   datastore.reload({params:{mapTL: topleft.toString(), mapBR: bottomright.toString(), zoomLevel: z, w: width, h: height}});
}

function indivDataLoadDataStore( oid ){
  
   dsForIndivOutage.reload({params:{type: "1", outageId: oid}});  
}

/* 20080930 echan: commented because there is a better way to disable bird's eye
function ChangeMapStyleHandler(e) {

   var s = map.GetMapStyle();
   if (s == VEMapStyle.Birdseye) {
     map.SetMapStyle(VEMapStyle.Hybrid);
   }
   refreshDataStoreFromMapBounds()
}
*/


//function zoomToOutageId(outageId, type){
function zoomToOutageId(outageId){	
/*	if (type == null) { type = 2 };
	
	if (type == 1) {
		var i = location.href.indexOf('?');
		var newURL = location.href;
		var url;
		if (-1 != i) {
			newURL = location.href.substr(0,i);
		
		}  		
		url = newURL + "?outageId=" + outageId;
		window.location = url;
		
	} else if (type == 2) { */
		var record = datastore.getById(outageId);
			
	   if(record != 'undefined'){
			var tl = new VELatLong(record.get('bbTLLat'), record.get('bbTLLong'));
			var br = new VELatLong(record.get('bbBRLat'), record.get('bbBRLong'));
			var rect = new VELatLongRectangle(tl, br); 	
			map.SetMapView(rect);  
		}else{
			alert("Outage is either restored or combined with another outage.");
		}  
//	}
	
}

function getRectangleForRecord( record ){
		var tl = new VELatLong(record.get('bbTLLat'), record.get('bbTLLong'));
		var br = new VELatLong(record.get('bbBRLat'), record.get('bbBRLong'));
		var rect = new VELatLongRectangle(tl, br); 	
		
		return rect;
}

function DoubleClickHandler(e){

	if(e.elementID != null){
		shape = map.GetShapeByID(e.elementID);

		//If image is not the legend, then zoom
		if(shape.GetCustomIcon().Image.substring((shape.GetCustomIcon().Image.length) - (LEGEND_IMAGE.length), shape.GetCustomIcon().Image.length) != LEGEND_IMAGE){
			// get the bounding box from the datastore
			var outageId = elementIdToOutageIdMap[shape.GetID()];
			zoomToOutageId(outageId);
		}
		
		//(MH)this is important! Don't delete
		return true;
    }
}

function EndZoomHandler(e){
	refreshDataStoreFromMapBounds();
}

function EndPanHandler(e){
	refreshDataStoreFromMapBounds();
}


/**
 * The callback used for the address input field and the button
 **/
function specialkeyHandler(field, event){
	if (event.getKey() == Ext.EventObject.ENTER || event.getKey() == Ext.EventObject.TAB){
		gotoInputFieldValue();
	}
}

function gotoInputFieldValue(){
	if (typeof(map) != 'undefined'){
			//var searchString = combo.getValue().toUpperCase();
			var searchTextBox = document.getElementById("addressField");
			var searchString = searchTextBox.value.toUpperCase();
			if (searchString.indexOf('BC') < 0) 
				searchString += ", BC";
			if (searchString.indexOf('CANADA') < 0)	
				searchString += ", Canada";
			searchTextBox.value = searchString;
			map.Find(null, searchString, null, null, 0,1);
			
			//save information necessary to display searched location pin
			searchAddress = searchString
			searchAddressFlag = true;
		}
}

/**
 * Datastore callbacks
 */
function outageDataChangeHandler(ds){
	elementIdToOutageIdMap = new Array();
	map.DeleteAllShapes();
	ds.each(addOutageRecordToMap);
}
 
 
function mediaMessageChangeHandler(ds){
	// show media messages only when we have messages!
	contentWithMediaMessages.setVisible(ds.getCount() > 0);
	contentNoMediaMessages.setVisible(ds.getCount() == 0);
} 

function indivDataChangeHandler(ds){

	if (ds.getCount() > 0) {
		record = ds.getAt(0);
		var tl = new VELatLong(record.get('bbTLLat'), record.get('bbTLLong'));
		var br = new VELatLong(record.get('bbBRLat'), record.get('bbBRLong'));
		var rect = new VELatLongRectangle(tl, br); 	
		map.SetMapView(rect); 
	} else {
		alert("Outage is either restored or combined with another outage.");
	}	
	
}

/**
 * Helper functions
 */ 
function addOutageRecordToMap (record){
	var lat  = record.get('locLat');
	var lng = record.get('locLong');
	var title = record.get('title');
	var description  = record.get('description');
	var polyPoints = record.get('polygon');
	var type = record.get('type');
	var shape; 
	if (typeof( polyPoints ) == "undefined" || polyPoints.length==0){
		// display pins
		var loc = new VELatLong(lat, lng);
		shape = new VEShape(VEShapeType.Pushpin, loc); 
	}else{
		// display polygon
		var points = new Array();
		for (var i=0; i<polyPoints.length; i=i+2){
			var loc = new VELatLong(polyPoints[i+1], polyPoints[i]);
			points[points.length]=loc;
		}
		shape = new VEShape(VEShapeType.Polygon, points); 
	    shape.SetLineColor(new VEColor(255,0,0,1.0));
        shape.SetFillColor(new VEColor(255,0,0,0.5));
	}  
	// set the icon based on the outage type(cluster or single?)
	if (type == 1){
		shape.SetCustomIcon(mapIconSingleOutage);
	}else{
		shape.SetCustomIcon(mapIconOutageGroup);
	}
		
	shape.SetTitle(title);
	shape.SetDescription(description);
	map.AddShape(shape);
	elementIdToOutageIdMap[shape.GetID()] = record.get('id');
	
}


function refreshDataStores(){
	mmStore.reload();
	refreshDataStoreFromMapBounds();
}

function initMapIcons(){
	
	mapIconOutageGroup  = new VECustomIconSpecification();
	mapIconSingleOutage = new VECustomIconSpecification();

	mapIconOutageGroup.Image = contextPath + '/image/outage_cluster.gif';
	mapIconOutageGroup.ImageOffset = new VEPixel(11, 11);
	
	mapIconSingleOutage.Image = contextPath + '/image/outage_single.gif';
	mapIconSingleOutage.ImageOffset = new VEPixel(11, 11);
}

function getQueryValue(str,name) {
	//: return named value from query string of name=value pairs
	var n = str.length;

	if ((0 == n) || (0 == name.length))
		return "";

	if (-1 == name.indexOf('='))
		name += "=";

	var i = str.toLowerCase().indexOf('\&'+name);

	if (-1 == i)
		i = str.toLowerCase().indexOf('\?'+name);

	if (-1 != i) {
		i += 1 + name.length;
		var d = str.indexOf('\&',i);
		if (-1 == d)
		d = n;
		return str.substr(i,d-i);
	}
	else
	{
		return "";
	}           
}

function veLoadURL() {

	var url = document.URL;
	var i = url.indexOf('?');

	if (-1 == i) {
		return false;
	}
	
	url = url.substr(i);
	var outageId = Number(getQueryValue(url,'outageid'));
	var regionName = getQueryValue(url,'region');	

	if ((0 < outageId) && (!isNaN(outageId))) { 
		indivDataLoadDataStore(outageId);
	} else if ((0 != regionName.length) && (regionName!=undefined)) {       
		zoomToArea(regionName);

	}
	
}

Ext.onReady(function() {
	BC_CENTER = new VELatLong(53.239622280409575, -130.122070312500005);

	contentWithMediaMessages = Ext.get('pageWithMediaMessages');
	contentNoMediaMessages = Ext.get('pageNoMediaMessages');
	//If Ext cannot get the DIV, that means the page cannot be loaded --> redirect to Unavailable page
	if (contentWithMediaMessages == null){
		window.location = contextPath + '/orsUnavailable.jsp';
	}
	if (contentNoMediaMessages == null) {
		window.location = contextPath + '/orsUnavailable.jsp';
	}	
	
	contentWithMediaMessages.setVisibilityMode(Ext.Element.DISPLAY);
	contentNoMediaMessages.setVisibilityMode(Ext.Element.DISPLAY);
	loadingIndicator = Ext.get('loadingIndicator');
  	loadingIndicator.hide();

	datastoreLoadingStateMap = new Array();
	datastoreLoadingStateMap["mediamsg"]=false;
	datastoreLoadingStateMap["outages"]=false;


    //------------------------------------------------------------
    //---         Initialize the mapping component             ---
    //------------------------------------------------------------

	initMapIcons();
	
	var outageRecordDef = Ext.data.Record.create([
   		{name: 'id'},
   		{name: 'type'},     
	    {name: 'locLong'},
	    {name: 'locLat'},
	    {name: 'bbTLLong'},
	    {name: 'bbTLLat'},
	    {name: 'bbBRLong'},
	    {name: 'bbBRLat'},
	    {name: 'polygon'},
	    {name: 'title'},
	    {name: 'description'}
	]);
	
	var outageReader = new Ext.data.JsonReader({
    	totalProperty: "size",  
    	root: "outages",        
    	id: "id"                
	}, outageRecordDef);


	datastore = new Ext.data.Store({
		    proxy: new Ext.data.HttpProxy({url: contextPath + '/mapOutageData', method: 'POST'}),
			reader: outageReader
	});	

	datastore.on('datachanged', outageDataChangeHandler);
	datastore.on('loadexception', pageUnavailable);
	datastore.on('beforeload', function(){loadingStarted('outages');});
	datastore.on('load', function(){loadingEnded('outages');});

	dsForIndivOutage = new Ext.data.Store({
			    proxy: new Ext.data.HttpProxy({url: contextPath + '/mapOutageData', method: 'POST'}),
				reader: outageReader
	});
	dsForIndivOutage.on('datachanged', indivDataChangeHandler);	

	map = new VEMap('map');
	//map.SetDashboardSize(VEDashboardSize.Small);
	map.LoadMap(BC_CENTER, BC_ZOOMLEVEL, null, null, null);
	map.SetScaleBarDistanceUnit(VEDistanceUnit.Kilometers);
	map.Resize(738, 400);
	//map.Resize(695, 400);

    //load this datastore in the background
//	zoomMapAndLoadDataStore(19);

    refreshDataStoreFromMapBounds();
    map.AttachEvent("onendzoom", EndZoomHandler);
    map.AttachEvent("onendpan", EndPanHandler);
    map.AttachEvent("ondoubleclick", DoubleClickHandler);
	map.AttachEvent("onclick", DoubleClickHandler);
	//map.AttachEvent("onchangemapstyle", ChangeMapStyleHandler);
    
    //------------------------------------------------------------
    //---     Initialize the location search address field     ---
    //------------------------------------------------------------
    //var store = new Ext.data.Store({
		// NOTE: the variable "context path" should be declared in the page. 
		// we should encapsulate his a bit nicer
	   // proxy: new Ext.data.HttpProxy({url: contextPath + '/addressSuggestions', method: 'POST'}),
	//	reader: new Ext.data.ArrayReader({}, [{name: 'address'}])
		//	});

	//combo = new Ext.form.ComboBox({
   // 	store: store,
    //	queryParam:'address',
    //	displayField:'address',
    //	hideTrigger:true,
    //  	typeAhead: false,
 	 // 	queryDelay: 1000,
    //	triggerAction: 'all',
	 //   selectOnFocus:true
	//});
	
	//combo.addListener('specialkey', specialkeyHandler);
	//combo.applyToMarkup('addressField');	
   
	//------------------------------------------------------------
    //---          Initialize the media messages               ---
    //------------------------------------------------------------
     
   	var mmTemplate = new Ext.XTemplate(
    	'<tpl for=".">' +
	        '<div class="mmsg">' +
			'<div class="mmdate">{date}</div>' +
			'<div class="mmarea">{area}</div>' +
			'<div class="mmtext">{message}</div>' +
			'</div>' +
	    '</tpl>' );
  
  
	mmStore = new Ext.data.JsonStore({
    	url: contextPath + '/mediaMessages',
	    root: 'mediaMessages',
    	fields: ['date', 'area', 'message', 'url']
	});

	mmStore.on('load', mediaMessageChangeHandler);
	mmStore.on('beforeload', function(){loadingStarted('mediamsg');});
	mmStore.on('load', function(){loadingEnded('mediamsg');});
	//mmStore.load();    
	
  	var mmView = new Ext.DataView({
  		applyTo: 'mediaMessages',
        loadingText: 'Loading Outage Messages',
        store: mmStore,
        tpl: mmTemplate,
        itemSelector: 'div.mmsg',
        //emptyText: '<div class="mmarea">No Messages to Report</div>',
		hideParent:true
    })
  
  	mmView.render();
  	
  	//Check the URL to see if we have Query String
  	var url = document.URL;
	var i = url.indexOf('?');

	if (-1 == i) {
	  	//------------------------------------------------------------
	    //---                Periodic Updater Task                 ---
	    //------------------------------------------------------------
		
		var task = {
	    	//run: function(){refreshDataStores();veLoadURL();},
	    	run: function(){refreshDataStores();},
		    interval: 1000 * 60 * 10 //10 minutes
		}
		Ext.TaskMgr.start(task);
		
	} else {
		veLoadURL();
		mmStore.reload();
	}
	
				
});

//bookmarking is disable until we find a way to make it work on firefox, IE and safari. Current only IE works.
/*function CreateBookmarkLink(outageId) {

	var i = location.href.indexOf('?');
	var newURL = location.href;
	var url;
	if (-1 != i) {
		newURL = location.href.substr(0,i);
		
	} 

 	if(outageId != undefined){
 
		 title = "BC Hydro Outage"; 
		 url = newURL + "?outageId=" + outageId;
				
		if (window.sidebar) { // Mozilla Firefox Bookmark
			window.sidebar.addPanel(title, url,"");
		} else if( window.external ) { // IE Favorite
			window.external.AddFavorite( url, title); 
		}		
	}else{
		alert("Sorry, we are unable to find that outage.");
	}
}*/
  
  

