
if (typeof mcd === 'undefined' || !('dom' in mcd) || !('event' in mcd)) {
	throw "mcd.Toggler cannot load: Required dependencies could not be found.";
} 

(function () {

	/**
	 * Shortcut to mcd.dom
	 * @private 
	 */
	var D = mcd.dom;
	
	/**
	 * Shortcut to mcd.event
	 * @private 
	 */
	var E = mcd.event;

	/**
	 * The Toggler constructor
	 * @param {String} id
	 * @constructor
	 */
	mcd.Toggler = function (id) {
		this.parent = D.getElement(id);
	};
	
	/**
	 * Shows the toggleable element
	 */
	mcd.Toggler.prototype.show = function () {
		D.removeClass(this.parent, 'hide');
	};
	
	/**
	 * Hides the toggleable element
	 */
	mcd.Toggler.prototype.hide = function () {
		D.addClass(this.parent, 'hide');
	};
	
	/**
	 * Toggles the visibility of the toggleable element
	 */
	mcd.Toggler.prototype.toggle = function () {
		D.toggleClass(this.parent, 'hide');
	};
	
	/**
	 * A manager for toggleable elements
	 */
	mcd.Toggler.manager = {
		/**
		 * An id-organized list of togglers
		 * @type {Object}
		 */
		togglers : {},
		
		/**
		 * A list of toggler triggers organized by the toggler id
		 * @type {Object}
		 */
		triggers : {},
		
		/**
		 * The default trigger class name
		 * @type {String}
		 */
		triggerClass : 'toggler-trigger',
		
		/**
		 * Toggled trigger class name
		 * @type {String}
		 */
		toggledTriggerClass : 'toggled',
		
		/**
		 * Initialization routine
		 * @return
		 */
		init : function () {
			var triggerList = D.getElementsByAttribute('class', this.triggerClass, null, 'a', true);
			
			for (var i = 0; i < triggerList.length; i++) {
				var id = triggerList[i].getAttribute('rel');
				
				if (id) {
					/* Create a new Toggler instance if it doesn't exist 
					 * already */
					if (!(id in this.togglers)) {
						this.togglers[id] = new mcd.Toggler(id);
					}
					
					/* Create a new object to store the triggers if it doesnt
					 * exist already */
					if (!(id in this.triggers)) {
						this.triggers[id] = [];
					}
					
					/* Group the trigger into the triggers list, organized by 
					 * the ID of the Toggler that it controls */
					this.triggers[id].push(triggerList[i]);
					
					/* Apply the callback on the trigger */
					E.add(triggerList[i], 'click', this.triggerCallback);
				}
			}
			
			return this;
		},
		
		triggerCallback : function (event) {
			/* Remote triggers use default */
			if (!D.hasClass(this, 'remote')) {
				E.preventDefault(event);
			}
			
			var togglerId   = this.getAttribute('rel'),
				allTriggers = mcd.Toggler.manager.getTriggers(togglerId);
			
			mcd.Toggler.manager.getToggler(togglerId).toggle();
			
			for (var i = 0; i < allTriggers.length; i++) {
				D.toggleClass(allTriggers[i], mcd.Toggler.manager.toggledTriggerClass);
			}
		},
		
		/** 
		 * Gets a specific toggler
		 * @param {String} id
		 * @return mcd.Toggler
		 */
		getToggler : function (id) {
			if (id in this.togglers) {
				return this.togglers[id];
			}
		},
		
		getTriggers : function (togglerId) {
			if (togglerId in this.triggers) {
				return this.triggers[togglerId];
			}
		},
		
		/**
		 * Hides all togglers
		 */
		hideAll : function () {
			for (var i in this.togglers) {
				this.togglers[i].hide();
			}
		},
		
		/**
		 * Shows all togglers
		 */
		showAll : function () {
			for (var i in this.togglers) {
				this.togglers[i].show();
			}
		},
		
		/**
		 * Toggles the visibility of all togglers
		 */
		toggleAll : function () {
			for (var i in this.togglers) {
				this.togglers[i].toggle();
			}
		}
	};

})();
