/**********************************************************************************
***********************************************************************************
                           JavaScript for BlackBook Whitelabel
                                   powered by BlackBook
                                
  @name         bb.js
  @author       Bastian Kuberek - bkuberek@blackbookmag.com                    
  @copyright    Copyright © 2008 BlackBook Media Corp. All rights reserved.    
  
  @require      prototype 1.6.x, scriptaculous 1.8.x
                                                                                 
***********************************************************************************
**********************************************************************************/


/* ===>  blackbook namespace  <==== */
var bb = { version: '1.0.9' };

/* ====>  bb search  <==== */
bb.search = {
	
	default_string: 'Search Guides by Bravo',
	form_element: 'bb-search-form',
	type_element: 'bb-search-type',
	tabs_element: 'bb-search-tabs',
	
	reset: function (type) {
		this.tabs_element.childElements().each(function(tab) {
			tab.style.backgroundPosition = "";
		});
		if($id('bb-search-'+type)){
			$id('bb-search-'+type).style.backgroundPosition = "0 -16px"; 
		};
		this.type = type;
	},
	
	set: function (type) {
		$id('bb-search-'+type).blur();
		this.type_element.value = type; 
		this.reset(type);
	},
	
	submit: function (event) {
		try{event.stop();}catch(e){};
		if (this.type == 'all') {
			this.action = this.form_element.action+'/keyword/'+rawurlencode(this.form_element.keywords.value);
		} else {
			this.action = this.form_element.action+'/'+this.type+'/keyword/'+rawurlencode(this.form_element.keywords.value);
		};
		window.location = this.action;
		return false;
	},
	
	_onFocus: function() {
		if (this.form_element.keywords.value == this.default_string) {
			this.form_element.keywords.value = '';
		} else {
			this.form_element.keywords.select();
		};
	},
	
	_onBlur: function() {
		if (this.form_element.keywords.value == '') this.form_element.keywords.value = this.default_string;
	},
	
	init: function () {
		this.form_element = $id(this.form_element);
		this.type_element = $id(this.type_element);
		this.tabs_element = $id(this.tabs_element);
		this.type = this.type_element.value; 
		this.reset(this.type);
		
		if (this.form_element.keywords.value == '') {
			this.form_element.keywords.value = this.default_string;
		}
		if (Prototype.Browser.IE === false) { // Stupid IE won't get a focus handler
			this.form_element.keywords.observe('focus', this._onFocus.bind(this));
			this.form_element.keywords.observe('blur', this._onBlur.bind(this));
		};
		this.form_element.observe('submit', this.submit.bindAsEventListener(this));
	}
};

