(function($) {
	jQuery.fn.op_menu = function(userOptions) {
		var defaults = {
			//apply default settings here
			rootPage: op_menu_root,
			taffyDb: op_menu,
			targetDiv: jQuery('#mainNav'),
			levelContentClass: 'levelContent',
			previewContentId: 'previewContent',
			initialized: false,
			showDuration: 200,
			hideDuration: 200,
			timeoutId: 0
		};
		jQuery.fn.op_menu.settings = jQuery.extend({}, defaults, userOptions);

		return this.each(function(){
			jQuery.fn.op_menu.settings.targetDiv.empty();
			var thisMenu = this;
			//var rootLevelPages = jQuery.fn.op_menu.settings.taffyDb.get({pid: op_menu_root});
			var levelTemplate = '';
			createLevel(op_menu_root, jQuery.fn.op_menu.settings.taffyDb.get({uid: op_menu_root}));
			//set this level to be the first one
			setFirstContainer();
			setupBreadcrumb();
			setupListener();
			//no animation for first call
			jQuery.fn.op_menu.settings.initialized = true;
		});
	};

	jQuery.fn.op_menu.settings = {

	};

	/**
	 * private functions
	 */

	function getSetting(key) {
		return jQuery.fn.op_menu.settings[key];
	}
	function setSetting(key, value) {
		jQuery.fn.op_menu.settings[key] = value;
	}

	function setFirstContainer() {
		var level = jQuery('.level', getSetting('targetDiv')).removeClass('first');
		if (level.length === 1) {
			jQuery('#siteNav').removeClass('fullWidth');
		}
		jQuery('.level:first', getSetting('targetDiv')).addClass('first');
	}

	function setupBreadcrumb() {
		var items = jQuery('.rootlineItem a', '#rootline');
		items.each(function(){
			var thisUid = jQuery(this).attr('id').substring(3);
			//test the uid
			var testRecord = jQuery.fn.op_menu.settings.taffyDb.first({'uid': thisUid});
			jQuery(this).mouseover(function(){
				showBcHover(thisUid);
			});
		});
	}

	function setupListener() {
		jQuery('#siteNav').mouseleave(function(){
			var toId = setTimeout(jQuery.op_menu.hideNavi, 3000);
			setSetting('timeoutId', toId);
		});
		jQuery('#siteNav').mouseenter(function(){
			clearTimeout(getSetting('timeoutId'));
		});
	}

	function showBcHover(uid) {
		var recordUid = parseInt(uid);
		var pageStack = [];
		var recordPid = 0;
		var stopPid = op_menu_root;
		var isMenuPage = true;
		var maxLevel = 1;
		while (!isNaN(recordUid) && recordUid !== stopPid) {
			var record = jQuery.fn.op_menu.settings.taffyDb.first({'uid': recordUid});
			maxLevel = Math.max(maxLevel, parseInt(record.level));
			recordUid = parseInt(record.pid);
			if(!isNaN(recordUid) && parseInt(record.uid) != stopPid) {
				pageStack.push(record);
			}
			else {
				isMenuPage = false;
			}
		};

		if (isMenuPage === true) {
			//now traverse the page stack to create the level divs
			pageStack.reverse();
			jQuery('li, a', getSetting('targetDiv')).removeClass('active');
			jQuery(pageStack).each(function(){
				createLevel(this.uid, this, (maxLevel + 1));
				//check the rootline of pages and highlight the active one
				jQuery('#lve-' + this.uid).addClass('active');
				if (this.stop_menu_slideout == 1) {
					return false;
				}
				return true;
			});
		}
	}

	function removeLevels(maxLevel) {
		var maxLevelDiv = jQuery('#level-' + maxLevel);
		var previous = jQuery('#level-' + maxLevel).prevAll();
		previous.animate({ width: '0'}, getSetting('hideDuration'),
				 function(){
					removeLevelsCallback(this);
				});

	}

	function showLevel(elem) {
		jQuery('#siteNav').addClass('fullWidth');
		if (jQuery(elem).hasClass('newLevel')) {
			if (jQuery.fn.op_menu.settings.initialized === true) {
				elem.css({
					'width':0
				});
				elem.siblings().removeClass('first');
				elem.addClass('first');
				elem.animate(
					{
						width: '196'
					},
					getSetting('showDuration'),
					function(){
						showLevelCallback(this);
					}
				);
			}
			elem.removeClass('newLevel');

		}
	}

	function showLevelCallback(elem) {

	}

	function removeLevelsCallback(elem){
		jQuery(elem).remove();
		setFirstContainer();
	}

	function createPreview(targetRecord) {
		var levelId = parseInt(targetRecord.level) + 1;
		var entryDiv = setupLevelDiv(levelId);

		var levelContent = jQuery('<div>', {
			'class':jQuery.fn.op_menu.settings.levelContentClass,
			'id':jQuery.fn.op_menu.settings.previewContentId
		}).appendTo(entryDiv);
		levelContent.data('pid', targetRecord.uid);
		//use dam image, fall back to regular image
		var imageSrc = (targetRecord.ov_dam_image || targetRecord.ov_image);

		if (imageSrc) {
			var image = jQuery('<img />', {
					'src': imageSrc
				});
			var imageLink = jQuery('<a>', {
				'href': targetRecord.url,
				'html': image
			}).appendTo(levelContent);
		}
		//field = tx_ppiopjsmenu_title // nav_title // title
		jQuery('<h2>', {'html': targetRecord.ov_title}).appendTo(levelContent);
		jQuery('<p>', {'html': targetRecord.ov_desc}).appendTo(levelContent);

		jQuery('<a>', {
			'href': targetRecord.url,
			'html': targetRecord.ov_more,
			'id': 'moreLink'
		}).appendTo(levelContent);

		//remove higher levels
		removeLevels(levelId);

		showLevel(entryDiv);

	}

	function createLevel (targetPid, targetRecord, keepLevel){
		var pages = jQuery.fn.op_menu.settings.taffyDb.get({pid: targetPid});

		//analyse target record to determine, what should be shown
		if ((pages.length < 1 || targetRecord.stop_menu_slideout === 1)) {
				// if there is a description entered, show that as a preview
			if (targetRecord.ov_desc !== '') {
				return createPreview(targetRecord);
			}
				//no subpages and no preview or max level reached -> jump to url
			if (!keepLevel) {
				document.location = targetRecord.url;
				return false;
			} else {
				return '';
			}
		}

		var level = parseInt(pages[0].level);
		var removeHigherLevels = level;
		if (!isNaN(parseInt(keepLevel))) {
			removeHigherLevels = Math.max(removeHigherLevels, parseInt(keepLevel));
		}
		//remove higher levels
		removeLevels(removeHigherLevels);

		var entryDiv = setupLevelDiv(level, targetPid);

		if (!entryDiv) {
			return '';
		}

		var entryUl = jQuery('<ul></ul>', {
			'class': jQuery.fn.op_menu.settings.levelContentClass
		}).appendTo(entryDiv);
		//save information, which item this is to not create it twice
		entryUl.data('pid', targetPid);

		jQuery(entryUl).fadeIn('fast');
		if (targetRecord.show_overview_link === 1) {
			var ovLi = jQuery('<li>').appendTo(entryUl);
			var ovA  = jQuery('<a>', {
				'href': targetRecord.url,
				'html': op_overview_label
			}).appendTo(ovLi);
		}
		jQuery(pages).each(function(){
			var entryUid = parseInt(this.uid);
			var entryUrl = (this.url ? this.url : '#');
			var entryRecord = this;

			var entryLi = jQuery('<li>', {'id': 'lve-' + entryUid}).appendTo(entryUl);

			var entryA = jQuery('<a>', {
				'href': (this.url ? this.url : '#'),
				'html': this.nav_title,
				click: function(){
					jQuery.op_menu.clickHandler(this, entryUid, entryRecord);
					return false;
				}
			}).appendTo(entryLi)
		});
		showLevel(entryDiv);

		return this;
	}

	/**
	 * check if the target div already exists -> only add the ul
	 * fade out and remove existing uls
	 */
	function setupLevelDiv(levelId, targetPid) {
		var entryDiv;
		if (document.getElementById('level-' + levelId)) {
			entryDiv = jQuery('#level-' + levelId);
			//remove previous list if it is new content
			var testUl = jQuery('.' + jQuery.fn.op_menu.settings.levelContentClass, entryDiv);
			if (testUl.data('pid') == targetPid) {
				//do nothing if it is the same content
				//tryLog("nothing to do, skipping creation")
				return false;
			}
			else {
				jQuery('#level-' + levelId + ' .' + jQuery.fn.op_menu.settings.levelContentClass).fadeOut('fast', function(){
					jQuery(this).remove();
				});
			}
		}
		else {
			entryDiv = jQuery('<div></div>', {
				'class': 'level newLevel',
				'id': 'level-' + levelId
			}).prependTo(jQuery.fn.op_menu.settings.targetDiv);
		}
		return entryDiv;
	}

	function highlightPath(menuEntry, uid, record) {
		var entryLi = jQuery(menuEntry).parent();
		var siblings = entryLi.siblings();
		siblings.removeClass('active');
		entryLi.addClass('active');
	}

	function levelClick(uid) {

	}

	/**
	 * public functions
	 */
	jQuery.op_menu = {
		updateMenu : function () {
			//tryLog("update menu");
		},
		clickHandler: function (menuEntry, uid, record) {
			highlightPath(menuEntry, uid, record);
			createLevel(uid, record);
		},
		hideNavi: function () {
			removeLevels(1);
		}
	}
})(jQuery);

jQuery(document).ready(function(){
	//var showLevel
	jQuery('#mainNav').op_menu();
});

