/**
 * jp.rinco.ui: JavaScript ui lib
 * @see prototype-1.6.0.2.js, jp-rinco.js
 * @author Toshio Yamashita (yamachan)
 * @licence 3-clause BSD license
 */

if (!jp.rinco.ui) {jp.rinco.ui = {
	author: "Toshio Yamashita (yamachan)",
	mail: "z@rinco.jp",
	version: "0.0.0",
	lastUpdate: "2008/10/21"
}}


jp.rinco.ui.bySortKey = function(v1,v2){
	try{
		v1 = typeof v1=="undefined" ? "" : v1.sortKey ? v1.sortKey : "";
		v2 = typeof v2=="undefined" ? "" : v2.sortKey ? v2.sortKey : "";
		return v1==v2 ? 0 : v1<v2 ? 1 : -1;		
	} catch (e) {}
	return 0;
}
jp.rinco.ui.bySortKeyAscending = function(v1, v2){ return - jp.rinco.ui.bySortKey(v1, v2); }

jp.rinco.ui.baseObject = new Class.create(jp.rinco.baseObject, {
	action: 'click', onClassName: "on", offClassName: "off", forceClass: true,
	selectorOn : function(t){if ($(t)) $(t).replaceClassName(this.offClassName, this.onClassName, this.forceClass);},
	selectorOff : function(t){if ($(t)) $(t).replaceClassName(this.onClassName, this.offClassName, this.forceClass);},
	isOn : function(t){return $(t) ? $(t).hasClassName(this.onClassName) : false;},
	isOff : function(t){return $(t) ? $(t).hasClassName(this.offClassName) : false;},
	targetOn : function(t){if ($(t)) $(t).show();},
	targetOff : function(t){if ($(t)) $(t).hide();},
	myClass: 'jp.rinco.ui.baseObject',
	lastUpdate: "2008/06/10"
});



jp.rinco.ui.popupClass = new Class.create(jp.rinco.ui.baseObject, {
	multi:0.5,
	margin:10,
	TOPLEFT:0,
	CENTER:1,
	initialize: function($super,id){
		this.id = id || '_jp_rinco_ui_popup';
		this.isOpen = false;
		this.bgStyle = {position:'absolute', left:'0px', top:'0px', zIndex: 98, backgroundColor:'#000000', opacity:0.5};
		this.popupStyle = {position: 'absolute', zIndex: 99, backgroundColor: '#ffffff', opacity: 0.9, margin:this.margin+'px'};
	},
	setMargin: function(v) {this.margin=v; this.popupStyle.margin=v+'px'},

	maxWidth: function(){ return (window.innerWidth||document.viewport.getWidth()) - this.margin*2 },
	maxHeight: function(){ return (window.innerHeight||document.viewport.getHeight()) - this.margin*2 },
	open: function(msg,x,y,w,h,mode,ps,bgs) {
		if (!this.background) {
			this.background = jp.rinco.getWorkElement(this.id + '_bg');
			document.body.appendChild(this.background);
			Event.observe(this.background, 'click', this.close.bindAsEventListener(this));
		}
		if (!this.popup) {
			this.popup = jp.rinco.getWorkElement(this.id + '_popup');
			document.body.appendChild(this.popup);
		}
		if(!this.isOpen) {
			if (true) {
				this.background.setStyle(this.bgStyle);
				this.background.style.width = Math.max(document.body.clientWidth,document.viewport.getWidth())+'px';
				var y_max = window.innerHeight&&window.scrollMaxY ? window.innerHeight+window.scrollMaxY : 0;
				if (document.documentElement.getHeight) y_max = Math.max(y_max,document.documentElement.getHeight());
				this.background.style.height = Math.max(y_max,document.body.clientHeight,document.viewport.getHeight())+'px';
				this.background.show();
				if (bgs)
					this.background.setStyle(bgs);
			}
			this.popup.setStyle(this.popupStyle);
			var vw = this.maxWidth();
			var vh = this.maxHeight();
			w =	typeof(w)!='number'||isNaN(w) ? Math.floor(vw*this.multi) : w<0 ? -Math.floor(vw*w) : w;
			h =	typeof(h)!='number'||isNaN(h) ? Math.floor(vh*this.multi) : h<0 ? -Math.floor(vh*h) : h;
			var r = Math.max(w/vw,h/vh,1);
			w = Math.floor(w/r);
			h = Math.floor(h/r);
			this.popup.style.width = w+'px';
			this.popup.style.height = h+'px';

			x =	typeof(x)!='number'||isNaN(x) ? Math.floor((vw-w)/2) : x<0 ? -Math.floor(vw*x) : x;
			x -= mode === this.CENTER ? Math.floor(w/2) : 0;
			y =	typeof(y)!='number'||isNaN(y) ? Math.floor((vh-h)/2) : y<0 ? -Math.floor(vw*y) : y;
			y -= mode === this.CENTER ? Math.floor(h/2) : 0;
			var off = document.viewport.getScrollOffsets();
			this.popup.style.left = (off.left+(x<0 ? 0 : x>vw-w ? vw-w : x))+'px';
			this.popup.style.top = (off.top+(y<0 ? 0 : y>vh-h ? vh-h : y))+'px';
			
			this.popup.innerHTML = msg||"";
			if(ps)
				this.popup.setStyle(ps);
			this.popup.show();
			this.isOpen = true;
		}
	},
	close: function() {
		if (this.background)
			this.background.hide();
		if (this.popup)
			this.popup.hide();
		this.isOpen = false;
	},
		
	myClass: 'jp.rinco.ui.popupClass',
	lastUpdate: "2008/10/17"
});

