
/* Copyright (c) 2011 der|Design */

(function($) {

	/* Runtime Class */

	function RuntimeClass(options) {

		var self = this;

		var globals = {};

		var counters = {};

		var cache = null;

		self.classes = {};

		self.options = options;

		self.window = $(window);

		self.objects = {};

		self.core = { creator: {} };

		/* Create Objects Hook
		 * -------------------
		 * Creator function that expects a function object with the following parameters: (object_type, class_fn, trigger_items)
		 * @object_type: unique ID identifier for object
		 * @class_fn: Class to be used to generate the object
		 * @trigger_items: jQuery collection of items
		 * @default_creator: Boolean value to determine if a default creator is to be used
		 *
		 * Creator functions should be assigned to Der.core.creator[object_type]. */

		this.create_objects = function(object_type, class_fn, trigger_items, use_default_creator) { // Requires DOM to be ready.

			if ( isset(use_default_creator) && use_default_creator == true ) { self.core.creator[object_type] = default_creator; }

			if ( self.core.creator.hasOwnProperty(object_type) ) {

				self.objects[object_type] = [];

				self.core.creator[object_type](object_type, class_fn, trigger_items);

			}

		}

		/* Default Creator (private)
		 * -------------------------
		 * Function to be used when default procedures should be executed.
		 * Useful if object creation process is not different. */

		function default_creator(object_type, class_fn, selector) {

			$(selector).each(function(i) {

				var options = $(this).find('span.options');

				if ( options.length ) {

					options = decode_option( options.html() );

				} else { options = {};  }

				self.objects[object_type].push( new class_fn(i, object_type, options, $(this) ) );

			});

		}

		this.set_object_content = function(object_type, object) {

			if ( ! isset(counters[object_type]) ) {

				counters[object_type] = 0;

			}

			var id = counters[object_type];

			self.objects[object_type][id].set_content(object);

			counters[object_type]++;

		}

		this.hide_visible_popups = function(type) {

			for (var i=0; i < self.objects[type].length; i++) {

				self.objects[type][i].hide();

			}

		}

		this.set = function(a, b, c) {  // a: slot, b: name, c: val

			if ( isset(c) ) {

				if ( ! isset(globals[a]) ) {

					globals[a] = {};

				}

				globals[a][b] = c;
				
				return c;

			} else { // a: name, b: val, c: undefined

				globals[a] = b;
				
				return b;

			}

		}

		this.get = function(a, b) { // a: slot, b: name

			try {

				if ( isset( b ) ) {

					return globals[a][b];

				} else { // a: name, b: undefined

					return globals[a];

				}

			} catch(e) {  } // catch TypeError

		}
		
		this.is = function(a, b) { // Compare boolean values
			
			return self.get(a, b);
			
		}
		
		this.get_option = function(option) {

			return options[option];

		}

		this.lock = function(context, timeout) {

			self.set(context, 'locked', true);

			if ( isset(timeout) ) {

				setTimeout(self.unlock, timeout, context);

			}

		}

		this.unlock = function(context) {

			self.set(context, 'locked', false);

		}

		this.locked = function(context) {

			return self.get(context, 'locked');
			
		}

		this.set_cookie = function(name, value, expires) {

			expires = ( isset(expires) ) ? expires : { expires: 365, path: '/' };

			$.cookie( name, value, expires );

		}

		this.get_cookie = function(name) {

			return $.cookie( name );

		}

		this.delete_cookie = function(name) {

			$.cookie(name, null, { path: '/' });

		}
		
	}
	
	function IE_Detect() {
		
		var self = this;
		
		var version = (function() {
			
			var re = /MSIE (\d+)\./;
				
			var match = navigator.appVersion.match(re);
				
			if ( match ) { return parseInt(match[1]); }
			
			else { return null; }
			
		})()
		
		self.version = function() { return version; }
		
		self.is_ie = function() { return version != null; }
		
		/* The following methods uses Internet Explorer's Conditional Comments comparison syntax:
		 * http://msdn.microsoft.com/en-us/library/ms537512(v=vs.85).aspx */
		
		self.e = function(v) { return (version) ? version == parseInt(v) : false; }  // Equals
		
		self.is = self.e; // Method alias
		
		self.gt = function(v) { return (version) ? version > parseInt(v) : false; } // Greater than
		
		self.gte = function(v) { return (version) ? version >= parseInt(v) : false; }  // Greater than or equals
		
		self.lt = function(v) { return (version) ? version < parseInt(v) : false; } // Less than
		
		self.lte = function(v) { return (version) ? version <= parseInt(v) : false; }  // Less than or equals
		
	}
	
	window.Der = new RuntimeClass(MilkyOptions);

	/* Initialization Code */

	queue_ready_fn(function() {

		Der.ie = new IE_Detect();
		
		Der.set('not_ie', ! $.browser.msie );
		
		Der.set('modern_browser', ( ! $.browser.msie || Der.ie.gte(9) ));
		
		Der.fallback = function(val) { return (Der.is('modern_browser')) ? val : 0; }
		
		Der.set('apple_device', ( navigator.platform == 'iPad' || navigator.platform == 'iPhone' || navigator.platform == 'iPod') );
		
		Der.set('cache', 'body', $('body')); // Store jquery wrapped body on cache

		Der.get('cache', 'body').removeClass('no-js').addClass('js'); // Enable JavaScript (theoretically)

	});

})(jQuery);
