// JavaScript Document

(function($) {
	$.fn.PhotoViewer = function (jsonPath,div,texts) {
		var json;
		var cfg, itm;
		var imgCache = [];
		var divId;
		var d = {};
		var itmPerPage;
		var panelMargin = 6;
		
		var lwVals;
		var lhVals;
		var lwGrid;
		var lhGrid;
		var lPhase = 0;
		var lTime = 0;
		var lCount = 0;
		var lPanels;
		var curPage = 0;
		
		var texts = (texts) ? texts : {pagerPrev:"<",pagerNext:">",searchByID: "Search by ID", searchBtn: "Search"};
		
		var timeout = [];
		
		var rcfg;
		
		function loadData(path,div) {
			if (/\?/.test(path)) {
				$.getJSON(path + "&jsoncallback=?",onLoad);
			} else {
				$.getJSON(path + "?jsoncallback=?",onLoad);
			}
			divId = div;
		}
		function onLoad (response) {
			json = response;
			cfg = json.settings;
			itm = json.person;
			init();
		}
		var inited = false;
		function init () {
			for (var i = itm.length-1; i >= 0; i--){
				//写真エントリ無かったら削除
				if (itm[i].photo.length == 0) {
					itm.splice(i,1);
					//preload(thumbURL(itm[i].photo[0].id, itm[i].photo[0].filetype));
				}
			}
			itmPerPage = cfg.row * cfg.col;
			setup();
			inited = true;
		}
		function setup () {
			d.root = $("#" + divId);
			d.root.empty();
			if (d.root.length == 0) return;
			d.stage = $("<div class='photoViewer-stage' />");
			d.pool = $("<div class='photoViewer-pool' />");
			d.root.append(d.stage);
			
			
			cfg.corner = cfg.corner != "0" ? true : false;
			rcfg = {
          antiAlias: true,
          autoPad: true,
          validTags: ["div"]
    	}
			rcfg.tl = rcfg.tr = rcfg.bl = rcfg.br = {radius: cfg.corner ? 4 :0};
			
			if (cfg.background == "0") { d.root.addClass("photoViewer-black"); }
			showPage (0);
			if (cfg.button != "0") { setupSearch();}
			
		}
		
		var panels = [];
		
		function showPage (n) { 
			curPage = n;
			var l = itm.length;
			var ipp = itmPerPage
			d.pool.empty();
			lPhase = 0;
			var j = 0;
			for (var i = n * ipp; i < ipp * (n + 1) && i < l; i++) {
				var img, imgj
				var thumb = thumbURL(itm[i].photo[0].id, itm[i].photo[0].filetype);

				img = new Panel(j,itm[i],onimgload,thumbURL,photoURL);
				j++;
				imgj = img.getDom();
				d.stage.append(imgj);
				panels.push(img);
				img.setup();
			}
			createPager();
		}
		var test
		function changePage (e) {
			if (curPage == e.data.n) return;
			hidePage();
			test = panels;
			panels = [];
			while (imgCache.length) {
				var i = imgCache.shift();
				i.unbind().remove();
			}
			showPage(e.data.n);
			return false;
		}
		
		function hidePage() {
			for (var i = 0;i < panels.length; i++) {
				panels[i].hide();
				panels[i] = null;
			}
			while(timeout.length){
				var d = timeout.shift();
				clearTimeout(d);
			}
		}
		
		function createPager () {
			if (!d.pager) {
				d.pager = $("<div class='pager'/>");
				d.root.append(d.pager);
			}
			d.pager.empty();
			//前後で表示するページ数
			var num = 4;
			var numPage = 1 + num * 2;
			var btnTmp = $("<a />");
			//全体のページ数
			var ttlPage = Math.ceil(itm.length / itmPerPage);
			var startPage = curPage - num;
			if (startPage + numPage > ttlPage) startPage = ttlPage - numPage;
			if (startPage < 0 ) startPage = 0;
			for (var i = 0; i < numPage && startPage + i < ttlPage; i++) {
				var cp = startPage + i;
				var elem = btnTmp.clone().append(cp + 1);
				if (cp == curPage) {
					d.pager.append(elem.addClass("current"));
				} else {
					d.pager.append(elem.addClass("link").attr("href","#"));
					elem.bind("click",{n:cp},changePage);
				}
			}
			//前へ
			if (curPage > 0) {
				elem = btnTmp.clone().append(texts.pagerPrev).attr("href","#");
				d.pager.prepend(elem.addClass("prev"))
				elem.bind("click",{n:curPage - 1},changePage);
			}
			//次へ
			if (curPage < ttlPage -1) {
				elem = btnTmp.clone().append(texts.pagerNext).attr("href","#");
				d.pager.append(elem.addClass("next"))
				elem.bind("click",{n:curPage + 1},changePage);
			}
		}
		function onimgload (e) {
			e.data.p.setSize(e.target.width, e.target.height);
			layout(e.data);
			//以下読み込みの遅れを再現するテストコード
			/*[test delay]*/
//			timeout.push(setTimeout(function () {
//				var size = getImageNaturalSize(e.target);
//				e.data.p.setSize(size.width, size.height);
//				layout(e.data);
//			},100+e.data.n * 600 + Math.floor((Math.random() -0.5) * 1000)));
			/*[/test delay]*/
		}
		
		
		function layout (dat) {
			if (lPhase == 0) {
				lTime = (new Date()).getTime();
				lPhase = 1;
				lCount = 0;
				lPanels = [];
			}
			
			
			var col = cfg.col;
			var row = cfg.row;
			var xpos,ypos;
			
			var ipp = (itmPerPage * (curPage +1) > itm.length) ?
			           itm.length - itmPerPage * curPage : itmPerPage;
			lCount ++;
			lPanels.push(dat.n);
			if (lPhase == 1){
				var curTime = (new Date()).getTime();
				if ((curTime - lTime) > 500 || lCount == ipp) {
					lPhase = 2;
					culcGrid();
					
					
					for (var i = 0; i < lPanels.length; i ++ ) {
						var j = lPanels[i];
						ypos = Math.floor(j / col);
						xpos = j % col;
						
						var p = panels[parseInt(j)].getDom();
						p.stop().clearQueue().css({left:lwGrid[xpos], top:lhGrid[ypos]}).delay(j * 75 + 200).delay(200)
						if (cfg.corner) {
							p.show(0)
							.queue(function () {
								$(this).find(".imgPlane").corner(rcfg);
								$(this).dequeue();
							})
							.hide(0)
						}
						p.fadeIn(300)
					}
					d.stage.clearQueue().animate({width:lwGrid[col],height:lhGrid[row]},200);
				}
				return;
			}
			if (lPhase == 2){
				culcGrid();
				var n = dat.n;
				for (var i = 0; i < lPanels.length; i ++ ) {
					var j = lPanels[i]
					var p = panels[j].getDom();
					ypos = Math.floor(j / col);
					xpos = j % col;
					if (j == n) {
						p.css({left:lwGrid[xpos], top:lhGrid[ypos]})
						if (cfg.corner) {
							p.show(0)
							.queue(function () {
							$(this).find(".imgPlane").corner(rcfg);
							$(this).dequeue();
							})
							p.hide(0)
						}
						p.fadeIn(300)
					} else {
						p.stop().animate({left:lwGrid[xpos], top:lhGrid[ypos], opacity: 1},200);
					}
				}
				d.stage.stop().animate({width:lwGrid[col],height:lhGrid[row]},200);
			}
		}
		function culcGrid () {
			lwVals = [];
			lhVals = [];
			lwGrid = [];
			lhGrid = [];
			var col = parseInt(cfg.col);
			var row = parseInt(cfg.row);
			
			var i;
			for (i = 0; i < col; i++) {lwVals[i] = 0;}
			for (i = 0; i < row; i++) {lhVals[i] = 0;}
			
			var xpos,ypos;
			for (i = 0; i < panels.length; i++) {
				ypos = Math.floor(i / col);
				xpos = i % col;
				lwVals[xpos] = Math.max(lwVals[xpos],panels[i].getDom().outerWidth());
				lhVals[ypos] = Math.max(lhVals[ypos],panels[i].getDom().outerHeight());
			}
			lwGrid[0] = lhGrid[0] = 0;
			for (i = 0; i < lwVals.length; i++) {
				lwGrid[i+1] = lwGrid[i] + lwVals[i] + panelMargin;
			}
			for (i = 0; i < lhVals.length; i++) {
				lhGrid[i+1] = lhGrid[i] + lhVals[i] + panelMargin;
			}
			lwGrid[col] = lwGrid[col] - panelMargin;
			lhGrid[row] = lhGrid[row] - panelMargin;
		}
		
		function setupSearch () {
			d.search = {};
			d.search.stage = $("<div class='photoViewer-search' />");
			d.search.input = $("<input type='text' maxlength='10' name='photoViewer-searchbox' class='photoViewer-seachbox' />");
			d.search.btn   = $("<a href='#' class='photoViewer-searchbtn' />");
			d.root.append(d.search.stage)
			d.search.stage.append(d.search.input).append(d.search.btn.append(texts.searchBtn));
			d.search.input.val(texts.searchByID).addClass("inactive");
			d.search.input.click(searchBoxActivated).focus(searchBoxActivated).blur(searchBoxInActivated);
			d.search.btn.click(searchButtonClicked);
		}
		
		function lookupId () {
			var id = d.search.input.val();
			for (var i =0; i < itm.length; i++) {
				if (itm[i].no  == id) {
					var offset = Math.floor(i/itmPerPage);
					changePage({data:{n:offset}});
					var v = i % itmPerPage;
					var t = setTimeout (function () { panels[v].d.img.click();},600);
					timeout.push(t);
				}
			}
		}
		
		function searchButtonClicked () {
			searchBoxVerify();
			lookupId();
			d.search.input.blur();
			return false;
		}
		
		function searchBoxActivated () {
			if (d.search.input.hasClass("inactive")) {
				d.search.input.val("").removeClass("inactive");
			}
			d.search.input.keyup(searchBoxChanged);
		}
		
		function searchBoxInActivated () {
			if (d.search.input.val() == "") {
				d.search.input.val(texts.searchByID).addClass("inactive");
			}
			d.search.input.unbind("keyup");
		}
		function searchBoxChanged (e) {
			searchBoxVerify();
			if (e.keyCode == 13) {
				lookupId();
				d.search.input.blur();
			}
		}
		function searchBoxVerify () {
			var str = d.search.input.val();
			str = str.replace("０","0").replace("１","1").replace("２","2").replace("３","3").replace("４","4")
			         .replace("５","5").replace("６","6").replace("７","7").replace("８","8").replace("９","9")
							 .replace(/[^0-9]*/g, "").replace(/^0+/, "");
			d.search.input.val(str)
			return str;
		}
		
		function thumbURL(str,ext) {
			return cfg.domain.replace(/\\\//g, "/") + cfg.thumbdir + "/" + str + "." + ext;
		}
		function photoURL(str,ext) {
			return cfg.domain.replace(/\\\//g, "/") + cfg.photodir + "/" + str + "." + ext;
		}
		loadData(jsonPath,div);
	}
	function Panel (ind,dat,comp,tURL,pURL) {
		this.d = {}
		this.d.root = $("<div class='panel' />");
		this.dom = this.d.root;
		this.d.img = $("<a href='#' class='imgPlane' />");
		this.d.cap = $("<div class='caption' />");
		this.d.num = $("<div class='num'>");
		this.d.root.append(this.d.img).append(this.d.num).append(this.d.cap);
		this.index = ind;
		this.data = dat;
		this.complete = comp;
		this.thumbURL = tURL;
		this.photoURL = pURL;
		
		this.d.root.hide();
		this.gallery = [];
		
		this.w = this.h = 0;
	}
	Panel.prototype.setup = function () {
		var d = this.data
		var str = this.thumbURL(d.photo[0].id,d.photo[0].filetype);
		this.d.img.css("backgroundImage", "url('" + str + "')");
		this.d.preload = new Image()
		var comp = this.complete;
		var tgt = this.d.preload;
		var nn = this.index;
		var pp = this
		this.d.preload.onload = function () {
			comp({target:this,data:{n:nn,p:pp}})
		}
		//this.d.preload.bind("load",{n:this.index,p:this},this.complete);
		this.d.preload.src = str;
		//this.d.root.append(this.d.preload)
		this.d.cap.empty().append(d.no);
		
		//lightbox
		for (var i = 0; i < d.photo.length; i ++) {
			var p = d.photo[i];
			var pdata;
			if (p.youtubeid) {
				pdata = {href  : "http://www.youtube.com/v/" + p.youtubeid,
				         width : 640,
								 height: 495,
								 autoScale: false,
								 transitionIn : 'none',
								 transitionOut: 'none',
				         type  : 'swf',
								 showNavArrows: false,
								 title :{t:p.took, c:p.comment},
				         swf   : {wmode:'transparent', allowfullscreen:'true'}
				         }
			} else {
				//pdata = [this.photoURL(p.id,p.filetype),
				//         "<span class='date'>" + p.took + "</span>"+p.comment];
				pdata = {href:this.photoURL(p.id,p.filetype),
								 title:{t:p.took, c:p.comment}};
			}
			this.gallery.push(pdata)
		}
		this.d.img.bind("click",{gallery:this.gallery},this.launchGallery);

	}
	
	Panel.prototype.launchGallery = function (e) {
		//$.slimbox(e.data.gallery,0,{loop:false});
		$.fancybox(e.data.gallery,
		           {titlePosition:'inside',overlayColor:'#000',transitionIn:'elastic',
							  transitionOut:'elastic',centerOnScroll:true,opacity:true,titleFormat:formatTitle});
		function formatTitle (title, currentArray, currentIndex, currentOpts) {
			var html = "";
			if (currentArray.length > 1) {
				html +='<div id="fancybox-title-pager"><div id="fancybox-title-pager-btn">'
						 + '<a id="fancybox-title-pager-btn-p"'
						 + ((currentIndex == 0 ) ? ' class="disabled"' : ' onclick="$.fancybox.prev();return false;"')
						 + '> </a><a id="fancybox-title-pager-btn-n"'
						 + ((currentIndex + 1 == currentArray.length  ) ? ' class="disabled"' : ' onclick="$.fancybox.next();return false;"')
						 + '> </a></div><span>' + (currentIndex + 1) + '/' + currentArray.length + '</span>'
						 + '</div>';
			}
			html += '<div id="fancybox-title-caption">' + (title.t ?'<strong>'+title.t+'</strong>  ':"")  + (title.c ?title.c:"") + '</div>';
			return html
			      
		}
		return false;
	}
	
	Panel.prototype.setSize = function  (aw,ah) {
		this.w = aw;
		this.h = ah;
		this.d.img.width (aw);
		this.d.img.height (ah);
	}
	Panel.prototype.hide = function () {
		this.d.preload.onload = null;
		this.d.preload = null;
		this.d.root.stop().clearQueue().fadeOut(200,function () {
			$(this).remove();
		});
	}
	Panel.prototype.getDom = function () {
		return this.d.root;
	}
	Panel.prototype.getImg = function () {
		return this.d.img;
	}
	var getImageNaturalSize = function(image){
		var	w = image.width ,
			h = image.height ;
		if ( typeof image.naturalWidth !== 'undefined' ) {	// for Firefox, Safari, Chrome
			w = image.naturalWidth;
			h = image.naturalHeight;
	
		} else if ( typeof image.runtimeStyle !== 'undefined' ) {	 // for IE
			var run = image.runtimeStyle;
			var mem = { w: run.width, h: run.height };	// keep runtimeStyle
			run.width  = "auto";
			run.height = "auto";
			w = image.width;
			h = image.height;
			run.width  = mem.w;
			run.height = mem.h;
		} else if ( typeof image.removeAttribute !== 'undefined' ) {		 // for Opera
			var mem = { w: image.width, h: image.height };	// keep original style
			image.removeAttribute("width");
			image.removeAttribute("height");
			w = image.width;
			h = image.height;
			image.width  = mem.w;
			image.height = mem.h;
		}
	
		return {width:w, height:h};
	}
})(jQuery);