jp.rinco.ui.popup = new jp.rinco.ui.popupClass();

/*
jp.rinco.ui.pxValue = function(v,d,m){
	d = d===undefined ? b : d; // default size
	m = m===undefined ? d : m; // max size

	//return v===undefined ? d+'px' : typeof(w)=='number' ? m*v+'px' : 
	
	// : typeof(w)=='number' ? w : typeof(w)=='string' ? w : NaN;
	
}
jp.rinco.ui.pxValue_old = function(v,b,d,m){
	b = b===undefined ? 1 : b; // base size
	d = d===undefined ? b : d; // default size
	m = m===undefined ? d : m; // max size
	return v===undefined||v===null||v===NaN ? d+'px' : typeof(v)=='number' ? jp.rinco.ui.pxValue_number(v,b,d,m) : typeof(v)=='string' ? (v.isNumber() ? jp.rinco.ui.pxValue_number(Number(v),b,d,m) : v) : d+'px';
}
jp.rinco.ui.pxValue_number = function(v,b,d,m){
	var r = v>0 ? Math.abs(Math.floor(b*v)) : v<0 ? Math.abs(Math.floor(m*v)) : d;
	return r>m ? m+'px' : r+'px';
}
*/

jp.rinco.ui.image = new Class.create(jp.rinco.ui.baseObject, {
	initialize: function($super,t,o){
		t = $(t);
		if (t) {
			this.target = t;		
			this.width = t.getWidth();
			this.height = t.getHeight();
			this.src = t.src;
			this.onMouseover = this._onMouseover.bindAsEventListener(this);
			this.onMouseout = this._onMouseout.bindAsEventListener(this);
			this.onMousedown = this._onMousedown.bindAsEventListener(this);
			this.onMouseup = this._onMouseup.bindAsEventListener(this);
			if (o) {
				this.setMouseover(o.mouseoverwidth,o.mouseoverheight,o.mouseoversrc);
				this.setMousedown(o.mousedownwidth,o.mousedownheight,o.mousedownsrc);
				this.setPopup(o.popupwidth,o.popupheight,o.popupsrc);
			}
		}
	},
	useMouseover: false,
	setMouseover: function(w,h,s) {
		if (w || h || s) {
			this.mo_wp = w||this.width+'px';
			this.mo_w = typeof(w)=='number' ? w : typeof(w)=='string'&&w.isNumber() ? Number(w) : NaN;
			this.mo_hp = h||this.height+'px';
			this.mo_h = typeof(h)=='number' ? h : typeof(h)=='string'&&w.isNumber() ? Number(h) : NaN;
			this.mo_s = s||this.src;
			Event.observe(this.target, 'mouseover', this.onMouseover);
			Event.observe(this.target, 'mouseout', this.onMouseout);
			this.useMouseover = true;
		} else
			this.useMouseover = false;
		return this;
	},
	isMouseover: false,
	_onMouseover: function() {
		this.isMouseover = true;
		this.update();		
	},
	_onMouseout: function() {
		this.isMouseover = false;
		this.isMousedown = false;
		this.update();		
	},
	useMousedown: false,
	setMousedown: function(w,h,s) {
		if (w||h||s) {
			this.md_wp = w||this.width+'px';
			this.md_w = typeof(w)=='number' ? w : typeof(w)=='string'&&w.isNumber() ? Number(w) : NaN;
			this.md_hp = h||this.height+'px';
			this.md_h = typeof(h)=='number' ? h : typeof(h)=='string'&&w.isNumber() ? Number(h) : NaN;
			this.md_s = s||this.src;
			Event.observe(this.target, 'mousedown', this.onMousedown);
			Event.observe(this.target, 'mouseup', this.onMouseup);
			Event.observe(this.target, 'mouseout', this.onMouseout);
			this.useMousedown = true;
			this.usePopup = false;
		} else
			this.useMousedown = false;
		return this;
	},
	usePopup: false,
	setPopup: function(w,h,s) {
		if (w||h||s) {
			this.pop_wp = w||this.width+'px';
			this.pop_w = typeof(w)=='number' ? w : typeof(w)=='string'&&w.isNumber() ? Number(w) : NaN;
			this.pop_hp = h||this.height+'px';
			this.pop_h = typeof(h)=='number' ? h : typeof(h)=='string'&&w.isNumber() ? Number(h) : NaN;
			this.pop_s = s||this.src;			
			Event.observe(this.target, 'mousedown', this.onMousedown);
			this.usePopup = true;
			this.useMousedown = false;
		} else
			this.usePopup = false;
		return this;
	},
	isMousedown: false,
	_onMousedown: function() {
		if (this.usePopup) {
			var msg = '<img src="'+this.pop_s+'" onclick="jp.rinco.ui.popup.close();" width="100%" height="100%"/>';
			var w = isNaN(this.pop_w) ? Number(this.pop_wp.replace(/[a-zA-Z]/g,'')) : this.pop_w>0 ? this.width*this.pop_w : this.pop_w;
			var h = isNaN(this.pop_h) ? Number(this.pop_hp.replace(/[a-zA-Z]/g,'')) : this.pop_h>0 ? this.height*this.pop_h : this.pop_h==0 ? this.height*w/this.width : this.pop_h;
			jp.rinco.ui.popup.open(msg,null,null,w,h,jp.rinco.ui.popup.TOPLEFT,{opacity:1});
		} else {
			this.isMousedown = true;
			this.update();			
		}
	},
	_onMouseup: function() {
		if (this.isMousedown) {
			this.isMousedown = false;
			this.update();		
		}
	},
	update: function() {
		if (this.target) {
			this.target.style.width =
				this.isMousedown&&this.useMousedown ? (
					isNaN(this.md_w) ? this.md_wp :
					this.md_w>0 ? Math.floor(this.width*this.md_w)+'px' :
					Math.abs(Math.floor(document.viewport.getWidth()*this.md_w))+'px'
				):
				this.isMouseover&&this.useMouseover ? (
					isNaN(this.mo_w) ? this.mo_wp :
					this.mo_w>0 ? Math.floor(this.width*this.mo_w)+'px' :
					Math.abs(Math.floor(document.viewport.getWidth()*this.mo_w))+'px'
				):
				this.width+'px';
			this.target.style.height =
				this.isMousedown&&this.useMousedown ? (
					isNaN(this.md_h) ? this.md_hp :
					this.md_h>0 ? Math.floor(this.height*this.md_h)+'px' :
					this.md_h==0 ? Math.floor(this.height*Number(this.target.style.width.replace(/[a-zA-Z]/g,''))/this.width)+'px' :
					Math.abs(Math.floor(document.viewport.getHeight()*this.md_h))+'px'
				):
				this.isMouseover&&this.useMouseover ? (
					isNaN(this.mo_w) ? this.mo_hp :
					this.mo_h>0 ? Math.floor(this.height*this.mo_h)+'px' :
					this.mo_h==0 ? Math.floor(this.height*Number(this.target.style.width.replace(/[a-zA-Z]/g,''))/this.width)+'px' :
					Math.abs(Math.floor(document.viewport.getHeight()*this.mo_h))+'px'
				):
				this.width+'px';
			this.target.src =
				this.isMousedown&&this.useMousedown ? this.md_s :
				this.isMouseover&&this.useMouseover ? this.mo_s :
				this.src;
		}
	},
	myClass: 'jp.rinco.ui.image',
	lastUpdate: "2008/10/21"
});

