/*
Script: site.js
	mmjaeger.com site class
	
License:
	MIT-style license.

Copyright:
	(C) Copyright 2007 Marco M. Jaeger, <http://mmjaeger.com>	 

Credits:
	class is based on MooTools framework <http://www.mootools.net/>
	(C) Copyright 2007 Valerio Proietti
	MIT-style license
*/

// Mootools Documentation: http://svn.mootools.net/tags/1-2b1/Docs/index.html
// Mootools Documentation: http://docs12b.mootools.net/
// Google Maps Api: http://code.google.com/apis/maps/documentation/
// Google Maps Blog: http://googlemapsapi.blogspot.com

//if (typeof(console) == 'undefined') var console = {};
var cookie = new Hash.Cookie('jsite', { duration: 365, path: '/' });

var Site = new Class({
					 
	Implements: [Events, Options],	
	
	options: {
		toggle: 		'expand',		// collapse | expand
		btn: 			'btn-toggle', 
		container:		'lvl-2',
		theme: 			'th01',
		level:			true,
		fontStep:		5,
		animateMenu: 	true,
		apiKey:				{
			0:				{ local: 	'ABQIAAAA72sx3KpMqkKR16NEWQAJZBT2yXp_ZAY8_ufC3CFXhHIE1NvwkxSVQ8HUIVqrbN4ssFIdMZFPAE5nfw',		// Google
							  server:	'ABQIAAAA4xWSNHokoOdL0J-r6kQcNRSVcPVrk1BRzLaZDtFkld6uf5g2nxRNGDaJy8ToafItR3iir3KhGLkgmg' },
			1:				{ local: 	'hLpDO9PV34Gy3lTz3VS5QA5Mq0usUmj3bp8O65tvPmlJxBZOPPygAe.ydJydRw--',								// Yahoo
							  server: 	'hLpDO9PV34Gy3lTz3VS5QA5Mq0usUmj3bp8O65tvPmlJxBZOPPygAe.ydJydRw--' },
			2:				{ local: 	'', 																							// Microsoft
			            	  server: 	'' }
		},
		cfg: {
			mapSource:		0
		},
		map: {
			style: {
				absolute:	false,
				top: 		false,
				width: 		412,
				height: 	338,
				offset:		'3em'
			},
			init: {
				show:			false,	// show map on load				
				type:			'G_PHYSICAL_MAP',	// G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP
				lat:			32.68041848810962,
				lng:			-117.1746826171875,
				zoom:			10,
				drag:			true,
				lock:			false,
				auto:			true	// auto zoom
			},
			controls: {
				hide:		false,	// disable all controls
				overview: 	true,
				zoom:		true,
				type:		true,
				terrain:	true,
				search:		false,
				scale:		true			
			},
			icons: {
				path:		'http://localhost/sites/dev_mmjaeger/site/images/icons/markers/',
				base: 		'red',
				colors:		['grey','red','orange','yellow','pink','green','blue','lightblue','darkblue'],
				hover: 		'white',
				numbered:	true
			},
			polyline: {
				show: 		false,
				area: 		true,
				color: 		'#ff0000',
				width: 		1,
				opacity: 	0.4,
				clickable:	false
			},
			magnify: {
				width:		168,
				height:		138,
				inline:		false,
				drag:		true,
				marker:		true,
				sync:		true,
				zoom:		2
			}
		}
	},
	
	initialize: function(options) {		
		this.setOptions(options);
		cookie.load();
		this.options.theme = cookie.has('theme') ? cookie.get('theme') : this.options.theme;
		this.options.level = cookie.has('level') ? cookie.get('level') : this.options.level;
		this.setTheme();
		this.setLevel();
		this.setFont();
		this.setComment();
		this.setArchive();
		this.setMenu();
		//this.setMap();
		this.loadApi(); // if map field value != '';

		/*window.addEvent('unload', function() {
			if (typeof(GUnload) == 'function') GUnload();
			//if ($type(GUnload) == 'function') GUnload();
		});*/

	},

	// set font
	setFont: function() {
		// init
		if (!$defined(this.cfont)) {
			// Firefox returns px when font-size is set to percent
			/*this.options.font = (!Browser.Engine.gecko) ? $(document.body).getStyle('font-size').toInt() : ($(document.body).getStyle('font-size').toInt()/16*100);*/
			this.options.font = $(document.body).getStyle('font-size').toInt()/16*100;
			this.cfont = this.options.font;
		}

		// add events
		$$('#theme li.ft-set').each(function(el, idx) {
			el.addEvent('click', function(event) {
				event.stop();										  
				switch (idx) {
					case 0:
						this.cfont = this.options.font;
						break;
					case 1:
						this.cfont = this.cfont + this.options.fontStep;
						break;
					case 2:
						this.cfont = this.cfont - this.options.fontStep;
						break
				}

				// set font size
				$(document.body).setStyle('font-size', this.cfont + '%');				
			}.bind(this))				  
		}.bind(this));		
	},

	// set theme
	setTheme: function (theme) {
		var theme  = $defined(theme) ? theme : this.options.theme;
		var elBody = $(document.body);
		// add events
		if (!elBody.hasClass()) {
			$$('#theme li.th-sel').each(function (el) {
				el.addEvent('click', function(ev) {
					ev.stop();
					this.setTheme(el.get('id'));								 
				}.bind(this))
			}.bind(this));	
		}
		
		// set theme
		elBody.removeClass(this.options.theme);
		if ($(this.options.theme)) $(this.options.theme).removeClass('active');
		elBody.addClass(theme);
		if ($(theme)) $(theme).addClass('active');
		this.options.theme = theme;
		cookie.set('theme', this.options.theme);
	},
	
	// animate side menu
	setMenu: function () {
		if (!this.options.animateMenu) return false;

		var css = 'padding-left';
		$$('#side-menu a').each(function(el) {
			var from = el.getStyle(css);	// original padding
			var to   = 30;
			
			el.addEvent('mouseenter', function(ev) {
				el.set('tween', {
					duration: 	100,
					transition:	Fx.Transitions.linear,
					wait:		true					   
				});
				el.tween(css, [from, to]);
				/*var fx = new Fx.Tween(el, css, { 
					duration: 	100,
					transition:	Fx.Transitions.linear,
					wait:		true
				}).start(from , to);*/
			})
			
			el.addEvent('mouseleave', function() {
				el.set('tween', {
					duration: 	800,
					transition:	Fx.Transitions.Bounce.easeOut,
					wait:		true					   
				});							   
				el.tween(css, [to, from]);
				/*var fx = new Fx.Tween(el, css, { 
					duration: 	800,
					transition:	Fx.Transitions.Bounce.easeOut,
					wait:		true
				}).start(to, from);*/
			})
										  
 		})		
	},
	
	// toggle level 2
	setLevel: function () {
		var el  = $(this.options.container);
		var btn = $(this.options.btn);
		//var h   = el.getOffsetSize().y; ???????
		
		var fx = new Fx.Slide(el, {
			duration: 1000,
			transition: Fx.Transitions.Pow.easeOut			
		});
		(this.options.level) ? fx.hide() : fx.show();
		(this.options.level) ? btn.set('text', 'Open') : btn.set('text', 'Close');
		btn.addEvent('click', function(ev) {
			ev.stop();
			fx.toggle();
			this.options.level = (this.options.level) ? false : true;
		    (this.options.level) ? btn.set('text', 'Open') : btn.set('text', 'Close');
			cookie.set('level', this.options.level);
			//cookie.save();
		}.bind(this));
		(this.options.level) ? btn.set('text', 'Open') : btn.set('text', 'Close');
	},
	
	// toggle comment form
	setComment: function () {
		var el = $('toggle_comment_form');
		if (!$defined(el)) return false;
		
		var stretch = el.getNext();
		var fx = new Fx.Slide(stretch, {
			duration: 1000,
			transition: Fx.Transitions.Pow.easeOut			
		}).hide();

		el.addEvent('click', function(ev) {
				ev.stop();
				fx.toggle();				
		});
	},
	
	// toggle archive entries
	setArchive: function () {
		// EE: show_empty needs to be set to "no"
		this.fxs = $$('ul.nav_cat_archive ul').map(function(el, idx) {
			return new Fx.Slide(el, {
				duration: 	1000,
				transition: Fx.Transitions.Pow.easeOut	
			}).hide();
		});	
		
		$$('ul.nav_cat_archive h4').each( function(el, idx) {			
			el.addEvent('click', function(ev) {
				ev.stop();				
				this.fxs[idx].toggle();				
			}.bind(this))
		}.bind(this))
	},

	// load map API 
	loadApi: function(isLoaded) {
		return false;
		isLoaded = (!isLoaded) ? false : isLoaded;
		// load api
		if (!isLoaded) {
			var key = this.options.cfg.mapSource;
			var loc = window.location;
			var api = (loc.hostname == 'localhost') ? this.options.apiKey[key].local : this.options.apiKey[key].server;
			
			new Asset.javascript('http://maps.google.com/maps?file=api&v=2.x&async=2&key=' + api, {
				onload: function() {
					// show loader					
					//$('map').startWaiting('bigWaiting');
					//this.waiter = new Waiter($('map').getParent().getParent()).start();					
				}.bind(this)
			});
		}
		
		if (!this.isLoadedApi()) {
			this.loadApi.delay(200, this, true);
		} else {	
			
			//new Asset.javascript('js/info/src/extinfowindow.js');
			
			this.loadMap('g-map');
			//this.addSavedPoints();	// read EE data
			
			// add event			
			window.addEvent('unload', function() {				
				if ($type(GUnload) == 'function') GUnload();
				//this.onCloseMap();
			}.bind(this));
			// hide loader
			//$('map').setStyle('background','none');
		}
	},

	// load map
	loadMap: function(el) {			
		var el = $(el);
		var opts = {
			draggableCursor: 	'pointer',
			draggingCursor: 	'move',
			//googleBarOptions: 	this.setGoogleBar(),
			suppressCopyright:	true,
			usageType: 			'o',
			logoPassive: 		true	
		}
		this.map = new GMap2(el, opts);
		this.setMap();
	},

	// set google map
	setMap: function() {		
		if (!this.checkMap()) return false;
		var options = this.options.map;
		
		$('g-map').setStyles({width: options.style.width, height: options.style.height}); // map dimensions

		this.map = new GMap2($('g-map'), {draggableCursor: 'arrow', draggingCursor: 'arrow'});
		options.init.type = this.getMapType(options.init.type);
		this.map.setCenter(new GLatLng(options.init.lat, options.init.lng), options.init.zoom, options.init.type);
		
		//this.map.setMapType(options.init.type);
		// controls and settings
		if (options.controls.terrain)	{ this.map.addMapType(G_PHYSICAL_MAP); }
		if (options.controls.search)	{ this.map.enableGoogleBar(); }
		if (options.controls.overview)	{ this.map.addControl(new GOverviewMapControl()); }
		if (options.controls.zoom) 		{ this.map.addControl(new GSmallZoomControl()); }
		if (options.controls.type) 		{ this.map.addControl(new GMapTypeControl()); } // alt: new GMapTypeControl(true)
		if (options.controls.scale)		{ this.map.addControl(new GScaleControl()); }
		if (options.controls.hide) 		{ this.map.hideControls(); this.map.disableGoogleBar(); }

		if (!options.init.drag) 		{ this.map.disableDragging(); }
		if (options.init.lock)			{ this.map.disableDragging(); this.map.hideControls(); this.map.disableGoogleBar(); }

		// add markers
		var bounds = new GLatLngBounds();
		var points = [];
		var setEvents = false; 
		unescape($('e-mapData').get('value')).split('\n').filter(function(item, index) {		
			return item.length > 0;							  
		}).each(function(item, index) {
			var json = JSON.decode(item);			
			if ($defined(json.mapSource)) {
				// overwrite map settings	
				
			} else {
				var o = this.setMarker(JSON.decode(item), index);
				if ($chk(o)) {
					if (o.map) setEvents = true;
					this.map.addOverlay(o.marker);
					this.map.setZoom(o.zmn);
					points.include(o.point);
					bounds.extend(o.point);
				}
			}
		}.bind(this));
		//console.log(this.map.getZoom());
/*		$('toggle-e-map').get('rel').split('\n').filter(function(item, index) {
			return item.length > 0;							  
		}).each(function(item, index) {
			var o = this.setMarker(JSON.decode(item), index);
			if ($chk(o)) {
				if (o.map) setEvents = true;
				this.map.addOverlay(o.marker);
				points.include(o.point);
				bounds.extend(o.point);
			}
		}.bind(this));*/
		//console.log(setEvents);
		// add polyline/polygone
		if ($chk(this.setPolyline(points))) this.map.addOverlay(this.setPolyline(points)); 
		
		// center map
		//if (options.init.auto) this.map.setZoom(this.map.getBoundsZoomLevel(bounds));		
		this.map.setCenter(bounds.getCenter());


		// add event to link (toggle map)
		$('toggle-e-map').addEvent('click', function(ev) {
			ev.stop();
			this.toggleMap();			
		}.bind(this));
		
		this.positionMap();
		this.toggleMap();
	},

	// check whether Map API is loaded
	isLoadedApi: function() {
		//var t = this.getRadio('mapSource');
		var t = 0;
		//var t = parseFloat(this.options.cfg.mapSource);
		//console.log('isLoadedApi: ' + z +' || '+ t);
		switch (t) {
			case 0: // Google
				if (typeof(GMap2) == 'undefined') return false;
				break;
			case 1: // Yahoo
				if (typeof(YMap)  == 'undefined') return false;				
				break;
			case 2: // Microsoft
				if (typeof(VEMap) == 'undefined') return false;
				break;
		};
		return true;
	},
	
	// get map type
	getMapType: function(str) {
		//G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP
		switch(str) {
			case 'G_NORMAL_MAP':
				return G_NORMAL_MAP;
				break;
			case 'G_SATELLITE_MAP':
				return G_SATELLITE_MAP;
				break;
			case 'G_HYBRID_MAP':
				return G_HYBRID_MAP;
				break;
			case 'G_PHYSICAL_MAP':
				return G_PHYSICAL_MAP;
				break;
			default:
				return G_NORMAL_MAP;
		}
	},
	
	// check whether map is available
	checkMap: function() {
		if (!$defined($('g-map'))) return false;
		if (!GBrowserIsCompatible()) {
			$('toggle-e-map').setStyle('display','none');
			return false;
		}
		if ($defined(this.map)) return false;
		
		return true;	
	},
	
	// position map {
	positionMap: function() {	
		var options = this.options.map;
		// set position
		$('e-mapContainer').setStyle('position', (options.style.absoute) ? 'absolute' : 'relative');
		if (options.style.absoute) {
			var off = (options.style.top) ? 0 : options.style.offset;
			var loc = (options.style.top) ? 'top' : 'bottom';
			$('e-mapContainer').setStyle(loc, off);
		}
	},
	
	// toggle map
	toggleMap: function() {		
		if (!$defined(this.map)) return false;
		var options = this.options.map;
		// set effect
		if (!$defined(this.fxMap)) {
			this.fxMap = new Fx.Morph('e-mapContainer', {
				duration: 1000,
				transition: Fx.Transitions.linear,
				onComplete: function () {
					this.map.isVisible = (this.map.isVisible) ? false : true;
					this.map.isVisible ? $('toggle-e-map').set('text','Hide Map') : $('toggle-e-map').set('text','Show Map');					
				}.bind(this)
			});
			
			this.map.isVisible = options.init.show;
			
			if (!this.map.isVisible) this.fxMap.set({height: 0, width: 0, opacity: 0});
			this.map.isVisible ? $('toggle-e-map').set('text','Hide Map') : $('toggle-e-map').set('text','Show Map');	
			
			return false;
		}
		
		// toggle map
		if (this.map.isVisible) {
			this.fxMap.start({ 'height': [this.map.height, 0], 'width': [this.map.width, 0], 'opacity': [1,0] });
			if (this.info.isVisible) {this.fxInfo.set({'opacity':0});	this.info.isVisible = false;}
		} else {
			this.fxMap.start({ 'height': [0, this.map.height], 'width': [0, this.map.width], 'opacity': [0,1] });
		}
	},
	
	// set marker(s)
	setMarker: function(json, index) {
		//console.log(json.toString());
		var obj 	= {};
		obj.title	= $chk(json.tit) ? json.tit.clean() : json.lat+', '+json.lng;
		obj.descr	= json.descr;	
		obj.icon   	= this.setIcon(json.ico, index-1);
		obj.lat		= parseFloat(json.lat);
		obj.lng		= parseFloat(json.lng);
		obj.zmn		= parseFloat(json.zmn);
		obj.point   = new GLatLng(obj.lat, obj.lng);		
		obj.marker 	= new GMarker(obj.point, {icon: obj.icon, title: obj.tit});
		obj.info	= json.inf;
		obj.map		= json.map;
		
		// create info overlay if needed
		if (obj.info && (!$defined(this.info))) {
			// set dimensions
			var v = $('e-mapContainer').getCoordinates();
			this.map.width  = v.width;
			this.map.height = v.height;

			this.prepareInfo();
		}
		
		// add events
		GEvent.addListener(obj.marker, 'click', function() {				
			this.toggleMapInfo(obj);			
		}.bind(this));
			
		if (obj.info) { // hover marker if info available
			GEvent.addListener(obj.marker, 'mouseover', function() {
				obj.marker.setImage(obj.icon.hover);											 
			}.bind(this));
			
			GEvent.addListener(obj.marker, 'mouseout', function() {
				obj.marker.setImage(obj.icon.image);											 
			}.bind(this));
		}
		
		return obj;
	},
	
	// toggle map info
	toggleMapInfo: function(obj) {
		/*if ($defined(this.fxInfo)) {
			this.fxInfo = new Fx.Morph('ovContainer', {
				duration: 1000,
				onComplete: function() {
					this.info.isVisible = (this.info.isVisible) ? false : true;	
				}.bind(this)
			}).set({'opacity': 0});
			
			$('ovContainerBtn').addEvent('click', function() {
				this.fxInfo.start({'opacity':[1,0]});											 
			}.bind(this))
			this.info.isVisible = false;			
		}*/
		
		if (!$defined(this.info.marker)) this.info.marker = obj;	
		if (obj.info) { 
			this.setZoomMap(obj);
			this.setInfoText(obj);
		}
		if (obj == this.info.marker) {		
			this.info.isVisible ? this.fxInfo.start({'opacity':[1,0]}) : this.fxInfo.start({'opacity':[0,1]});	
		} else if (!this.info.isVisible) {
			 this.fxInfo.start({'opacity':[0,1]});		
		}
		
		if (!obj.info) {
			if (this.info.isVisible) this.fxInfo.start({'opacity':[1,0]});		
		}
		this.info.marker = obj;
	},
	
	// prepare info containers
	prepareInfo: function() {
			var options = this.options.map;
			// prepare
			var el = new Element('div', {'id':'ovContainer'});
			el.grab(new Element('div', {'id':'ovBtn'}));
			el.grab(new Element('div', {'id':'ovMap'}));
			el.grab(new Element('div', {'id':'ovText', 'class':'small'}));
			el.inject($('e-mapContainer'), 'top');
			$('ovMap').setStyles({width: options.magnify.width, height: options.magnify.height})
			$('ovText').setStyle('width', options.magnify.width);	
			this.info = el;
			
			// re-position
			if (!options.magnify.inline) {
				el.setStyles({left: this.map.width, top: 0});				
				options.magnify.drag = false; // disable dragging when outline				
			}
			
			// drag
			if (options.magnify.drag) {
				var handle = $('ovText');
				handle.setStyle('cursor', 'move');
				var d = new Drag.Move(el, {container: $('e-mapContainer'), handle: handle});
			}
			
			this.fxInfo = new Fx.Morph('ovContainer', {
				duration: 1000,
				onComplete: function() {
					this.info.isVisible = (this.info.isVisible) ? false : true;	
				}.bind(this)
			}).set({'opacity': 0});
			
			$('ovBtn').addEvent('click', function() {
				this.fxInfo.start({'opacity':[1,0]});											 
			}.bind(this))
			this.info.isVisible = false;
			
			return;		
	},
	
	// set map info text
	setInfoText: function(obj) {
		var options = this.options.map;
		if (!$chk(obj.map)) {
			$('ovMap').setStyle('display', 'none');	
		} else {
			$('ovMap').setStyle('display', '');		
		}

		// set info text
		var el = $('ovText'); el.empty();
		var html = '';
		html += '<ul class="vert">';
		html += '	<li><label>Location: </label>'+obj.title+'</li>';
		html += '	<li><label>Latitude: </label>'+obj.lat.toFixed(6)+'</li>';
		html += '	<li><label>Longitude: </label>'+obj.lng.toFixed(6)+'</li>';
		if (obj.descr) html += '	<li class="last"><label>Description: </label>'+obj.descr+'</li>';
		html += '</ul>';
		
		el.set('html', html);
	},
	
	setZoomMap: function(obj) {
		var options = this.options.map;
		// create zoom map
		if (!$defined(this.zmap)) { 			
			this.zmap = new GMap2($('ovMap'));
			this.zmap.setCenter(new GLatLng(options.init.lat, options.init.lng), options.init.zoom, options.init.type);
			this.zmap.disableDragging();
			this.zmap.hideControls();			
			this.zmap.noMove = false;
			
			// add events to sync zoom map - to do: move to main map!!!
			if (options.magnify.sync) {
				// change map type
				GEvent.addListener(this.map, 'maptypechanged', function() {		
					this.zmap.setMapType(this.map.getCurrentMapType());					
					this.zmap.noMove = true;
				}.bind(this));
				
				// zoom map
				GEvent.addListener(this.map, 'zoomend', function(startZoom, endZoom) {					 
					this.zmap.setCenter(obj.point, Math.min((endZoom + options.magnify.zoom), 15));	
					this.zmap.noMove = true;
				}.bind(this));
				
				// move map
				GEvent.addListener(this.map, 'moveend', function() {													 
					if (!this.zmap.noMove) this.zmap.setCenter(this.map.getCenter());
					this.zmap.noMove = false;			
				}.bind(this));
			}
			
			// return to initial position
			GEvent.addListener(this.zmap, 'click', function() {
				this.map.setCenter(obj.point);
				this.zmap.setCenter(obj.point);	
			}.bind(this));
		}
		
		// place marker - to do: create marker only the first time!!!
		if (options.magnify.marker) this.zmap.addOverlay(new GMarker(obj.point, {icon: obj.icon, title: obj.title}));
		this.zmap.setCenter(obj.point, Math.min((this.map.getZoom() + options.magnify.zoom), 15));	
	},
	
	// set polyline(s)
	setPolyline: function(points) {
		var options = this.options.map;
		if (!options.polyline.show) return false;
		var p = null;
		var w = options.polyline.width;
		var c = options.polyline.color;
		var o = options.polyline.opacity;
		
		if (options.polyline.area) {
			p = new GPolygon(points, c, 0, o, c, o*0.5);	
		} else {
			p = new GPolyline(points, c, w, o, {geodesic: true, clickable: options.polyline.clickable});	
		}
		
		return p;
	},
	
	// set map icon
	setIcon: function (color, index) {	
		var options = this.options.map;
		var color 				= (options.icons.colors.indexOf(color) > -1) ? color : options.icons.base;
		var index 				= (options.icons.numbered) ? index + 1 : '';
		
		var icon  				= new GIcon();
		icon.image  			= options.icons.path + color + index + '.png';
		icon.hover 				= options.icons.path + options.icons.hover + '.png';
		icon.shadow 			= '';
		icon.iconSize 			= new GSize(17, 19);  
		icon.iconAnchor 		= new GPoint(0, 19);
		icon.infoWindowAnchor 	= new GPoint(15, 1);
		
		return icon;
	}
});


var Map = new Class({
					
	Implements: [Events, Options],
	
	Extends: Site,
	
	options: {
	},
	
	initialize: function(el, options) {
		this.setOptions(options);	
	}
	
});

window.addEvent('domready', function(){ 
	var site = new Site();
});