/**
 * hashgrid (Mootools version)
 * http://github.com/dotjay/hashgrid (jQuery version)
 * Version 1, 15 June 2010
 * Original JQuery code By Jon Gibbins, accessibility.co.uk
 * Convert to mootools by NAD/, www.nad-design.net
 *
 * // Using a basic #grid setup
 * var grid = new hashgrid();
 *
 * // Using #grid with a custom id (e.g. #mygrid)
 * var grid = new hashgrid("mygrid");
 *
 * // Using #grid with additional options
 * var grid = new hashgrid({
 * 	   container: '',           // Grid's container Element, <body> by default
 *     id: 'mygrid',            // id for the grid container
 *     modifierKey: 'alt',      // optional 'ctrl', 'alt' or 'shift'
 *     showGridKey: 's',        // key to show the grid
 *     holdGridKey: 'enter',    // key to hold the grid in place
 *     foregroundKey: 'f',      // key to toggle foreground/background
 *     jumpGridsKey: 'd',       // key to cycle through the grid classes
 *     numberOfGrids: 2,        // number of grid classes used
 *     classPrefix: 'class',    // prefix for the grid classes
 *     cookiePrefix: 'mygrid'   // prefix for the cookie name
 * });
 */


/**
 * You can call hashgrid from your own code, but it's loaded here by
 * default for convenience.
 */
window.addEvent('domready', function(){

	var grid = new hashgrid({
		numberOfGrids: 2,
		container: $('scrolling_page'),
		id: 'mygrid'           
	});

});


/**
 * hashgrid class
 */

var hashgrid = new Class({
	
	Implements:  [Options], 
	
	//variables setup
		overlayOn: false,
		sticky: false,
		overlayZState: 'B',
		overlayZBackground: -1,
		overlayZForeground: 99999,
		classNumber: 1,
		overlay: null,
		overlayCookie: null,
		state: null,
		
	//options
	options : {
		container: $(document.body),	// Grid's container Element, <body> by default
		id: 'grid',             		// id for the grid container
		modifierKey: null,      		// optional 'ctrl', 'alt' or 'shift'
		showGridKey: 'g',       		// key to show the grid
		holdGridKey: 'h',       		// key to hold the grid in place
		foregroundKey: 'f',     		// key to toggle foreground/background
		jumpGridsKey: 'j',      		// key to cycle through the grid classes
		numberOfGrids: 1,       		// number of grid classes used
		classPrefix: 'grid-',   		// prefix for the grid classes
		cookiePrefix: 'hashgrid'		// prefix for the cookie name
	},
	
	initialize: function(options){
		this.setOptions(options);
		
		// Create overlay, hidden before adding to DOM
		var overlayEl = new Element("div", {id: this.options.id, style: "display: none"});
		overlayEl.inject(this.options.container,'top');
		this.overlay = overlayEl;
	
		// Unless a custom z-index is set, ensure the overlay will be behind everything
		this.overlay.setStyle('z-index', this.overlayZBackground);
	    var size = this.overlay.getParent().getSize();
	    var pageHeight = size.y;
		var pageWidth = size.x;
		
		// Override the default overlay height with the actual page height
		this.overlay.setStyle('height', pageHeight);
		this.overlay.setStyle('width', pageWidth);
	
		// Check for saved state
		this.overlayCookie = readCookie(this.options.cookiePrefix + this.options.id);
		if (typeof this.overlayCookie == 'string') {
			this.state = this.overlayCookie.split(',');
			this.state[2] = Number(this.state[2]);
			if ((typeof this.state[2] == 'number') && !isNaN(this.state[2])) {
				this.classNumber = this.state[2].toFixed(0);
				this.overlay.addClass(this.options.classPrefix + this.classNumber);
			}
			if (this.state[1] == 'F') {
				this.overlayZState = 'F';
				this.overlay.setStyle('z-index', this.overlayZForeground);
			}
			if (this.state[0] == '1') {
				this.overlayOn = true;
				this.sticky = true;
				this.overlay.show();
			}
		}
		else {
			this.overlay.addClass(this.options.classPrefix + this.classNumber)
		}
		
		// Keyboard controls
		self = this;
		window.addEvent('keydown', function(event){
			self.keydownHandler(event.key);
		});
		window.addEvent('keyup', function(event){
			self.keyupHandler(event.key);
		});
	},

	/**
	 * Helpers
	 */

	getModifier: function (e) {
		if (this.options.modifierKey == null) return true; // Bypass by default
		var m = true;
		switch(this.options.modifierKey) {
			case 'ctrl':
				m = (e.ctrlKey ? e.ctrlKey : false);
				break;
			case 'alt':
				m = (e.altKey ? e.altKey : false);
				break;
			case 'shift':
				m = (e.shiftKey ? e.shiftKey : false);
				break;
		}
		return m;
	},

	saveState: function () {
		createCookie(this.options.cookiePrefix + this.options.id, (this.sticky ? '1' : '0') + ',' + this.overlayZState + ',' + this.classNumber, 1);
	},

	/**
	 * Event handlers
	 */

	keydownHandler: function (key) {
		var m = this.getModifier(key);
		if (!m) return true;
		var k = key;
		if (!k) return true;
		switch(k) {
			case this.options.showGridKey:
				if (!this.overlayOn) {
					this.overlay.show();
					this.overlayOn = true;
				}
				else if (this.sticky) {
					this.overlay.hide();
					this.overlayOn = false;
					this.sticky = false;
					this.saveState();
				}
				break;
			case this.options.holdGridKey:
				if (this.overlayOn && !this.sticky) {
					// Turn sticky overlay on
					this.sticky = true;
					this.saveState();
				}
				break;
			case this.options.foregroundKey:
				if (this.overlayOn) {
					// Toggle sticky overlay z-index
					if (this.overlay.getStyle('z-index') == this.overlayZForeground) {
						this.overlay.setStyle('z-index', this.overlayZBackground);
						this.overlayZState = 'B';
					}
					else {
						this.overlay.setStyle('z-index',this. overlayZForeground);
						this.overlayZState = 'F';
					}
					this.saveState();
				}
				break;
			case this.options.jumpGridsKey:
				if (this.overlayOn && (this.options.numberOfGrids > 1)) {
					// Cycle through the available grids
					this.overlay.removeClass(this.options.classPrefix + this.classNumber);
					this.classNumber++;
					if (this.classNumber > this.options.numberOfGrids) this.classNumber = 1;
					this.overlay.addClass(this.options.classPrefix + this.classNumber);
					if (/webkit/.test( navigator.userAgent.toLowerCase() )) {
						forceRepaint();
					}
					this.saveState();
				}
				break;
		}
	},

	keyupHandler: function (key) {
		var m = this.getModifier(key);
		if (!m) return true;
		var k = key;
		if (!k) return true;
		if ((k == this.options.showGridKey) && !this.sticky) {
			this.overlay.hide();
			this.overlayOn = false;
		}
	}

});

/**
 * Cookie functions
 *
 * By Peter-Paul Koch:
 * http://www.quirksmode.org/js/cookies.html
 */
var createCookie = function (name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
};

var readCookie = function (name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
};

var eraseCookie = function (name) {
	createCookie(name,"",-1);
};


/**
 * Forces a repaint (because WebKit has issues)
 * http://www.sitepoint.com/forums/showthread.php?p=4538763
 * http://www.phpied.com/the-new-game-show-will-it-reflow/
 */
var forceRepaint = function () {
	var ss = document.styleSheets[0];
	try {
		ss.addRule('.xxxxxx', 'position: relative');
		ss.removeRule(ss.rules.length - 1);
	} catch(e){}
};


