/**
* Megadropdown - jQuery plugin to create dropdown menus.
*
* @author Rocco Janse, <rocco@efocus.nl>
* @since 14 apr 2010
* @version 1.0
* @package Megadropdown
* @requires jQuery v1.4 or above
* @uses jCarousel
*/

(function($) {

	// return chainable element collections	
	$.fn.megadropdown = function(options) {
		return this.each(function() {
			new $mmdd(this, options);
		});
	};

	// defaults
	var defaults = {
		name: null,
		container: null,
		dropdowns: null,
		items: [],
		onComplete: null,
		onOpen: null,
		onClose: null
	};

	// logic of the megadropdown object
	$.megadropdown = function(el, options) {

		// extend options
		this.options = $.extend({}, defaults, options || {});

		// add element as trigger
		this.trigger = el;

		// add container element
		this.container = this.options.container;

		// only if current container exists, to prevent errors
		if (this.container.length != 0) {
		
			this.container.css('display', 'block');

			// get dropdown items
			this.getItems();

			// add highlighting effect on items
			this.initHighLighting();

			// add events to triggers
			this.initTrigger();

			// add events to dropdowns
			this.initDropdown();

			// add events to closebutton, if found
			this.initCloseButton();

			// we have to start our carousel here
			// otherwise we get a infinite loop error (jCarousel)
			if ($(this.container).find('div.carrousel').length > 0 == true) {
				$(this.container).find('div.carrousel').each(function() {

					$(this).jcarousel({
						visible: 5,
						scroll: 5,
						easing: 'easeOutExpo',
						buttonNextHTML: $(this).find('a.next'),
						buttonPrevHTML: $(this).find('a.previous'),
						buttonNextEvent: 'mouseover',
						buttonPrevEvent: 'mouseover'
					});
					
					$(this).find('a.next').removeAttr('href');
					$(this).find('a.previous').removeAttr('href');

				});
			}

			// hide current dropdown
			this.hide();
		}

		// callback init complete
		if (this.options.onComplete != null) {
			this.options.onComplete(this, 'init');
		}

	}

	// create shortcut for internal use
	var $mmdd = $.megadropdown;
	$mmdd.fn = $mmdd.prototype
	$mmdd.fn.extend = $mmdd.extend = $.extend;

	// methods
	$mmdd.fn.extend({

		/**
		* sets up the triggers to open or close dropdown
		* @return void
		*/
		initTrigger: function() {
			$(this.trigger).unbind();
			$(this.trigger).bind({
				'mouseover': $.proxy(function() {
					this.open();
				}, this),
				'mouseleave': $.proxy(function(event) {
					this.close(event);
				}, this)
			});
		},

		/**
		* sets up the dropdown container
		* @return void
		*/
		initDropdown: function() {
			$(this.container).addClass('js-position');
			$(this.container).unbind();
			$(this.container).bind({
				'mouseleave': $.proxy(function(event) {
					this.close(event);
				}, this)
			});
		},

		/**
		* adds close method to close button (if found)
		* @return void
		*/
		initCloseButton: function() {
			$(this.container).find('a.close').unbind();
			$(this.container).find('a.close').bind({
				'click': $.proxy(function(event) {
					event.stopImmediatePropagation();
					this.close();
				}, this)
			});
		},

		/**
		* adds highlight (fade) effect to list items
		* @author Klaas Dieleman (klaas[AT]efocus.nl)
		* @since 1.1, 7 may 2010
		* @return void
		*/
		initHighLighting: function() {
			if (this.items.length > 0) {
				
				// fade out all but first by default
				$(this.items).not(':first-child').css('opacity', 0.5);
				
				$(this.items).each($.proxy(function(index, item) {

					// add events
					$(item).unbind();
					$(item).bind({
						'mouseenter': $.proxy(function() {
							$(this.items).css('opacity', 0.5);
							
							$(item).clearQueue();
							$(item).fadeTo('fast', 1);
						}, this),
						'mouseleave': function() {
							$(item).fadeTo('fast', 0.5);
						}
					});
				}, this));

			}
		},

		/**
		* get items of current dropdown
		* @return void
		*/
		getItems: function() {
			if (this.options.items.length == 0) {
				var arrModels = $(this.container).find('.model').not('.last');
				var arrSlides = $(this.container).find('.slide');
				if (arrModels.length > 0) {
					this.items = arrModels;
				} else if (arrSlides.length > 0) {
					this.items = arrSlides;
				} else {
					this.items = [];
				}
			} else {
				this.items = this.options.items;
			}
		},

		/**
		* opens current dropdown
		* @return void
		*/
		open: function() {

			// change height, not set to 'hide' to prevent IE bugs
			//$(this.container).show();
			$(this.container).css('height', '301px');
			$(this.trigger).addClass('active');

			// callback close complete
			if (this.options.onOpen != null) {
				this.options.onOpen(this, 'opened');
			}
		},

		/**
		* hides current dropdown
		* @return void
		*/
		hide: function() {
			// change height, not set to 'hide' to prevent IE bugs
			//$(this.container).hide();
			$(this.container).css('height', 0);
		},

		/**
		* closes current dropdown
		* @return void
		*/
		close: function(event) {

			// get current mouse position and determine if mouse is over the dropdown element
			if (event) {
				var mouse_y = event.pageY;
				var mouse_x = event.pageX;
				var min_y = this.container.offset().top;
				var max_y = this.container.offset().top + this.container.height();
				var min_x = this.container.offset().left;
				var max_x = this.container.offset().left + this.container.width();
				// mouse is inside, return
				if (mouse_y >= min_y && mouse_y < max_y && mouse_x >= min_x && mouse_x < max_x) {
					return;
				}
			}

			// do hiding
			//$(this.container).hide();
			// change height, not set to 'hide' to prevent IE bugs
			$(this.container).css('height', 0);
			$(this.trigger).removeClass('active');

			// callback close complete
			if (this.options.onClose != null) {
				this.options.onClose(this, 'closed');
			}

		},

		/**
		* debug method to test vars
		* @return string debug data
		*/
		debug: function() {
			console.log(this.options.name);
			console.log(this.trigger);
			console.log(this.container);
			console.log(this.items);
			console.log(this.options);
		}
	});
})(jQuery);