/**
 * mobilize.js
 * 
 * Copyright (c) 2011-12-28 Code 42 Software, Inc.
 * 
 * mobilize.js is a lightweight framework agnostic script that detects if you are on a mobile platform
 * and allows you to render an alternative template into the body and creates custom events for screen rotation, this script should
 * ideally be loaded before anything on the page. mobilize.js only provides what's needed and nothing more.
 * 
 * @usage: 
 * 
 * 	MOBILIZE.init({ tpl: 'path/to/template.html', zoom: true/false });
 * 
 * @events: 
 * 	- mobilize-landscape: triggered after viewport is rotated into landscape orientation
 *  - mobilize-portrait: triggered after viewport is rotated into portrait orientation
 *  - mobilize-template-loaded: triggered after mobile template is loaded
 * 
 * @options:
 *  - tpl: path/name to template file
 *  - zoom: boolean to determine whether or not the user can zoom / scale 
 *  
 * @author Vann Ek, vann@code42.com
 */

(function() {

	/*
		inline inclusion of:
		- css_browser_selector
		- vine: https://github.com/arexkun/Vine
		- microajax: http://code.google.com/p/microajax/
	*/
	function css_browser_selector(a){var b=a.toLowerCase(),d=function(a){return b.indexOf(a)>-1},e="gecko",f="webkit",g="safari",h="opera",i="mobile",j=document.documentElement,k=[!/opera|webtv/i.test(b)&&/msie\s(\d)/.test(b)?"ie ie"+RegExp.$1:d("firefox/2")?e+" ff2":d("firefox/3.5")?e+" ff3 ff3_5":d("firefox/3.6")?e+" ff3 ff3_6":d("firefox/3")?e+" ff3":d("gecko/")?e:d("opera")?h+(/version\/(\d+)/.test(b)?" "+h+RegExp.$1:/opera(\s|\/)(\d+)/.test(b)?" "+h+RegExp.$2:""):d("konqueror")?"konqueror":d("blackberry")?i+" blackberry":d("android")?i+" android":d("chrome")?f+" chrome":d("iron")?f+" iron":d("applewebkit/")?f+" "+g+(/version\/(\d+)/.test(b)?" "+g+RegExp.$1:""):d("mozilla/")?e:"",d("j2me")?i+" j2me":d("iphone")?i+" iphone":d("ipod")?i+" ipod":d("ipad")?i+" ipad":d("mac")?"mac":d("darwin")?"mac":d("webtv")?"webtv":d("win")?"win"+(d("windows nt 6.0")?" vista":""):d("freebsd")?"freebsd":d("x11")||d("linux")?"linux":"","js"];c=k.join(" ");j.className+=" "+c;return c}function microAjax(a,b){this.bindFunction=function(a,b){return function(){return a.apply(b,[b])}};this.stateChange=function(a){if(this.request.readyState==4){this.callbackFunction(this.request.responseText)}};this.getRequest=function(){if(window.ActiveXObject){return new ActiveXObject("Microsoft.XMLHTTP")}else{if(window.XMLHttpRequest){return new XMLHttpRequest}}return false};this.postBody=arguments[2]||"";this.callbackFunction=b;this.url=a;this.request=this.getRequest();if(this.request){var c=this.request;c.onreadystatechange=this.bindFunction(this.stateChange,this);if(this.postBody!==""){c.open("POST",a,true);c.setRequestHeader("X-Requested-With","XMLHttpRequest");c.setRequestHeader("Content-type","application/x-www-form-urlencoded");c.setRequestHeader("Connection","close")}else{c.open("GET",a,true)}c.send(this.postBody)}}css_browser_selector(navigator.userAgent);vine=function(a,b,c,d,e,f,g,h,i){function k(d,e){e=d[a]=d[a]||b++;return c[e]=c[e]||{b:{},e:{}}}function j(a){return a.charAt?g.getElementById(a):a}h={d:k,Event:i=function(a,b,c){c=this;for(b in a)c[b]=c[b]||a[b];c.timestamp=+(new Date),c.target=c.target||c.srcElement},bind:function(a,b,c,g,i,l,m,n){if((n=(m=b.split(" ")).length)>1)while(n--)h.bind(a,m[n],c);else{a=j(a),i=k(a);if(l=/^(.+)\.([^\.]+)$/.exec(b))b=l[2],l=l[1];(i.e[b]=i.e[b]||[]).push({n:l,f:c,d:g||{}}),!i.b[b]&&(i.b[b]=1,a[e]?a[e](b,function(c){h.trigger(a,b,c)[d]&&c.preventDefault()},null):a[f]?a[f]("on"+b,function(){return!h.trigger(a,b,window.event)[d]}):0)}},trigger:function(a,b,c,e,f,h,l,m){a=j(a);if(!c&&a.nodeType){if(!a.fireEvent){h=g.createEvent((init=/click|mousedown|mouseup|mousemove/.test(b))?"MouseEvents":"HTMLEvents"),h[init?"initMouseEvent":"initEvent"](b,!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),a.dispatchEvent(h);return h}try{return new i({defaultPrevented:a[b=="click"?b:fireEvent]("on"+b)})}catch(n){}}h=new i(c||{}),e=k(a).e[b]||[];for(f=0;m=e[f];f++)h.namespace=m.n,h.data=m.d,l=l||m.f.call(a,h)===!1;h[d]=h[d]||l;return h},unbind:function(b,d,e,f,g,h){b=j(b);if(!d)return c[b[a]]=b[a]=null;e=k(b);if(d.charAt)if(d.charAt(0)=="."){d=d.slice(1);for(h in e.e){f=[];for(g=0;g<e.e[h].length;g++)e.e[h][g].n!=d&&f.push(e.e[h][g]);e.e[h]=f}}else e.e[d]=[];else for(h in e.e){f=[];for(g=0;g<e.e[h].length;g++)e.e[h][g].f!=d&&f.push(e.e[h][g]);e.e[h]=f}}},i.prototype={defaultPrevented:!1,preventDefault:function(){this[d]=!0}};return h}(+(new Date),1,{},"defaultPrevented","addEventListener","attachEvent",document)

	window.MOBILIZE = {

		_defaultOpts: {
			tpl: null,
			zoom: false
		},

		/* Quick and dirty version of jQuery's $.extend method */
		_merge: function(to, from) {
		    var newObj = {};
		    for (var attrname in from) { newObj[attrname] = from[attrname]; }
		    for (var attrname in to) { newObj[attrname] = to[attrname]; }
		    return newObj;
		},

		init: function(opts) {
			var self = this;
			if (typeof(opts) != "object") {
				console.log("Options is not an object:",opts);
				return;
			}
			self.options = this._merge(opts,this._defaultOpts);
			var _html = document.querySelector('html');
			var mobileCss = 'margin:0;padding:0;width:100%;height:100%;overflow:"hidden";-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%';	
			var meta = document.createElement('meta');
			var zoomable = self.options.zoom ? 'minimum-scale=0.5, maximum-scale=2.0, user-scalable=yes' : 'maximum-scale=1.0, user-scalable=no';
			var metaContent = 'width=device-width, initial-scale=1.0,'+zoomable;
			meta.name = "viewport";
			meta.content = metaContent;
			
			window.onload = function() {
				if (self.isMobile()) {
					_html.style.cssText = mobileCss;
					document.head.appendChild(meta);
					self.setOrientationChange();				
					self.render(self.options.tpl);
				}
			}
		},

		isMobile: function() {
			var self = this;
			var htmlClasses = document.querySelector('html').className.split(" ");
			return (htmlClasses.indexOf('mobile') == -1) ? false : true;
		},

		render: function(tpl) {
			var self = this;
			var _body = document.querySelector('body');
			microAjax(tpl, function(res) {
				_body.innerHTML = res;
				self.trigger('mobilize-template-loaded');
			});				
		},

		orientationChange: function() {
			var self = this;
			if (window.orientation == 90 || window.orientation == -90) {
				self.addClass('landscape')
					.removeClass('portrait')
					.trigger('mobilize-landscape');
			} else {
				self.addClass('portrait')
					.removeClass('landscape')
					.trigger('mobilize-portrait');
			}
		},
			
		setOrientationChange: function() {
			var self = this;
			var supportsOrientationChange = "onorientationchange" in window,
			 	orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
			self.orientationChange();
			window.addEventListener(orientationEvent, function() {
				self.orientationChange();
			});
		},
		
		addClass: function(klass) {
			var _body = document.querySelector('body');
			var _classAry = _body.className.split(" ");
			_classAry.push(klass);
			_body.className = _classAry.join(" ");
			return this;
		},
		
		removeClass: function(klass) {
			var _body = document.querySelector('body');
			var _classAry = _body.className.split(" ");
			var idx = _classAry.indexOf(klass);
			if (idx != -1) {
				_classAry.splice(idx,1);
				_body.className = _classAry.join(" ");					
			}
			return this;
		},
		
		trigger: function(evt) {
			var _body = document.querySelector('body');
			var self = this;
			vine.trigger(_body,evt);
			return this;
		}		

	};

})();
