
/* ------------------------------------------------------------------------
ギャラリー（01）
	Copyright (c) 2010, Matsumoto.JS All rights reserved.

【使用方法】（なるべく<head>タグ内にて）
<script src="js/prototype.js" type="text/javascript"></script>
<script src="js/scriptaculous.js?load=effects" type="text/javascript"></script>
<script src="js/gallery01.js" type="text/javascript"></script>
<script language="JavaScript" type="text/javascript">
var slideObj;
Event.observe(window,'load',function() {
	var option = {imageId:"container", duration:0.5};
	var gallary = new Gallery01("imagelist.xml",option);
});
</script>

【パラメータの説明】
第1パラメータはXMLの場所を指定します（JSON指定も可、サンプルを参照）
第2パラメータは以下の情報を任意に指定します（上記書式を参考に）
	imageId: スライドショーを表示するブロックのID
	thumbId: サムネールを表示するブロックのID
	textId: XML<description>テキストを表示する際のテキストブロックのID
		（指定しない、または空の場合はテキストを表示しません）
	valign: 縦方向のセンタリング(初期値: false)
	halign: 横方向のセンタリング(初期値: true)
	※ valign,halignはimageId内のimgタグに属性またはCSSでwidth,heightがないこと。
  　（指定すると実サイズが取得できず位置調整ができないため）
	darkness: アクティブでないサムネール暗さ(0.1 から 0.9)
	duration: フェードの時間を秒で指定（画像の切替え時間）
	linkTarget: ジャンプURLがある場合のターゲットウィンドウ（'_self','_blank'）
	interval: 自動切り替えの間隔を秒で指定（初期値: 0=再生しない）
	id: 複数起動用（初期値: default）

【XMLの説明】
<?xml version="1.0" encoding="UTF-8"?>
<items>
	<item>
		<title>タイトルはイメージのaltに適用</title>
		<url>画像URL:相対パスの場合HTMLから/01.jpg</url>
		<link>画像クリックでジャンプさせる場合のURL</link>
		<description>説明文:HTMLタグはエスケープします</description>
		<thumb>サームネール画像URL:相対パス/01_s.jpg</thumb> <!-- これはオプション -->
	</item>
</items>
 ------------------------------------------------------------------------ */