jp.rinco.ui.img = function(e){
	var i;
	if (e && e.nodeName && e.nodeName=="IMG") {
		var w = e.getAttribute("mouseoverwidth");
		var h = e.getAttribute("mouseoverheight")
		var s = e.getAttribute("mouseoversrc");
		var dw = e.getAttribute("mousedownwidth");
		var dh = e.getAttribute("mousedownheight")
		var ds = e.getAttribute("mousedownsrc");
		var pw = e.getAttribute("popupwidth");
		var ph = e.getAttribute("popupheight")
		var ps = e.getAttribute("popupsrc");
		if (w||h||s||dw||dh||ds||pw||ph||ps) {
			i = new jp.rinco.ui.image(e);
			i.setMouseover(w,h,s);
			i.setMousedown(dw,dh,ds);
			i.setPopup(pw,ph,ps);
		}
	}
	return i;
}

jp.rinco.ui.rss = new Class.create(jp.rinco.ui.baseObject, {
	count: 0,
	YEAR_ON: 1,
	YEAR_OFF: 2,
	YEAR_AUTO: 3,
	initialize: function($super, url){
		this.url = url==undefined ? '' : url;
		this.onSuccess = this._onSuccess.bindAsEventListener(this);
		this.data = [];
		this.year_mode = this.YEAR_ON;
	},
	request: function(url) {
		url = url==undefined ? this.url : url;
		if (url.empty())
			return;

		var me = this;
		new Ajax.Request(url,{
			method: 'get',
			onSuccess: this.onSuccess
		});
	},
	formatDate: function(d,ym) {
		if (d && d instanceof Date) {
			switch(ym||this.year_mode) {
				case this.YEAR_OFF:
					return (d.getMonth()+1).toString().padding(2,'0') + '-' + d.getDate().toString().padding(2,'0');
				case this.YEAR_AUTO:
					return d.isSameYear() ? this.formatDate(d,this.YEAR_OFF) : this.formatDate(d,this.YEAR_ON);
				default:
					return d.toSimpleDateString('-');
			}			
		}
		return '';
	},
	_onSuccess: function(res) {
		var root = res.responseXML.documentElement;
		var channels = root.getElementsByTagName('channel');
		if (root.nodeName == 'rss' && channels.length == 1) {
			var channel = channels[0];
			this.title = this.getChildValue(channel, 'title');
			this.link = this.getChildValue(channel, 'link');
			this.description = this.getChildValue(channel, 'description');				

			var items = channel.getElementsByTagName('item');
			if (items.length > 0 && this.targetTable) {
				this.count = items.length;
				for (var l=0; l<this.count; l++) {
					var o = {};
					o.u = new Date(this.getChildValue(items[l], 'date').left(10).replace(/\-/g, '/'));
					o.l = String(this.getChildValue(items[l], 'link')||'');
					o.t = String(this.getChildValue(items[l], 'title')||'');
					if (o.u && !o.l.empty() && !o.t.empty()) {
						this.data.push(o);

						var a = [];
						a.push(this.formatDate(o.u));
						a.push('<a href="' + this.getChildValue(items[l], 'link') + '">' + this.getChildValue(items[l], 'title') + '</a>');
						this.targetTable.push(a);
					}
				}
				this.targetTable.updateDisplayColumn();
			}
		}		
	},
	getChildValue: function(e,tag) {
		var cs = tag==undefined ? e.childNodes : e.getElementsByTagName(tag);
		return cs.length<1 ? '' : cs[0].firstChild && (cs[0].firstChild.nodeType == 3 || cs[0].firstChild.nodeType == 4) ? cs[0].firstChild.nodeValue : '';
	},
	myClass: 'jp.rinco.ui.rss',
	lastUpdate: "2008/08/05"
});

