/**
 * jquery.dlmenu.js v1.0.1
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright 2013, Codrops
 * http://www.codrops.com
 */
;( function( $, window, undefined ) {

	'use strict';

	// global
	var Modernizr = window.Modernizr, $body = $( 'body' );

	$.DLMenu = function( options, element ) {
		this.$el = $( element );
		this._init( options );
	};

	// the options
	$.DLMenu.defaults = {
		// classes for the animation effects
		animationClasses : { classin : 'dl-animate-in-1', classout : 'dl-animate-out-1' },
		// callback: click a link that has a sub menu
		// el is the link element (li); name is the level name
		onLevelClick : function( el, name ) { return false; },
		// callback: click a link that does not have a sub menu
		// el is the link element (li); ev is the event obj
		onLinkClick : function( el, ev ) { return false; },
		backLabel: 'Back',
		// Change to "true" to use the active item as back link label.
		useActiveItemAsBackLabel: false,
		// Change to "true" to add a navigable link to the active item to its child
		// menu.
		useActiveItemAsLink: false,
		// On close reset the menu to root
		resetOnClose: true
	};

	$.DLMenu.prototype = {
		_init : function( options ) {

			// options
			this.options = $.extend( true, {}, $.DLMenu.defaults, options );
			// cache some elements and initialize some variables
			this._config();

			var animEndEventNames = {
					'WebkitAnimation' : 'webkitAnimationEnd',
					'OAnimation' : 'oAnimationEnd',
					'msAnimation' : 'MSAnimationEnd',
					'animation' : 'animationend'
				},
				transEndEventNames = {
					'WebkitTransition' : 'webkitTransitionEnd',
					'MozTransition' : 'transitionend',
					'OTransition' : 'oTransitionEnd',
					'msTransition' : 'MSTransitionEnd',
					'transition' : 'transitionend'
				};
			// animation end event name
			this.animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ] + '.dlmenu';
			// transition end event name
			this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ] + '.dlmenu';
			// support for css animations and css transitions
			this.supportAnimations = Modernizr.cssanimations;
			this.supportTransitions = Modernizr.csstransitions;

			this._initEvents();

		},
		_config : function() {
			this.open = false;
			this.$trigger = this.$el.children( '.dl-trigger' );
			this.$menu = this.$el.children( 'ul.dl-menu' );
			this.$menuitems = this.$menu.find( 'li:not(.dl-back)' );
            this.$el.find( 'ul.dl-menu' ).prepend( '<li class="dl-back"><a href="#"><span class="sr-only">empty space  </span></a><a href="#" class="dl-close-link">CLOSE</a></li>' );
            this.$el.find( 'ul.dl-submenu' ).prepend( '<li class="dl-back"><a href="#"class="dl-back-link">BACK</a><a href="#" class="dl-close-link">CLOSE</a></li>' );
			this.$back = this.$menu.find( 'li a.dl-back-link' );
		},
		_initEvents : function() {

			var self = this;

			this.$trigger.on( 'click.dlmenu', function() {
				if( self.open ) {
					self._closeMenu();
				}
				else {
					self._openMenu();
                    $('a.dl-close-link').on( 'click.dlmenu', function() {
                        self._closeMenu() ;
                    } );
					// clicking somewhere else makes the menu close
					$body.off( 'click' ).children().on( 'click.dlmenu', function() {
						self._closeMenu() ;
					} );

				}
				return false;
			} );

			this.$menuitems.on( 'click.dlmenu', function( event ) {

				event.stopPropagation();

				var $item = $(this),
					$submenu = $item.children( 'ul.dl-submenu' );

				// Only go to the next menu level if one exists AND the link isn't the
				// one we added specifically for navigating to parent item pages.
                var target = $( event.target );
                if (target.is( ".expand" ) ) {
                    if (($submenu.length > 0) && !($(event.currentTarget).hasClass('dl-subviewopen'))) {

                        var $flyin = $submenu.clone().css('opacity', 0).insertAfter(self.$menu),
                            onAnimationEndFn = function () {
                                self.$menu.off(self.animEndEventName).removeClass(self.options.animationClasses.classout).addClass('dl-subview');
                                $item.addClass('dl-subviewopen').parents('.dl-subviewopen:first').removeClass('dl-subviewopen').addClass('dl-subview');
                                $flyin.remove();
                            };

                        setTimeout(function () {
                            $flyin.addClass(self.options.animationClasses.classin);
                            self.$menu.addClass(self.options.animationClasses.classout);
                            if (self.supportAnimations) {
                                self.$menu.on(self.animEndEventName, onAnimationEndFn);
                            }
                            else {
                                onAnimationEndFn.call();
                            }

                            self.options.onLevelClick($item, $item.children('span.expand').text());
                        });

                        return false;

                    }
                    else {
                        self.options.onLinkClick($item, event);
                    }
                }
			} );

			this.$back.on( 'click.dlmenu', function( event ) {

				var $this = $( this ),
					$submenu = $this.parents( 'ul.dl-submenu:first' ),
					$item = $submenu.parent(),

					$flyin = $submenu.clone().insertAfter( self.$menu );

				var onAnimationEndFn = function() {
					self.$menu.off( self.animEndEventName ).removeClass( self.options.animationClasses.classin );
					$flyin.remove();
				};

				setTimeout( function() {
					$flyin.addClass( self.options.animationClasses.classout );
					self.$menu.addClass( self.options.animationClasses.classin );
					if( self.supportAnimations ) {
						self.$menu.on( self.animEndEventName, onAnimationEndFn );
					}
					else {
						onAnimationEndFn.call();
					}

					$item.removeClass( 'dl-subviewopen' );

					var $subview = $this.parents( '.dl-subview:first' );
					if( $subview.is( 'li' ) ) {
						$subview.addClass( 'dl-subviewopen' );
					}
					$subview.removeClass( 'dl-subview' );
				} );

				return false;

			} );

		},
		closeMenu : function() {
			if( this.open ) {
				this._closeMenu();
			}
		},
		_closeMenu : function() {
			var self = this,
				onTransitionEndFn = function() {
					self.$menu.off( self.transEndEventName );
					if( self.options.resetOnClose ){
						self._resetMenu();
					}
				};

			this.$menu.removeClass( 'dl-menuopen' );
			this.$menu.addClass( 'dl-menu-toggle' );
			this.$trigger.removeClass( 'dl-active' );
            this.$trigger.parent('.dl-menuwrapper').css('height', '0');
            this.$trigger.parent().siblings('.overlay-container').hide();

			if( this.supportTransitions ) {
				this.$menu.on( this.transEndEventName, onTransitionEndFn );
			}
			else {
				onTransitionEndFn.call();
			}

			this.open = false;
		},
		openMenu : function() {
			if( !this.open ) {
				this._openMenu();
			}
		},
		_openMenu : function() {
			var self = this;
			// clicking somewhere else makes the menu close
            $('a.dl-close-link').on( 'click.dlmenu', function() {
                self._closeMenu() ;
            } );
			$body.off( 'click' ).on( 'click.dlmenu', function() {
				self._closeMenu() ;
			} );
            this.$trigger.parent().siblings('.overlay-container').show();
            this.$trigger.parent('.dl-menuwrapper').css('height', 'auto');
			this.$menu.addClass( 'dl-menuopen dl-menu-toggle' ).on( this.transEndEventName, function() {
				$( this ).removeClass( 'dl-menu-toggle' );
			} );
			this.$trigger.addClass( 'dl-active' );
			this.open = true;
            if ($('#dl-menu').find('li.active-trail').length) {
                $('#dl-menu ul.dl-menu').addClass('dl-subview');
                $('li.active-trail').addClass('dl-subview');
                $('a.active').parent().removeClass('dl-subview').parent().parent().removeClass('dl-subview').addClass('dl-subviewopen');
            }
		},
		// resets the menu to its original state (first level of options)
		_resetMenu : function() {
			this.$menu.removeClass( 'dl-subview' );
			this.$menuitems.removeClass( 'dl-subview dl-subviewopen' );
		}
	};

	var logError = function( message ) {
		if ( window.console ) {
			window.console.error( message );
		}
	};

	$.fn.dlmenu = function( options ) {
		if ( typeof options === 'string' ) {
			var args = Array.prototype.slice.call( arguments, 1 );
			this.each(function() {
				var instance = $.data( this, 'dlmenu' );
				if ( !instance ) {
					logError( "cannot call methods on dlmenu prior to initialization; " +
					"attempted to call method '" + options + "'" );
					return;
				}
				if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
					logError( "no such method '" + options + "' for dlmenu instance" );
					return;
				}
				instance[ options ].apply( instance, args );
			});
		}
		else {
			this.each(function() {
				var instance = $.data( this, 'dlmenu' );
				if ( instance ) {
					instance._init();
				}
				else {
					instance = $.data( this, 'dlmenu', new $.DLMenu( options, this ) );
				}
			});
		}
		return this;
	};

} )( jQuery, window );