var Gallery01 = Class.create();
Gallery01.prototype = {

initialize: function(loc,option) {
	this.url = loc;
	this.props = {
		imageId : "image-container",
		thumbId : "thumb-container",
		textId : "",
		valign : false,
		halign : true,
		darkness : 0.3,
		duration : 1.0,
		linkTarget : "_self",
		interval : 0,
		id : "default"
	};
	if(option) for(var key in option) this.props[key] = option[key];
	this.props.id = this.props.id + '_';

	this.myTimer = 0;
	this.idx = 0;
	this.itemCount = 0;
	this.imageUrls = new Array(); //Image URLs
	this.thumbUrls = new Array(); //Thumbnail URLs <option>
	this.linkArray = new Array();
	this.titlArray = new Array(); //Titles
	this.descArray = new Array(); //Descriptions
	this.baseDiv = $(this.props.imageId);
	this.thumbDiv = $(this.props.thumbId);

	if (this.url.items) this.loadJson();
	else this.loadXMLFile();
},

loadXMLFile: function () {
	new Ajax.Request(this.url, {
		method: "get",
		onComplete: function (httpObj) {
						this.displayData(httpObj);
					}.bindAsEventListener(this)
		}
	);
},

displayData: function (httpObj) {
	var XML = httpObj.responseXML;
	var itemsTag = XML.getElementsByTagName("items");
	var items = itemsTag[0].getElementsByTagName("item");
	this.itemCount = items.length;
	for (var i = 0; i < this.itemCount; i++) {
		var nd = items[i].getElementsByTagName("url")[0];
		this.imageUrls[i] = nd.firstChild.nodeValue;
		nd = items[i].getElementsByTagName("thumb")[0];
		if (nd) this.thumbUrls[i] = nd.firstChild ? nd.firstChild.nodeValue:'';
		nd = items[i].getElementsByTagName("link")[0];
		if (nd) this.linkArray[i] = nd.firstChild ? nd.firstChild.nodeValue:'';
		nd = items[i].getElementsByTagName("title")[0];
		if (nd) this.titlArray[i] = nd.firstChild ? nd.firstChild.nodeValue:'';
		nd = items[i].getElementsByTagName("description")[0];
		if (nd) this.descArray[i] = nd.firstChild ? nd.firstChild.nodeValue:'';
	}
	//prepare & preload
	this.prepareImages();
},

loadJson: function () {
	var items = this.url.items;
	this.itemCount = items.length;
	for (var i = 0; i < this.itemCount; i++) {
		var nd = items[i].url;
		this.imageUrls[i] = nd;
		nd = items[i].thumb;
		this.thumbUrls[i] = nd ? nd:'';
		nd = items[i].link;
		this.linkArray[i] = nd ? nd:'';
		nd = items[i].title;
		this.titlArray[i] = nd ? nd:'';
		nd = items[i].description;
		this.descArray[i] = nd ? nd:'';
	}
	this.prepareImages();
},

effectSlide: function (next) {
	this.fadeOut(this.idx);

	//thumbnail Off
	if (next != this.idx)
		this.thumbOff(this.props.id+"thumb-"+this.idx);

	this.idx = next;
	this.fadeIn(this.idx);
},

fadeOut: function (lbl) {
	if (!$(this.props.id+"slitem-"+lbl)) return;
	new Effect.Fade(this.props.id+"slitem-"+lbl, { duration:this.props.duration*0.1, from:1.0, to:0.0 });
	if (this.props.textId) {
		new Effect.Fade(this.props.id+"sltext-"+lbl, { duration:this.props.duration*0.1, from:1.0, to:0.0 });
	}
},

fadeIn: function (lbl) {
	this.createSlide(lbl);
	new Effect.Appear(this.props.id+"slitem-"+lbl, { duration:this.props.duration*0.9, from:0.0, to:1.0 });
	if (this.props.textId) {
		new Effect.Appear(this.props.id+"sltext-"+lbl, { duration:this.props.duration*0.9, from:0.0, to:1.0 });
	}
},

startSlide: function (lbl) {
	this.effectSlide(lbl);
	if (!this.myTimer && this.props.interval != 0)
		this.myTimer = setInterval(function(e) {
			var next = this.idx + 1;
			if (next == this.itemCount) next = 0;
			this.thumbOn(this.props.id+"thumb-"+next);
			this.effectSlide(next);
		}.bindAsEventListener(this), this.props.interval*1000);
},

stopSlide: function () {
	if (this.myTimer) {
		clearInterval(this.myTimer);
		this.myTimer = 0;
	}
},

prepareImages: function () {
	this.baseDiv.style.position = "relative";
	this.baseDiv.style.overflow = "hidden";
	//preload images
	for (var i=0; i < this.itemCount; i++) {
		var img = new Image();
		if (i==0) {
            Event.observe(img,'load',function() {
				this.startSlide(0);
			}.bindAsEventListener(this));
		}
		img.src = this.imageUrls[i];
		//thumbnails
		this.createThumbnail(i);
	}
	
},

createSlide: function (lbl) {
	if ($(this.props.id+"slitem-"+lbl))
		this.baseDiv.removeChild($(this.props.id+"slitem-"+lbl));
	var imgObj = new Element('img');
	var imgBox;

	if (this.titlArray[lbl]) imgObj.alt = this.titlArray[lbl];
	imgObj.setStyle({'border':'0'});
	imgObj.src = this.imageUrls[lbl];
	var pH = this.baseDiv.getHeight();
	var pW = this.baseDiv.getWidth();
	var iH = imgObj.height;
	var iW = imgObj.width;

	//Resize to fit
	if (iH <= iW && iW > pW) { //landscape
		var ratio = iH / iW;
		imgObj.width = pW;
		imgObj.height = pW * ratio;
	} else if (iH > iW && iH > pH) { //portrait
		var ratio = iW / iH;
		imgObj.height = pH;
		imgObj.width = pH * ratio;
	}
	var newH = imgObj.height;
	var newW = imgObj.width;

	if (this.linkArray[lbl]) {
		var lnkObj = new Element('a', {
			'id':this.props.id+'slitem-'+lbl, 'href':this.linkArray[lbl],
			'target':this.props.linkTarget
		});
		lnkObj.setStyle({'position':'absolute','left':'0','top':'0'}).hide();
		lnkObj.insert(imgObj);
		this.baseDiv.insert(lnkObj);
		imgBox = lnkObj;
	} else {
		imgObj.id = this.props.id + "slitem-" + lbl;
		imgObj.setStyle({'position':'absolute','left':'0','top':'0'}).hide();
		this.baseDiv.insert(imgObj);
		imgBox = imgObj;
	}

	//Centering image
	if (newH > 0 && this.props.valign && newH < pH)
		imgBox.setStyle({"top":parseInt((pH-newH)/2)+"px"}); //landscape
	if (newW > 0 && this.props.halign && newW < pW)
		imgBox.setStyle({"left":parseInt((pW-newW)/2)+"px"}); //portrait

	if (this.props.textId) {
		var base_txt = $(this.props.textId);
		if ($(this.props.id+"sltext-"+lbl))
			base_txt.removeChild($(this.props.id+"sltext-"+lbl));

		var txtObj = new Element('span');
		txtObj.id = this.props.id+"sltext-" + lbl;
		txtObj.setStyle({position:"absolute",
			width:base_txt.getWidth()+"px"});
		txtObj.hide();
		var texts = this.descArray[lbl]?this.descArray[lbl]:'';
		txtObj.innerHTML = texts;
		base_txt.insert(txtObj);
	}
},

createThumbnail: function (lbl) {
	if (!this.thumbDiv) return;
	var imgObj = new Element('img');

	if (this.titlArray[lbl]) imgObj.alt = this.titlArray[lbl];
	imgObj.setStyle({border:"0"});
	imgObj.src = this.thumbUrls[lbl] ? this.thumbUrls[lbl] : this.imageUrls[lbl];
	imgObj.id = this.props.id + "thumb-" + lbl;
	imgObj.hide();
	this.thumbDiv.insert(imgObj);

	imgObj.onmouseover = function(){
		this.thumbOn(imgObj.id);
	}.bindAsEventListener(this);
	imgObj.onmouseout = function(){
		if (this.props.id+"thumb-"+this.idx != imgObj.id) this.thumbOff(imgObj.id, 0.2);
	}.bindAsEventListener(this);
	imgObj.onclick = function(){
		this.stopSlide();
		this.startSlide(lbl);
	}.bindAsEventListener(this);

	var op = 1.0;
	if (lbl != 0) op = this.props.darkness;
	new Effect.Appear(this.props.id+"thumb-"+lbl, { duration:this.props.duration, from:0.0, to:op });
},

thumbOn: function (thumbId) {
	if (!this.thumbDiv) return;
	new Effect.Opacity(thumbId, {
		duration:0.2, to:1.0, queue: {position:'end',scope:thumbId}
	});
},

thumbOff: function (thumbId, dur) {
	if (!this.thumbDiv) return;
	new Effect.Opacity(thumbId, {
		duration:dur?dur:this.props.duration, to:this.props.darkness
	});
}

}//prototype