/* ====>  bb modal  <==== */
bb.modal = {
	/* initial settings */
	options: {
		overlayId: 'bb-overlay',
		overlayClassName: '',
		overlayOpacity: 0.9,
		overlayZIndex: 1000000,
		className: 'bb-modal',
		fadeIn: 0.5,
		fadeOut: 0.5
	},
	windows: [],
	
	load: function(element, options) {

		var options = Object.extend({
			autoOpenIfLinked: false,
			position: 'absolute',
			contents: false,
			width: null,
			height: null,
			offsetLeft: 0, 
			offsetTop: 0,
			loading: false, 
			fade: true,
			fadeDuration: 0.8,
			image: false,
			imageCloseOnClick: true,
			hover: false,
			overlayDisplay: true,
			overlayClassName: 'screen',
			overlayCloseOnClick: true,
			containerClassName: '',
			opacity: 0.9,
			zIndex: 1000000,
			iframe: false,
			iframeTemplate: new Template('<iframe src="#{href}" width="100%" height="100%" frameborder="0" id="#{id}"></iframe>'),
			evalScripts: true, 
			requestOptions: {},
			
			// events 
			beforeOpen: Prototype.emptyFunction,
			afterOpen: function() {
				try {
					close_el = $id('modal_container').down('.bb-modal-close');
					close_el.observe('click', function(event) {
						event.stop()
						Control.Modal.close();
					});
			    } catch(e) { return; };
			},
			beforeClose: Prototype.emptyFunction,
			afterClose: Prototype.emptyFunction,
			onSuccess: Prototype.emptyFunction,
			onFailure: Prototype.emptyFunction,
			onException: Prototype.emptyFunction,
			beforeImageLoad: Prototype.emptyFunction,
			afterImageLoad: Prototype.emptyFunction
			
		}, options || {});
		
		bb.modal.windows.push(new Control.Modal(element, options));
	},
	
	/* methods */
	open: function (element, center, screen) {
		try{element = $id(element);}catch(e){return;};
		if (screen === true) this.overlay.addClassName('screen');
		this.overlay.show();
		this.overlay.observe('click', function(evt) {
			bb.modal.close();
			bb.modal.overlay.stopObserving('click');
		});
		if (center === true){
			this.center(element);
			Event.observe(window, 'scroll', function() {
				this.center(element);
			}.bind(this));
		};
		element.addClassName(this.options.className);
		new Effect.Appear(element, {duration: bb.modal.options.fadeOut});
	},
	
	close: function (element) {
		element = $id(element);
		if (!element) {
			$$('.'+this.options.className).each(function(element) {
				new Effect.Fade(element, {duration: bb.modal.options.fadeIn, afterFinish: function(){bb.modal.overlay.hide()}});
			});
		} else {
			new Effect.Fade(element, {duration: bb.modal.options.fadeIn, afterFinish: function(){bb.modal.overlay.hide()}});
		};
		Event.stopObserving(document, 'scroll');
		this.reset();
	},
	
	toggle: function (element, center, screen) {
		try{element = $id(element);}catch(e){return;};
		if (element.visible()) {
			this.close(element);
		} else {
			this.open(element, center, screen);
		};
	},
	
	reset: function (options) {
		var options = Object.extend(this.options, options || {});
		this.overlay.removeClassName('screen');
		this.overlay.id = options.overlayId;
		classNames = $w(this.overlay.className);
		for (i = 0; i < classNames.length; i++) {
			this.overlay.removeClassName(classNames[i]);
		};
		this.overlay.addClassName(options.overlayClassName);
		this.overlay.style.position = 'absolute';
		this.overlay.style.backgroundColor = '';
		this.overlay.style.zIndex = options.overlayZIndex;
		this.overlay.style.display = 'none';
		this.overlay.setOpacity(options.overlayOpacity);
	},
	
	updateOverlayHeight: function () {
		this.overlay.style.height = this.getPageSizeWithScroll() + 'px';
	},
	
	center: function (element) {
		try{element = $id(element);}catch(e){return;};
		my_width	= document.viewport.getWidth();
		my_height	= document.viewport.getHeight();
		scrollY		= document.viewport.getScrollOffsets().top;
		elementDimensions = Element.getDimensions(element);
		setX = ( my_width  - elementDimensions.width  ) / 2;
		setY = ( my_height - elementDimensions.height ) / 2 + scrollY;
		setX = ( setX < 0 ) ? 0 : setX;
		setY = ( setY < 0 ) ? 0 : setY;
		element.style.position	= 'absolute';
		element.style.zIndex	= this.options.overlayZIndex + 1;
		element.style.left		= setX + "px";
		element.style.top		= setY + "px";
	},
	
	getPageSizeWithScroll: function () {
		if (window.innerHeight && window.scrollMaxY) {// Firefox
			yWithScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			yWithScroll = document.body.scrollHeight;
		} else { // works in Explorer 6 Strict, Mozilla (not FF) and Safari
			yWithScroll = document.body.offsetHeight;	
		}
		return yWithScroll;
	},
	
	// has to run after DOM:loaded
	init: function () {
		if (this.overlay == null) {
			this.overlay = new Element('div', {'id': this.options.overlayId, 'class': this.options.overlayClassName, 'style': 'position:absolute; z-index:'+this.options.overlayZIndex+'; display:none;'});
			this.overlay.setOpacity(this.options.overlayOpacity);
			
			var body_tag = document.getElementsByTagName('body')[0];
			Element.extend(body_tag);
			body_tag.insert(this.overlay);
			
			this.updateOverlayHeight();
			
			this.loader = new Element('div', {'id': 'bb-loader', 'style': 'display:none; z-index:'+this.options.overlayZIndex+1+';'});
			document.body.insert(this.loader);
		};
		
		/* observe links */
		
		/* 
		open modal
		must be an anchor of class bb-modal-open. require href= '#' + id of element to open
		*/
		$$('.bb-modal-open').each(function(node) {
			var element = node.readAttribute('href').substring(node.readAttribute('href').indexOf('#') + 1);
				element = $id(element);
			var width = element.getWidth() + parseInt(element.getStyle('padding-left').sub('px','')) + parseInt(element.getStyle('padding-right').sub('px',''));
			var height = element.getHeight() + parseInt(element.getStyle('padding-top').sub('px','')) + parseInt(element.getStyle('padding-bottom').sub('px',''));
			var options = {
				containerClassName: element.className,
				width: width,
				height: height
			};

			if (element.id == 'bb-city-bar-more-cities') {
				options.position = 'relative';
				options.opacity = 0;
				options.offsetTop = 20;
				options.width = 206;
			};
			new Control.Modal(node, options);
//			el.observe('click', function(evt) {
//				evt.stop();
//				element = this.readAttribute('href').substring(this.readAttribute('href').indexOf('#') + 1);
//				bb.modal.open(element);
//			});
		});
		/* 
		close modal
		must be an anchor of class bb-modal-close. require href= '#' + id of element to close
		*/
		$$('.bb-modal-close').each(function(el) {
			Control.Modal.close();
//			el.observe('click', function(evt) {
//				evt.stop();
//				element = this.readAttribute('href').substring(this.readAttribute('href').indexOf('#') + 1);
//				bb.modal.close(element);
//			});
		});
	}
};

/**
 *	bb.misc
 *	miscelaneous methods
 */