jp.rinco.ui.table = new Class.create(jp.rinco.ui.baseObject, {
	tableClassName: '',
	tableStyle: {},
	headerTrClassName: '',
	oddClassName: '',
	evenClassName: '',
	overClassName: '',
	controlClassName: 'table-pages',
	noSortHtml: '&nbsp;[^v]',
	ascendingSortHtml: '&nbsp;[Av]',
	descendingSortHtml: '&nbsp;[^V]',
	initialize: function($super,t,ow){
		$super();
		this.head = [];
		this.body = [];
		this.foot = [];
		this.columns = 0;
		this.rows = 0;
		this.target = null;
		this.isSortable = true;
		this.sortMinimum = 5;
		this.sortColumn = -1;
		this.isAscending = true;
		this.startColumn = 0;
		if (t != undefined)
			this.initTable(t,ow);
	},

	// --------------- data control API ---------------
	setStartColumn: function(v,op) {
		v = op==true ? this.startColumn + v : v;
		this.startColumn = v<0 ? 0 : v>this.rows ? this.rows : v;
	},
	setDisplayColumn: function(v) {
		this.displayColumn = v==undefined||isNaN(Number(v)) ? this.rows : Number(v);
	},
	sort: function(f){
		if (this.sortColumn >= 0)
			this.body.sort(f instanceof Function ? f : this.isAscending ? jp.rinco.ui.bySortKeyAscending : jp.rinco.ui.bySortKey);		
	},
	setSort: function(v,f) {
		if (this.isSortable && v >= 0 && v < this.columns) {
			if (v == this.sortColumn) {
				var ff = f==undefined ? !this.isAscending : f;
				if (this.isAscending != ff) {
					this.isAscending = ff;				
					this.sort();
				}
			} else {
				this.sortColumn = v;
				for (var l=0; l<this.body.length; l++)
					this.body[l].sortKey = this.body[l][v].stripTags();	
				this.isAscending = f==undefined ? true : f;
				this.sort();
			}
		}
	},
	push: function(o){
		if (o instanceof Array) {
			this.body.push(o);
			this.columns = Math.max(this.columns, o.length);
			//if (this.setup instanceof Function) this.setup(o);		
		}
		this.rows = this.body.length;
	},

	// --------------- UI update APIs ---------------
	updateStartColumn: function(v,op) {
		this.setStartColumn(v,op);
		this.update();
	},
	updateDisplayColumn: function(v) {
		this.setDisplayColumn(v);
		this.setStartColumn(0);
		this.update();
	},
	updateSort: function(v,f) {
		this.setSort(v,f);
		this.update();
	},
	hasTd: function(e) {
		if($(e) && $(e).down('td'))
			return true;
		return false;
	},
	update: function(t){
		t = t==undefined ? this.target : $(t);
		if (!t) return;
		if (this.rows<1 || this.displayColumn<1) {
			t.hide();
			return;
		}

		var ts = t.tryDown('thead').select('th');
		for (var l=0; l<ts.length && l<this.head.length; l++) {
			ts[l].innerHTML = this.head[l] + this.getSortHtml(l);
			ts[l]._jp_rinco_ui_t = this;
		}

		var tbody = t.tryDown('tbody');
		ts = tbody.select('tr').filter(this.hasTd);
		for (var l=ts.length; l<this.displayColumn; l++) {
			var tr = document.createElement('tr');
			for (var ll=0; ll<this.columns; ll++)
				tr.appendChild(document.createElement('td'));
			tbody.appendChild(tr);
			this.setupTr(tr,l);
		}
		for (var l=this.displayColumn; l<ts.length; l++)
			ts[l].hide();

		ts = tbody.select('tr').filter(this.hasTd);
		for (var l=0; l<this.displayColumn; l++) {
			if (l+this.startColumn<this.body.length) {
				var tds = ts[l].select('td');
				for (var ll = 0; ll<tds.length && ll<this.body[l+this.startColumn].length; ll++)
					tds[ll].innerHTML = this.body[l+this.startColumn][ll];
				ts[l].show();
			} else
				ts[l].hide();				
		}

		var tfoot = t.down('tfoot');
		if (tfoot) {
			ts = tfoot.select('th');
			for (var l=0; l<ts.length && l<this.foot.length; l++)
				ts[l].innerHTML = this.foot[l];
		}
		if (this.control) {
			if (this.startColumn==0 && this.displayColumn==this.rows) {
				this.control.hide();
			} else {
				this.control.innerHTML = this.getControlHtml();
				this.control.show();				
			}
		}
		t.show();
	},
	getSortHtml: function(l){
		if (!this.isSortable) return '';
		var h = '<a href="javascript://" onclick="this.parentNode._jp_rinco_ui_t.updateSort(' + l + ');">';
		h += l!=this.sortColumn ? this.noSortHtml : this.isAscending ? this.ascendingSortHtml : this.descendingSortHtml;
		return h + '</a>';
	},
	getControlHtml: function(){
		var pages = Math.ceil(this.rows / this.displayColumn);
		if (pages < 2)
			return '';
		var h = '';
		var page = 0;
		for (var l=1; l<=pages; l++) {
			if (page==0 && this.startColumn < this.displayColumn * l) {
				h += '<b>' + l + '</b>';
				page = l;
			} else {				
				h += '<a href="javascript://" onclick="this.parentNode._jp_rinco_ui_t.updateStartColumn(' + this.displayColumn*(l-1) + ')">' + l + '</a>';
			}
		}
		if (page != 1)
			h = '&lt;<a href="javascript://" onclick="this.parentNode._jp_rinco_ui_t.updateStartColumn(-' + this.displayColumn + ',true);">prev</a>|&nbsp;' + h;
		if (page != pages)
			h += '&nbsp;|<a href="javascript://" onclick="this.parentNode._jp_rinco_ui_t.updateStartColumn(' + this.displayColumn + ',true);">next</a>&gt;';
		
		h += '&nbsp;[<a href="javascript://" onclick="this.parentNode._jp_rinco_ui_t.updateDisplayColumn();">all</a>]';
		return h;
	},

	// --------------- analyze TABLE emement ---------------
	analyzeHead: function(t){
		var ts = t.tryDown('thead').select('th');
		for (var l=0; l<ts.length; l++)
			this.head.push(ts[l].innerHTML);
		this.columns = Math.max(this.columns, ts.length);			
	},
	analyzeBody: function(t){
		var ts = t.tryDown('tbody').select('tr');
		for (var l=0; l<ts.length; l++) {
			var tds = ts[l].select('td');
			if (tds && tds.length > 0) {
				var a = [];
				for (var ll=0; ll<tds.length; ll++) {
					var cs = tds[ll].getAttribute('colspan');
					cs = cs==null ? 1 : Number(cs);
					cs = isNaN(cs) ? 1 : cs;
					for (var l3=0; l3<cs; l3++)
						a.push(tds[ll].innerHTML);					
				}
				this.push(a);
				this.columns = Math.max(this.columns, a.length);			
			}
		}
	},
	analyzeFoot: function(t){
		var tfoot = t.down('tfoot');
		if (tfoot) {
			var ts = tfoot.select('th');
			for (var l=0; l<ts.length; l++)
				this.foot.push(ts[l].innerHTML);
			this.columns = Math.max(this.columns, this.foot.length);			
		}
	},
	analyzeTable: function(t){
		t = $(t);
		if (!t)
			return;
		this.columns = 0;
		this.head = [];
		this.analyzeHead(t);		
		this.body = [];
		this.analyzeBody(t);		
		this.foot = [];
		this.analyzeFoot(t);		
	},

	// --------------- others ---------------
	getTableHtml: function(){
		//if (this.body.length < 1) return '';		
		var h = '<table><thead>';
		if (this.head.length > 0) {
			h += '<tr>';
			for (var l=0; l<this.head.length; l++)
				h += '<th>' + this.head[l] + '</th>';
			h += '</tr>'			
		}
		h += '</thead><tbody>';
		for (var l=0; l<this.displayColumn && l+this.startColumn<this.body.length; l++) {
			h += '<tr>';			
			for (var ll=0; ll<this.body[l+this.startColumn].length; ll++)
				h += '<td>' + this.body[l+this.startColumn][ll] + '</td>';
			h += '</tr>'			
		}
		h += '</tbody><tfoot>';
		if (this.foot.length > 0) {
			h += '<tr>'			
			for (var l=0; l<this.foot.length; l++)
				h += '<th>' + this.foot[l] + '</th>';
			h += '</tr>'			
		}
		h += '<tr><th colspan="' + this.columns + '" class="' + this.controlClassName + '"></th></tr>';
		return h + '</tfoot></table>';
	},
	onmouseover: function(){if(this._jp_rinco_ui_t) $(this).addClassName(this._jp_rinco_ui_t.overClassName);},
	onmouseout: function(){if(this._jp_rinco_ui_t) $(this).removeClassName(this._jp_rinco_ui_t.overClassName);},
	setupTr: function(e,l) {
		$(e).addClassName(l%2==0 ? this.oddClassName : this.evenClassName);
		e._jp_rinco_ui_t = this;
		if (!this.overClassName.empty() && !e.onmouseover && !e.onmouseout) {
			e.onmouseover = this.onmouseover;
			e.onmouseout = this.onmouseout;				
		}
	},
	setupTable: function(t) {
		t = t==undefined ? this.target : $(t);
		if (!t) return;

		t.addClassName(this.tableClassName);
		t.setStyle(this.tableStyle);

		var e = t.tryDown('thead').down('tr');		
		if (e && e.down('th'))
			e.addClassName(this.headerTrClassName);

		var ts = t.tryDown('tbody').select('tr').filter(this.hasTd);
		for (var l=0; l<ts.length; l++)
			this.setupTr(ts[l],l);
		var e = t.down('tr th.' + this.controlClassName);
		if (e) {
			e._jp_rinco_ui_t = this;		
			this.control = e;
		}
	},

	initTable: function(t,ow,l){ t = $(t); if (!t) return;
		var tbl = t.down('table');
		if (tbl) this.analyzeTable(tbl);
		this.setDisplayColumn(l);
		if (ow===true)
			t.innerHTML = this.getTableHtml();
		this.target = t.down('table');
		if (this.rows < this.sortMinimum)
			this.isSortable = false;
		this.setupTable();
		this.update();
	},
	myClass: 'jp.rinco.ui.table',
	lastUpdate: "2008/10/21"
});

