(function($) {
	
	$.fn.navigation = function(options)
	{
		// デフォルト
		var settings = $.extend({
			imgext					: 'gif|jpg|png',	// 画像の拡張子
			imgPostfixOn			: '_on',			// ON画像（有：'_on',無：''）
			imgPostfixIn			: '',				// IN画像（有：'_in',無：''）
			effect					: 'roll',			// エフェクト（画像切替：'roll', 透明度：'fade'）
			activeClass				: 'active',			// 自ページ時のクラス
			activeClassTarget		: 'li',				// 自ページクラス対象
			activeParentClass		: 'activeParent',	// 上位階層時のクラス
			activeParentClassTarget	: 'li',				// 上位階層クラス対象
			exParentClass			: 'exparent',		// 上位階層対象除外クラス
			exParentPath			: '/',				// 上位階層対象除外パス
			fade_speed				: 150,
			fade_opacity			: 0.75,
			onClick					: function(elm){},
			onMouseOver				: function(elm){},
			onMouseOut				: function(elm){},
			callback				: function(){}
		}, options);
		
		var regIndex = new RegExp('(index.html|index.php|https://|http://)');
		var regOff   = new RegExp('\.('+settings.imgext+')$');
		var regOn    = new RegExp('('+settings.imgPostfixOn+'|'+settings.imgPostfixIn +')\.('+settings.imgext+')$');
		var regIn    = new RegExp(settings.imgPostfixIn+'\.('+settings.imgext+')$');

		function setEffect(elm){
			if(settings.effect == 'roll'){
				rollOver(elm);
			}else if(settings.effect == 'fade'){
				fadeOver(elm);
			}
		}

		function rollOver(elm)
		{
			elm.originalSrc = $(elm).attr('src');
			elm.rolloverSrc = elm.originalSrc.replace(regOff, settings.imgPostfixOn+'.'+'$1');

			// 先読み
			elm.rolloverImg = new Image;
			elm.rolloverImg.src = elm.rolloverSrc;

			if(elm.originalSrc != elm.rolloverSrc){
				$(elm).hover(function() {
					$(elm).attr('src', elm.rolloverSrc);
				}, function() {
					$(elm).attr('src', elm.originalSrc);
				});
			}
		}

		function fadeOver(elm)
		{
			$(elm).hover(function() {
				$(elm)
					.stop(true, false)
					.fadeTo(settings.fade_speed, settings.fade_opacity);
			}, function() {
				$(elm).fadeTo(settings.fade_speed, 1);
			});
		}

		function getLinkType(elm)
		{
			if(elm.getAttribute('href').substr(0,1) == '#'){
				return 'other';
			}

			var href = getUri(elm, elm.getAttribute('href'));
			var setImgFlg = false;
			if((href.absolutePath.replace(regIndex,"") == location.href.replace("#"+location.hash,"").replace(regIndex,"")) && !href.Fragment){
				//そのページ
				$(elm).find('img').each(function(){
					var src = $(this).attr('src');
					if(settings.imgPostfixIn){
						$(this).attr('src',src.replace(regOff, settings.imgPostfixIn+"."+"$1"));
					}else if(settings.imgPostfixOn){
						$(this).attr('src',src.replace(regOff, settings.imgPostfixOn+"."+"$1"));
					}
				});
				if(settings.activeClass && settings.activeClassTarget){
					var t = $(elm).closest(settings.activeClassTarget);
					if(t.length > 0 && !t.hasClass(settings.activeClass)){
						t.addClass(settings.activeClass);
					}
				}
				$(elm).replaceWith($(elm).html());
				return 'self';

			}else if (0 <= location.href.search(href.absolutePath.replace(regIndex,""))){
				if(settings.exParentClass && $(elm).hasClass(settings.exParentClass)){
				}else if(settings.exParentPath && settings.exParentPath == href.Pathname.replace(regIndex,"")){
				}else{
					//上位階層
					$(elm).find('img').each(function(){
						var src = $(this).attr('src');
						if(settings.imgPostfixIn){
							$(this).attr('src',src.replace(regOff, settings.imgPostfixIn+"."+"$1"));
						}else if(settings.imgPostfixOn){
							$(this).attr('src',src.replace(regOff, settings.imgPostfixOn+"."+"$1"));
						}
					});
					if(settings.activeParentClass && settings.activeParentClassTarget){
						var t = $(elm).closest(settings.activeParentClassTarget);
						if(t.length > 0 && !t.hasClass(settings.activeParentClass)){
							t.addClass(settings.activeParentClass);
						}
					}
					return 'parent';
				}
			}

			return 'other';
		}

		function getUri(elm, path)
		{
			elm.originalPath = path;
			elm.absolutePath = (function(){
				var e = document.createElement('span');
				e.innerHTML = '<a href="' + path + '" />';
				return e.firstChild.href;
			})();
			var fields = {'Username' : 4, 'Password' : 5, 'Port' : 7, 'Protocol' : 2, 'Host' : 6, 'Pathname' : 8, 'URL' : 0, 'Querystring' : 9, 'Fragment' : 10};
			var regex = /^((\w+):\/\/)?((\w+):?(\w+)?@)?([^\/\?:]+):?(\d+)?(\/?[^\?#]+)?\??([^#]+)?#?(\w*)/;
			var r = regex.exec(elm.absolutePath);
			for(var f in fields){
				if(typeof r[fields[f]] != 'undefined'){
					elm[f] = r[fields[f]];
				}
			}
			return elm;
		}

		this.each(function() {
			$(this).find('a[href]:first').each(function(){
				var type = getLinkType(this);
				if(type == "self"){
				}else if(type == "parent"){
					if(settings.effect == 'fade'){
						$(this).find('img').each(function(){
							setEffect(this);
						});
					}
					$(this).click(function () {
						settings.onClick(this);
					});
				}else{
					$(this).find('img').each(function(){
						setEffect(this);
					});
					$(this).click(function () {
						settings.onClick(this);
					});
				}

			});
			$(this).hover(function() {
				settings.onMouseOver(this);
			}, function() {
				settings.onMouseOut(this);
			});
		});

		settings.callback();
		
		return this;
	};

})(jQuery);