bb.misc = {
	// bb.misc.pop(t, n, o)
	pop: function(target, name, options) {
		
		if (target==null) return false;
		
		var name = (name==null) ? 'popup' : name;
		
		var options = Object.extend({
			width: 900,
			height: 600,
			left: 150,
			top: 10,
			screenX: 200,
			screenY: 30,
			toolbar: 0,
			location: 0,
			directories: 0,
			resizable: 1,
			status: 0,
			menubar: 0,
			scrollbars: 1
		}, options || {});
		
		var o = Object.toQueryString(options).gsub('&',',');
		
		console.log(o);
		
		var popup = window.open(target, name, o);
		if (window.focus) {
			popup.focus();
		};
		return false;
	},
	// bb.misc.backToTop()
	backToTop: function() {
		var x1 = x2 = x3 = 0;
		var y1 = y2 = y3 = 0;
		if (document.documentElement) {
			x1 = document.documentElement.scrollLeft || 0;
			y1 = document.documentElement.scrollTop || 0;
		};
		if (document.body) {
			x2 = document.body.scrollLeft || 0;
			y2 = document.body.scrollTop || 0;
		};
		x3 = window.scrollX || 0;
		y3 = window.scrollY || 0;
		var x = Math.max(x1, Math.max(x2, x3));
		var y = Math.max(y1, Math.max(y2, y3));
		window.scrollTo(Math.floor(x / 2), Math.floor(y / 2));
		if (x > 0 || y > 0) {
			window.setTimeout("bb.misc.backToTop()", 25);
		};
		return false;
	}
};

/* ====>  bb init  <==== */
bb.init = function() {
	bb.search.init();
	bb.modal.init();
};

/*
 * Initialize bb
 */
document.observe('dom:loaded', bb.init);

/*
 * Raw URL Encode
 * http://phpjs.org/functions/rawurlencode
 */
function rawurlencode( str ) {
    var histogram = {}, tmp_arr = [];
    var ret = str.toString();
    var replacer = function(search, replace, str) {
        var tmp_arr = [];
        tmp_arr = str.split(search);
        return tmp_arr.join(replace);
    };
    histogram["'"]   = '%27';
    histogram['(']   = '%28';
    histogram[')']   = '%29';
    histogram['*']   = '%2A'; 
    histogram['~']   = '%7E';
    histogram['!']   = '%21';
    ret = encodeURIComponent(ret);
    ret = replacer('%20', ' ', ret);
    for (search in histogram) {
        replace = histogram[search];
        ret = replacer(search, replace, ret);
    };
    return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
        return "%"+m2.toUpperCase();
    });
    return ret;
};

/*
 * Cookie
 */
var Cookie = {
	version: '0.7',
	cookies: {},
	_each: function(iterator) {
		$H(this.cookies).each(iterator);
	},

	getAll: function() {
		this.cookies = {};
		$A(document.cookie.split('; ')).each(function(cookie) {
			var seperator = cookie.indexOf('=');
			this.cookies[cookie.substring(0, seperator)] = 
					unescape(cookie.substring(seperator + 1, cookie.length));
		}.bind(this));
		return this.cookies;
	},

	read: function() {
		var cookies = $A(arguments), results = [];
		this.getAll();
		cookies.each(function(name) {
			if (this.cookies[name]) results.push(this.cookies[name]);
			else results.push(null);
		}.bind(this));
		return results.length > 1 ? results : results[0];
	},

	write: function(cookies, options) {
		if (cookies.constructor == Object && cookies.name) cookies = [cookies];
		if (cookies.constructor == Array) {
			$A(cookies).each(function(cookie) {
				this._write(cookie.name, cookie.value, cookie.expires,
										cookie.path, cookie.domain);
			}.bind(this));
		}else {
			options = options || {expires: false, path: '', domain: ''};
			for (name in cookies){
				this._write(name, cookies[name],
										options.expires, options.path, options.domain);
			}
		}
	},

	_write: function(name, value, expires, path, domain) {
		if (name.indexOf('=') != -1) return;
		var cookieString = name + '=' + escape(value);
		if (expires) cookieString += '; expires=' + expires.toGMTString();
		if (path) cookieString += '; path=' + path;
		if (domain) cookieString += '; domain=' + domain;
		document.cookie = cookieString;
	},

	erase: function(cookies) {
		var cookiesToErase = {};
		$A(arguments).each(function(cookie) {
			cookiesToErase[cookie] = '';
		});

		this.write(cookiesToErase, {expires: (new Date((new Date()).getTime() - 1e11))});
		this.getAll();
	},

	eraseAll: function() {
		this.erase.apply(this, $H(this.getAll()).keys());
	}
};

Object.extend(Cookie, {
	get: Cookie.read,
	set: Cookie.write,

	add: Cookie.read,
	remove: Cookie.erase,
	removeAll: Cookie.eraseAll,

	wipe: Cookie.erase,
	wipeAll: Cookie.eraseAll,
	destroy: Cookie.erase,
	destroyAll: Cookie.eraseAll
});