jp.rinco.ui.calender2 = new Class.create(jp.rinco.ui.baseObject, {
	initialize: function($super){
		$super();
		this.date = new Date();
		this.date.setDate(1);
		this.items = {};
	},

	// --------------- data control API ---------------
	repeatMax: 14,
	push: function(k,o){
		k = k instanceof Date ? k.toSimpleDateString('') : k;
		if (this.items[k] == undefined)
			this.items[k] = [];
		var v = o instanceof Element ? o.innerHTML : o;
		if(!this.items[k].include(v))
			this.items[k].push(v);
	},
	pushAuto: function(k,o){
		var ks = k.split(',');
		if (ks.length > 1) {
			for (var l=0; l<ks.length; l++)
				this.pushAuto(ks[l],o);
		} else {
			ks = k.toString().split('-');
			if (ks.length > 1) {
				var d = new Date(ks[0]);
				k = d.toSimpleDateString('');
				var ed = new Date(ks[1]).toSimpleDateString('');
				var count = 0;
				while(k <= ed && count<this.repeatMax) {
					this.push(k,o);				
					d.addDate(1);
					k = d.toSimpleDateString('');
					count++;
				}
			} else {
				this.push(new Date(k).toSimpleDateString(''),o);
			}
		}
	},
	get: function(k){
		return this.items[k] == undefined ? [] : this.items[k];
	},
	getDayBodyHtml: function(y,m,d) {
		y = y.toString().padding(4,'0');
		m = m.toString().padding(2,'0');
		d = d.toString().padding(2,'0');
		var ret = this.get(y+m+d).join('');
		ret += this.get(m+d).join('');
		ret += this.get(d).join('');
		return ret;
	},

	// --------------- Date control API ---------------
	today: new Date(),
	startYear: 0,
	startMonth: 1,
	endYear: 0,
	endMonth: 12,
	isStart: function(){return this.startYear>0 && (this.year()<this.startYear || (this.year()==this.startYear && this.month()<=this.startMonth));},
	isEnd: function(){return this.endYear>0 && (this.endYear<this.year() || (this.year()==this.endYear && this.endMonth<=this.month()));},
	addMonth: function(v){
		if (v == undefined){
			this.setYear(jp.rinco.today.getFullYear());
			this.setMonth(jp.rinco.today.getMonth()+1);
		} else
			this.date.addMonth(v);
		if (this.isStart()) {
			this.setYear(this.startYear);
			this.setMonth(this.startMonth);		
		} else if (this.isEnd()) {
			this.setYear(this.endYear);
			this.setMonth(this.endMonth);		
		}
	},

	// --------------- UI update APIs ---------------
	labels: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
	move: function(v){
		this.addMonth(v);
		this.update();
	},
	update: function(t, l){
	},	

	// --------------- others ---------------


	myClass: 'jp.rinco.ui.calender',
	lastUpdate: "2008/07/31"
});

