1/**
2* Gumby Framework
3* ---------------
4*
5* Follow @gumbycss on twitter and spread the love.
6* We worked super hard on making this awesome and released it to the web.
7* All we ask is you leave this intact. #gumbyisawesome
8*
9* Gumby Framework
10* http://gumbyframework.com
11*
12* Built with love by your friends @digitalsurgeons
13* http://www.digitalsurgeons.com
14*
15* Free to use under the MIT license.
16* http://www.opensource.org/licenses/mit-license.php
17*/
18!function($) {
19
20	'use strict';
21
22	function Gumby() {
23		this.$dom = $(document);
24		this.$html = this.$dom.find('html');
25		this.isOldie = !!this.$html.hasClass('oldie');
26		this.click = 'click';
27		this.onReady = this.onOldie = this.onTouch = false;
28		this.autoInit = $('script[gumby-init]').attr('gumby-init') === 'false' ? false : true;
29		this.debugMode = Boolean($('script[gumby-debug]').length);
30		this.touchDevice = !!(Modernizr.touch || window.navigator.userAgent.indexOf("Windows Phone") > 0);
31		this.gumbyTouch = false;
32		this.touchEvents = 'js/libs';
33		this.breakpoint = Number($('script[gumby-breakpoint]').attr('gumby-breakpoint')) || 768;
34		this.touchEventsLoaded = false;
35		this.uiModulesReady = false;
36		this.uiModules = {};
37		this.inits = {};
38
39		// jQuery mobile touch events
40		var touch = $('script[gumby-touch]').attr('gumby-touch'),
41			path = $('script[gumby-path]').attr('gumby-path');
42
43		// do not use touch events
44		if(touch === 'false') {
45			this.touchEvents = false;
46
47		// set path to jQuery mobile
48		// support touch/path attrs for backwards compatibility
49		} else {
50			if(touch) {
51				this.touchEvents = touch;
52			} else if(path) {
53				this.touchEvents = path;
54			}
55		}
56
57		// update click property to bind to click/tap
58		if(this.touchDevice) {
59			this.click += ' tap';
60		}
61
62		// add gumby-touch/gumby-no-touch classes
63		// gumby touch == touch enabled && smaller than defined breakpoint
64		if(this.touchDevice && $(window).width() < this.breakpoint) {
65			this.$html.addClass('gumby-touch');
66			this.gumbyTouch = true;
67		} else {
68			this.$html.addClass('gumby-no-touch');
69		}
70
71		if(this.debugMode) {
72			this.debug('Gumby is in debug mode');
73		}
74	}
75
76	// initialize Gumby
77	Gumby.prototype.init = function(options) {
78		var scope = this,
79			opts = options ? options : {};
80
81		// call ready() code when dom is ready
82		this.$dom.ready(function() {
83			if(opts.debug) {
84				scope.debugMode = true;
85			}
86
87			scope.debug("Initializing Gumby");
88
89			// init UI modules
90			var mods = opts.uiModules ? opts.uiModules : false;
91			scope.initUIModules(mods);
92
93			if(scope.onReady) {
94				scope.onReady();
95			}
96
97			// call oldie() callback if applicable
98			if(scope.isOldie && scope.onOldie) {
99				scope.onOldie();
100			}
101
102			// call touch() callback if applicable
103			if(Modernizr.touch && scope.onTouch) {
104				scope.onTouch();
105			}
106		});
107
108		return this;
109	};
110
111	Gumby.prototype.helpers = function() {
112		if(this.onReady) {
113			this.onReady();
114		}
115
116		// call oldie() callback if applicable
117		if(this.isOldie && this.onOldie) {
118			this.onOldie();
119		}
120
121		// call touch() callback if applicable
122		if(Modernizr.touch && this.onTouch) {
123			this.onTouch();
124		}
125	};
126
127	// public helper - set Gumby ready callback
128	Gumby.prototype.ready = function(code) {
129		if(code && typeof code === 'function') {
130			this.onReady = code;
131		}
132
133		return this;
134	};
135
136	// public helper - set oldie callback
137	Gumby.prototype.oldie = function(code) {
138		if(code && typeof code === 'function') {
139			this.onOldie = code;
140		}
141
142		return this;
143	};
144
145	// public helper - set touch callback
146	Gumby.prototype.touch = function(code) {
147		if(code && typeof code === 'function') {
148			this.onTouch = code;
149		}
150
151		return this;
152	};
153
154	// print to console if available and we're in debug mode
155	Gumby.prototype.console = function(type, data) {
156		if(!this.debugMode || !window.console) { return; }
157		console[console[type] ? type : 'log'](data.length > 1 ? Array.prototype.slice.call(data) : data[0]);
158	};
159
160	// pass args onto console method for output
161	Gumby.prototype.log = function() { this.console('log', arguments); };
162	Gumby.prototype.debug = function() { this.console('debug', arguments); };
163	Gumby.prototype.warn = function() { this.console('warn', arguments); };
164	Gumby.prototype.error = function() { this.console('error', arguments); };
165
166	// public helper - return debuggin object including uiModules object
167	Gumby.prototype.dump = function() {
168		return {
169			$dom: this.$dom,
170			isOldie: this.isOldie,
171			touchEvents: this.touchEvents,
172			debugMode: this.debugMode,
173			autoInit: this.autoInit,
174			uiModules: this.uiModules,
175			click: this.click
176		};
177	};
178
179	// grab attribute value, testing data- gumby- and no prefix
180	Gumby.prototype.selectAttr = function() {
181		var i = 0;
182
183		// any number of attributes can be passed
184		for(; i < arguments.length; i++) {
185			// various formats
186			var attr = arguments[i],
187				dataAttr = 'data-'+arguments[i],
188				gumbyAttr = 'gumby-'+arguments[i];
189
190			// first test for data-attr
191			if(this.is('['+dataAttr+']')) {
192				return this.attr(dataAttr) ? this.attr(dataAttr) : true;
193
194			// next test for gumby-attr
195			} else if(this.is('['+gumbyAttr+']')) {
196				return this.attr(gumbyAttr) ? this.attr(gumbyAttr) : true;
197
198			// finally no prefix
199			} else if(this.is('['+attr+']')) {
200				return this.attr(attr) ? this.attr(attr) : true;
201			}
202		}
203
204		// none found
205		return false;
206	};
207
208	// add an initialisation method
209	Gumby.prototype.addInitalisation = function(ref, code) {
210		this.inits[ref] = code;
211	};
212
213	// initialize a uiModule, single / array of module refs
214	Gumby.prototype.initialize = function(ref, all) {
215		if(typeof ref === 'object') {
216			var i = 0;
217			for(i; i < ref.length; i++) {
218				if(!this.inits[ref[i]] || typeof this.inits[ref[i]] !== 'function') {
219					this.error('Error initializing module: '+ref[i]);
220					continue;
221				}
222
223				this.inits[ref[i]](all);
224			}
225		} else if(this.inits[ref] && typeof this.inits[ref] === 'function') {
226			this.inits[ref](all);
227		} else {
228			this.error('Error initializing module: '+ref);
229		}
230
231		return this;
232	};
233
234	// store a UI module
235	Gumby.prototype.UIModule = function(data) {
236		var module = data.module;
237		this.uiModules[module] = data;
238	};
239
240	// loop round and init all UI modules
241	Gumby.prototype.initUIModules = function(mods) {
242		var x, m, arr = this.uiModules;
243
244		// only initialise specified modules
245		if(mods) {
246			arr = mods;
247		}
248
249		// initialise everything
250		for(x in arr) {
251			m = mods ? arr[x] : x;
252			this.uiModules[m].init();
253		}
254	};
255
256	window.Gumby = new Gumby();
257
258}(jQuery);
259