/*
var cal = new jp.rinco.ui.calender2();
cal.push(new Date(),'000')
cal.pushAuto('2008/07/30,2008/07/31','aaa')
cal.pushAuto('2008/07/29-2008/07/31','bbb')
cal.pushAuto('2008/07/28-2008/07/30,2008/07/30-2008/07/31','ccc')
alert(Object.toJSON(cal.items));
alert(cal.myClass +' '+ cal.lastUpdate);
*/

jp.rinco.ui.calender = new Class.create(jp.rinco.ui.baseObject, {
	id: '',
	today: new Date(),
	start: 0,
	labels: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
	initialize: function($super, t, y, m, l){
		$super();
		this.date = new Date();
		this.date.setDate(1);
		this.screenBuffer = [];
		this.currentScreen = null;
		this.setYear(y);
		this.setMonth(m);
		if ($(t)) {
			this.target = $(t);
			this.update($(t),l);
		}
	},
	year: function(){return this.date.getFullYear();},
	setYear: function(n){if (n != undefined && !isNaN(Number(n))) this.date.setYear(Number(n))},
	month: function(){return this.date.getMonth() + 1;},
	setMonth: function(n){if (n != undefined && !isNaN(Number(n))) this.date.setMonth(Number(n)-1)},

	startYear: 0,
	startMonth: 1,
	endYear: 0,
	endMonth: 12,
	isStart: function(){return this.startYear>0 && (this.year()<this.startYear || (this.year()==this.startYear && this.month()<=this.startMonth));},
	isEnd: function(){return this.endYear>0 && (this.endYear<this.year() || (this.year()==this.endYear && this.endMonth<=this.month()));},
	move: function(v){
		if (v == undefined){
			this.date.setYear(this.today.getFullYear());
			this.date.setMonth(this.today.getMonth());
		} else
			this.date.addMonth(v);
		if (this.isStart()) {
			this.date.setYear(this.startYear);
			this.date.setMonth(this.startMonth-1);		
		} else if (this.isEnd()) {
			this.date.setYear(this.endYear);
			this.date.setMonth(this.endMonth-1);		
		}
		this.update();
	},
	getDayId: function(n){ n = Number(n);
		if(!isNaN(n) && n > 0)
			return this.id + this.screenKey + 'd_' + n;
		return '';
	},
	getDayElement: function(n){
		return $(this.getDayId(n));
	},
	getDayHeadElement: function(n){
		var d = this.getDayElement(n);
		if (d) return d.down('.day_head');
	},
	getDayBodyElement: function(n){
		var d = this.getDayElement(n);
		if (d) return d.down('.day_body');
	},

	header: '<table></thead>',
	dayStyle: '',
	headStyle: '',
	bodyStyle: '',
	getLabelHtml: function(l){
		l = l==undefined ? this.labels : l;
		var h = '';
		if (l && l.length==7) {
			h += '<tr>';
			for (var c=0; c<7; c++) {
				var v = (this.start + c) % 7;
				h += '<th class="label l_' + v + '">' + l[v] + '</th>';
			}
			h += '</tr></thead>';			
		}
		return h;
	},
	dayHeader: '',
	getDayHeadHtml: function(d,c){return '<div class="day_head"' + (this.headStyle=='' ? '' : ' style="'+this.headStyle+'"') + '>' + d + '</div>';},
	getDayBodyHtml: function(d,c){return '<div class="day_body"' + (this.bodyStyle=='' ? '' : ' style="'+this.bodyStyle+'"') + '></div>';},
	dayFooter: '',
	getDayHtml: function(d,c){
		var opt = this.date.isSameYear() && this.date.isSameMonth() && jp.rinco.today.getDate()==d ? ' today' : '';
		if (typeof isHoliday == 'function')
			opt += isHoliday(this.year(), this.month(), d) ? ' holiday' : '';
		return '<td id="' + this.id + this.screenKey + 'd_' + d + '" class="day l_' + c + opt + '"' + (this.dayStyle=='' ? '' : ' style="'+this.dayStyle+'"') + '>' + this.dayHeader + this.getDayHeadHtml(d,c) + this.getDayBodyHtml(d,c) + this.dayFooter + '</td>';
	},
	getBodyHtml: function(){
		var h = '<tbody><tr>';
		var c;
		for (c=0; c<this.date.getDaysBefore(this.start); c++)
			h += "<td></td>";
		for (var d=1; d <= this.date.getDaysOfMonth(); d++,c++) {
			if (c > 6) {
				h += "</tr><tr>";
				c = 0;
			}
			h += this.getDayHtml(d,c);
		}
		return h + '</tr></tbody>';
	},
	footer: '</table>',
	getHtml: function(l){return this.header + this.getLabelHtml(l) + this.getBodyHtml() + this.footer},
	update: function(t,l){
		t = t==undefined ? this.target : $(t);
		this.screenKey = "" + this.year() + this.month();
		if (this.currentScreen != null)
			this.currentScreen.hide();
		var screen = this.screenBuffer[this.screenKey];
		if (screen == undefined) {
			screen = document.createElement("div");
			t.appendChild(screen);
			screen = $(screen);
			this.screenBuffer[this.screenKey] = screen;
			screen.innerHTML = this.getHtml(l);
			if (this.elementList) {
				for (var l = 0; l < this.elementList.list.length; l++) {
					var i = this.elementList.list[l];
					if (i.year == this.year() && i.month == this.month()) {
						var d = this.getDayBodyElement(i.day);
						if (d) {
							d.appendChild(i);
						}
					}
				}
			}
			if (this.setupScreen instanceof Function)
				this.setupScreen();			
		} else
			screen.show();
		this.currentScreen = screen;
		if (this.setup instanceof Function)
			this.setup();			
	},
	myClass: 'jp.rinco.ui.calender',
	lastUpdate: "2008/10/21"
});

jp.rinco.ui.expandableElement = new Class.create(jp.rinco.ui.baseObject, {
	initialize: function($super){},
	source: 'div.title', target: 'pre', target2: '',
	invite: function(e,f){ e = $(e);
		if (e) {			
			var s = e.tryDown(this.source);
			if (s && !this.action.empty()) {
				if (this.setup instanceof Function)
					this.setup(e);			
				Event.observe(s, this.action, this.listener.bindAsEventListener(this));
				e._jp_rinco_ui_e = this;
			}
			if (f!=undefined) this.update(e,f)
			return e;
		}
	},
	listener: function(e){this.toggle(Event.element(e));},
	expand: function(e){
		e = jp.rinco.ui.upTarget(e,'_jp_rinco_ui_e');
		if (e) {
			var ee = this;
			ee.selectorOn(e.tryDown(ee.source));
			if (!ee.target.empty()) ee.targetOn(e.down(ee.target));
			if (!ee.target2.empty()) ee.targetOn(e.down(ee.target2));
		}
	},
	collapse: function(e){
		e = jp.rinco.ui.upTarget(e,'_jp_rinco_ui_e');
		if (e) {
			this.selectorOff(e.tryDown(this.source));
			if (!this.target.empty()) this.targetOff(e.down(this.target));
			if (!this.target2.empty()) this.targetOff(e.down(this.target2));
		}
	},
	update: function(e, f){if (f) this.expand(e); else this.collapse(e);},
	toggle: function(e){
		e = jp.rinco.ui.upTarget(e,'_jp_rinco_ui_e');
		if (e) this.update(e, this.isOff(e.tryDown(this.source)));
	},
	myClass: 'jp.rinco.ui.expandableElement',
	lastUpdate: "2008/09/22"
});

jp.rinco.ui.elementList = new Class.create(jp.rinco.baseObject, {
	initialize: function($super){
		this.list = [];
		this.length = 0;
	},
	beforePush: function(e) {
		e._jp_rinco_ui_lo = this.length;
		e._jp_rinco_ui_ls = this.length++;
		if (this.expandableElement) this.expandableElement.invite(e);
		if (this.setup instanceof Function) this.setup(e);		
	},
	push: function(e){ e = $(e); if (e) {
		this.beforePush(e);
		this.list.push(e);
	}},
	pushAll: function(p, css) {
		this.parent = $(p);
		if (this.parent) {with (this) {
			var cs = css==undefined ? parent.childElements() : parent.select(css);
			cs.each(function(e){push(e);});
		}}
	},
	sort: function(f){
		this.list.sort(f instanceof Function ? f : jp.rinco.ui.bySortKey);		
		var c = 0;
		if (this.parent) {with (this) {
			list.each(function(e){
				e._jp_rinco_ui_ls = c++;
				parent.removeChild(e);
				parent.appendChild(e);
			});	
		}}
	},
	insert: function(e,p,f){e=$(e);p=$(p); if (e&&p) {
		this.beforePush(e);
		f = f instanceof Function ? f : jp.rinco.ui.bySortKey;
		var flag = true;
		for (var l = 0; flag && l < this.list.length; l++) {
			if (e === this.list[l]) {
				flag = false;
			} else if (f(this.list[l],e) >= 0) {
				this.list.insertBefore(e,this.list[l]);
				p.insertBefore(e,this.list[l]);
				flag = false;
			}
		}
		if (flag){
			this.list.push(e);
			p.appendChild(e);		
		}
	}},
	insertAll: function(p,css,f) {
		this.parent = $(p);
		var ex = f instanceof Function ? f : jp.rinco.ui.bySortKey;
		if (this.parent) {with (this) {
			var cs = css==undefined ? parent.childElements() : parent.select(css);
			cs.each(function(e){insert(e,parent,ex);});
		}}
		alert(1);
	},
	isExpandMax: 6,
	isExpand: function(e) {return e._jp_rinco_ui_lo < 5 ? true : false;},
	updateExpand: function(f) {
		var ex = f==undefined ? this.isExpand : f;
		if (this.expandableElement && ex instanceof Function) {with (this) {
			list.each(function(e){expandableElement.update(e, ex(e));});
		}}
	},
	expandAll: function() {this.updateExpand(jp.rinco.alwaysTrue);},
	collapseAll: function() {this.updateExpand(jp.rinco.alwaysFalse);},
	expandHead: function(n) {
		n = n==undefined ? 1 : Number(n);
		if (this.expandableElement && !isNaN(n) && n <= this.list.length)
			for(var l=0; l<n; l++)
				this.expandableElement.expand(this.list[l]);
	},

	updateDisplay: function(f) {
		var ex = f==undefined ? jp.rinco.alwaysTrue : f;
		this.list.each(function(e){
			if(ex(e))
				e.show();
			else
				e.hide();
		});		
	},
	showAll: function() {this.updateDisplay(jp.rinco.alwaysTrue);},
	hideAll: function() {this.updateDisplay(jp.rinco.alwaysFalse);},

	myClass: 'jp.rinco.ui.elementList',
	lastUpdate: "2008/07/22"
});

jp.rinco.ui.singleSelection = new Class.create(jp.rinco.ui.baseObject, {
	selectors: [], targets: [], callbacks: [], selected: 0,
	push: function(selector, target){
		if (target == undefined)
			this.targets.push("");
		else {
			Event.observe($(selector), this.action, this._listener.bindAsEventListener(this));	
			this.targets.push(target);
		}
		$(selector)._jp_rinco_ui_s = this;
		if (this.setup instanceof Function) this.setup($(selector));
		this.selectors.push($(selector));
	},
	_listener: function(ev){
		var e = Event.element(ev);
		e = jp.rinco.ui.upTarget(e,'_jp_rinco_ui_s');
		if (e)
			this.listener.call(e);		
	},
	listener: function(){
		var ss = this._jp_rinco_ui_s;
		for (var l=0; l<ss.selectors.length; l++) {
			if (ss.selectors[l] == this) {
				ss.selectorOn(this,l);
				ss.targetOn(ss.targets[l],l);
				ss.selected = l;
			} else {
				ss.selectorOff(ss.selectors[l],l);
				ss.targetOff(ss.targets[l],l);				
			}
		}
		if (ss.callbacks[ss.selected] instanceof Function) ss.callbacks[ss.selected].call(ss);
		if (ss.callback instanceof Function) ss.callback.call(ss);
	},
	select: function(n) {
		if (typeof(n)=="number") {
			if (-1 < n && n < this.selectors.length) {
				this.listener.call(this.selectors[n]);
				return true;				
			}
		} else {
			n = $(n);
			if (!n) 
				return false;
			if (n._jp_rinco_ui_s && n._jp_rinco_ui_s == this) {
				this.listener.call(n);
				return true;
			} else 
				for (var l = 0; l < this.selectors.length; l++) {
					if ($(this.targets[l]) == n) {
						this.listener.call(this.selectors[l]);
						return true;
					}
				}
		}
		return false;
	},
	myClass: 'jp.rinco.ui.singleSelection',
	lastUpdate: "2008/09/22"
});


/* ***** short names (_jp_rinco_ui_*)*****
 * expandableElement: e
 * elementList: lo,ls
 * singleSelection: s
 * table: t
 */

jp.rinco.ui.upTarget = function(e,n) {
	return !e||e==document ? null : e[n] ? e : jp.rinco.ui.upTarget(e.parentNode,n);
}

