// IDにopenと命名しても動いてくれない。

// InlineImgのidに日本語指定をするとIEで動かない。
// InlinImgはjpg,gif,png,bmp,あとなんだっけ。複数の画像形式に対応させたい。
function Debug(obj,isAlert)
{
	var str = "";
	for (var i in obj){
		str += i + " : " + obj[i] + "<br>\n";
	}
	if (isAlert){
		alert(str);
	} else {
		$(document.body).innerHTML += str;
	}
}

var U64 = Class.create();
U64.str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_';
Number.prototype.U64 = function(){
	var numeric = this;
	var tmp ='';
	while (numeric){
		var n = numeric%64;
		tmp = U64.str.substr(n,1) + tmp;
		numeric = (numeric - n)/64;
	}
	return tmp;
}
String.prototype.U64 = function(){
	var str = this;
	var n = 0;
	for (var i=0;i<str.length;++i){
		n = n*64 + U64.str.indexOf(str.substr(i,1));
	}
	return n;
}

function AddCSS(list){
	var sheet = null;
	if (Prototype.Browser.IE){
		sheet = document.createStyleSheet();
	} else {
		var element = new Element('style');
		$(document.getElementsByTagName('head')[0]).insert(element);
		sheet = element.sheet;
	}
	list.each(function(item){
		if (Prototype.Browser.IE){
			sheet.addRule(item[0],item[1]);
		} else {
			sheet.insertRule(item[0] + ' { ' + item[1] + ' }',sheet.cssRules.length);
		}
	});
}

AddCSS([
	// Inline各種用
	['.Inline:hover',"background-color:#9999FF; cursor: pointer;"],
	['tbody.Inline:hover',"background-color:#cccccc; cursor: normal;"],
	['tbody.Inline td',"background-color:#9999FF; cursor: pointer;"],
	['.InlineImg',"border:1px solid;padding:3px;background-color:#EEEEEE"],
	// CheckableForm用
	['.ok',"color:#33FF33; font-weight:bold;"],
	['.ng',"color:#FF3333; font-weight:bold;"],
	// Prompt用
	['.Prompt',"background-position:left top;background-repeat:no-repeat;border:#7E9DB9 solid 1px;"]
]);


String.prototype.br2nl = function(){
	return this.replace(/<BR\s*\/?>/mgi,"\r\n");
};
String.prototype.nl2br = function(){
	return this.replace(/\r?\n/mg,"<BR>");
};

Array.prototype.unique = function(){
	var storage = {};
	var uniqueArray = [];

	var i, value;
	for (i = 0; i < this.length; i++) {
		value = this[i];
		if (!(value in storage)) {
			storage[value] = true;
			uniqueArray.push(value);
		}
	}

	return uniqueArray;
}

function GetKeyCode(e){
	if (!e) e = event;// IE対策
	return e.keyCode || e.charCode;
}

if (Object.isUndefined(Inline)) { var Inline = { } }


// 入力を自動チェックするフォーム
CheckableForm = Class.create({
	initialize: function(element,options){
	    if (!(element = $(element))) return;
	    var ref = this;
	    this.element = element;
		this.options = Object.extend({
			button : null,
			list : {}
		}, options || {});
		var options = this.options;

		element.select("input[type='text']").each(function(node){
			if (!Prototype.Browser.IE){// 打鍵チェックはIEでは重くなるからやめておく
				node.observe('keyup',ref.inspect.bind(ref));
			}
			node.observe('blur',ref.inspect.bind(ref));
		});
		element.select("input[type='radio']").each(function(node){
			node.observe('click',ref.inspect.bind(ref));
		});
		element.select("input[type='checkbox']").each(function(node){
			node.observe('click',ref.inspect.bind(ref));
		});
		element.select("textarea").each(function(node){
			if (!Prototype.Browser.IE){
				node.observe('keyup',ref.inspect.bind(ref));
			}
			node.observe('blur',ref.inspect.bind(ref));
		});
		element.select("select").each(function(node){
			node.observe('change',ref.inspect.bind(ref));
		});
		this.inspect();
	},
	inspect : function(){
		var flag = true;
		var param = this.element.serialize().toQueryParams();
		var Set = function(obj,b){
			if (b){
				obj.addClassName('ok').removeClassName('ng').update('OK!');
			} else {
				obj.addClassName('ng').removeClassName('ok').update('(必須)');
			}
			return b;
		}

		$w(this.options.w).each(function(item){
			flag = Set($('check_' + item),param[item]) && flag;
		});
		$H(this.options.list).each(function(item){
			flag = Set($('check_' + item[0]),item[1](param)) && flag;
		});

		$(this.options.button)[flag ? 'enable' : 'disable']();
		// IEではdisable変更すると無駄に1クリック必要になるバグがあったような？
		// ダミーとの表示入れ替えで対処する。
	//	$(this.options.button)[flag ? 'show' : 'hide']();
	//	$(this.options.button + 'dummy')[flag ? 'hide' : 'show']();
	}
});



Object.extend(Inline,{
	images : [],
	create : function(){
		var options = Object.extend({
			// ユーザ指定データ
			selector : '',						// cssセレクタ
			id : null,							// DOM要素
			edit : true,						// 編集可能にするか？
			require : false,					// 編集後、データは必須か？(null不許可か？)
			data : '',							// データ
			list : null,						// InlineText専用。単語候補のリスト

			// 自動生成データ
			element : null,						// 編集用の要素
			obj : null,							// データ本体の格納位置

			// 振る舞い関数群
			target : function(options){		// ターゲットオブジェクト特定
				options.obj = $(options.id) || $$(options.selector)[0];
			},
			show : function(options){			// データ表示
				options.obj.update(options.data);
			},
			attention : function(options){			// 本体の入力注目
				options.obj.addClassName('Inline');
			},
			create : function(options){			// 編集オブジェクト生成
				return new Element('textarea',{
					style : 'position:absolute;display:none;'
				});
			},
			position : function(options){
				options.element.clonePosition(options.obj);
			},
			setdata : function(options){
				options.element.value = options.data;
			},
			getdata : function(options){
				return options.element.value;
			},
			compare : function(options,value){	// データ比較
				return options.data != value;
			},
			update : Prototype.emptyFunction,	// データ更新
			init : Prototype.emptyFunction,		// 追加初期化
			preShow : Prototype.emptyFunction	// 表示直前調整
		}, arguments[0] || {});
		options.target(options);
		options.show(options);

		if (options.edit){
			options.attention(options);
			options.obj.onclick = function(){
				if (!options.element){
					options.element = options.create(options);
					$(document.body).insert(options.element);
					options.position(options);
					options.element.style.fontSize = options.obj.getStyle('fontSize');
			//		options.element.style.borderWidth = options.obj.getStyle('borderWidth');
					options.setdata(options);
					options.element.show().focus();
					options.blur = function(){
						var data = options.getdata(options);
						if (data || !options.require){
							if (options.compare(options,data)){
								options.data = data;
								options.show(options);
								options.update(data);
								Inline.update();
							}
							options.element.hide();
						}
					}
					options.element.observe('blur',options.blur);
					options.init(options);
				}
				options.preShow(options);
				options.element.show().focus();
				Inline.images.each(function(item){
					if (item.options.element){
						item.options.element.hide();
					}
				});
			}
		}
	},
	update : function(){
		Inline.ans.show();
		setTimeout(function(){
			Inline.ans.hide();
		},1000);
	}
});

/*
var InlineDate = function(obj,func){
	var tmp = obj.innerHTML.split(' ')[0];
	obj.innerHTML = (tmp == '1900-01-01') ? '' : tmp;
	obj.onclick = function(){
		if (!obj.EditElement){
			var tmp = new Element('input',{
				type : 'text',
				style : 'position:absolute;display:none'
			});
			$(document.body).insert(tmp);
			Position.clone(obj,tmp);
			tmp.show().focus();
			tmp.value = obj.innerHTML;

			var UpdateAjax = function(){
				if (obj.innerHTML != tmp.value){
					obj.update(tmp.value);
					func(tmp.value || '1900-01-01');
				}
				tmp.hide();
			}
			tmp.onblur = UpdateAjax;
			tmp.onkeydown = function(e){
				if (GetKeyCode(e) == 13){
					UpdateAjax();
				}
			}
			new InputCalendar(tmp, {
				format: 'yyyy-mm-dd',
				weekFirstDay:ProtoCalendar.SUNDAY,
				lang:'ja',
				triggers: [obj]
			}).addChangeHandler(UpdateAjax);
			obj.EditElement = tmp;
		}
		obj.EditElement.show().focus();
	}
	return obj;
}
*/

// imgタグのidを指定する。このidが、アップロードされた際のファイル名になる。
// imgタグにはalt属性を指定しておかないと、GoogleChromeで枠が生成されない。
InlineImg = Class.create({
	initialize: function(){
		var nth = Inline.images.length;
		Inline.images.push(this);
		this.options = Object.extend({
			selector : '',
			id : null,
			className : '',
			edit : true,
			require : false,
			data : '',
			alt : '画像アップロード',
			show : function(options){	// 編集しないときの表示方法
				if (options.isExist){
					options.obj.insert(new Element('img',{
						className : options.className,
						src : options.data
					}));
				}
			},
			update : Prototype.emptyFunction
		}, arguments[0] || {});
		var options = this.options;
		var obj = $(options.id) || $$(options.selector)[0];
		options.obj = obj;

		if (!$('frame')){
			$(document.body).insert(new Element('iframe',{
				style : 'display:none;width:0px;height:0px;',
				id : 'frame',
				name : 'frame'
			}));
		}

		var Show = function(isExist){
			if (options.edit){
				var img = new Element('img',{
					alt : options.alt,
					className : options.className,
					src : (isExist ? options.data : '')
				});
				obj.addClassName('Inline');
				obj.insert(img);
				var fix = options.data.toLowerCase().substr(options.data.lastIndexOf('.'));
				options.isImage = false;
				$w('.jpg .png .gif').each(function(item){
					if (fix == item) options.isImage = true;
				});
				if (!options.isImage && isExist){
					obj.insert(new Element('a',{
						href : options.data,
						target : '_blank'
					}).insert(options.alt));
				}

				img.onclick = function(){
					if (!options.element){
						options.element = new Element('div',{
							className : 'InlineImg',
							style : 'position:absolute;display:none'
						});
						var opt = 'data=' + encodeURIComponent(options.data) + '&n=' + nth;
						var form = new Element('form',{
							target : 'frame',
							action : Inline.path + 'upload.php?' + opt,
							enctype : 'multipart/form-data',
							encoding : 'multipart/form-data',	// IE対策。
							method : 'post'
						});
						options.element.insert(form);
						var button = new Element('input',{type : 'button',value : 'アップロード'});
						button.onclick = function(){
							form.action = Inline.path + 'upload.php?' + opt;
							form.submit();
							d.enable();
							options.element.hide();
						}
						var d = new Element('input',{type : 'button',value : '削除',style : 'margin-left:10px;'});
						d.onclick = function(){
							if (window.confirm('画像ファイルを削除してもよろしいですか？')){
								form.action = Inline.path + 'upload.php?del=del&' + opt;
								form.submit();
								d.disable();
								options.element.hide();
							}
						}
						form.insert(new Element('input',{type : 'file',name : 'Filedata'}))
							.insert(button)
							.insert(d);
						$(document.body).insert(options.element);
						options.element.clonePosition(options.obj,{
							setWidth : false,
							setHeight : false
						});
						options.element.setStyle({
							'top' : (parseInt(options.element.getStyle('top')) + options.obj.getDimensions()['height']) + 'px'
						});
						if (!isExist){
							d.disable();
						}
					}
					options.element.toggle();
				}
			} else {
				options.isExist = isExist;
				options.show(options);
			}
		}

		new Ajax.Request(Inline.path + 'upload.php?exist=' + encodeURIComponent(options.data),
		{
			onComplete : function(request){
				Show(request.responseText == 'true');
			}
		});
	}
});

Object.extend(InlineImg, {
	update : function(nth,data){
		var options = Inline.images[nth].options;
		var obj = options.obj;
		$(obj.firstChild).setAttribute('src',data);
		if (!options.isImage){
			if (data.split('?')[0] == 'null'){
				obj.childNodes[1].remove();
			} else {
				obj.insert(new Element('a',{
					href : options.data,
					target : '_blank'
				}).insert(options.alt));
			}
		}
	}
});

InlineMultiSelect = Class.create({
	initialize: function(){
		Inline.create(Object.extend({
			target : function(options){
				options.obj = $(options.id) || $$(options.selector)[0];
				options.texts = $A(options.texts);
			},
			show : function(options){
				var tmp = options.data.split(',');
				var arr = {};
				tmp.each(function(item){
					arr[item] = true;
				});
				options.obj.update();
				if (options.values){
					options.values.each(function(item,i){
						if (arr[item]){
							options.obj.insert(options.texts[i]);
						}
					});
				} else {
					options.texts.each(function(item){
						if (arr[item]){
							options.obj.insert(item);
						}
					});
				}
			},
			create : function(options){
				return new Element('select',{
					size : options.texts.length,
					multiple : true,
					style : 'position:absolute;display:none'
				});
			},
			position : function(options){
				options.element.clonePosition(options.obj,{
					setWidth : false,
					setHeight : false
				});
			},
			setdata : function(options){
				var tmp = options.data.split(',');
				var arr = {};
				tmp.each(function(item){
					arr[item] = true;
				});
				if (options.values){
					options.values.each(function(item,i){
						var opt = new Element('option',{value : item}).insert(options.texts[i]);
						opt.selected = arr[item];
						options.element.insert(opt);
					});
				} else {
					options.texts.each(function(item){
						var opt = new Element('option',{value : item}).insert(item);
						opt.selected = arr[item];
						options.element.insert(opt);
					});
				}
			},
			getdata : function(options){
				str = '';
				$A(options.element.options).each(function(item){
					if (item.selected){
						str += item.value + ',';
					}
				});
				return str.substr(0,str.length -1);
			}
		}, arguments[0] || {}));
	}
});

InlineSelect = Class.create({
	initialize: function(){
		Inline.create(Object.extend({
			target : function(options){
				options.obj = $(options.id) || $$(options.selector)[0];
				options.texts = $A(options.texts);
			},
			show : function(options){
				if (options.values){
					options.values.each(function(item,i){
						if (options.data == item){
							options.obj.update(options.texts[i]);
							return;
						}
					});
				} else {
					options.texts.each(function(item){
						if (options.data == item){
							options.obj.update(item);
							return;
						}
					});
				}
			},
			create : function(options){
				return new Element('select',{
					size : options.texts.length,
					style : 'position:absolute;display:none'
				});
			},
			position : function(options){
				options.element.clonePosition(options.obj,{
					setWidth : false,
					setHeight : false
				});
			},
			setdata : function(options){
				if (options.values){
					options.values.each(function(item,i){
						var opt = new Element('option',{value : item}).insert(options.texts[i]);
						opt.selected = (options.data == item);
						options.element.insert(opt);
					});
				} else {
					options.texts.each(function(item){
						options.element.insert(new Element('option',{value : item,selected : (options.data == item)}).insert(item));
					});
				}
			},
			getdata : function(options){
				var value = null;
				$A(options.element.options).each(function(item){
					if (item.selected){
						value = (options.values) ? item.value : item.innerHTML;
					}
				});
				return value;
			}
		}, arguments[0] || {}));
	}
});

InlineText = Class.create({
	initialize: function(){
		Inline.create(Object.extend({
			create : function(){
				return new Element('input',{
					type : 'text',
					style : 'position:absolute;display:none'
				});
			},
			compare : function(options,value){
				var check = false;
				if (options.list){
					options.list.each(function(item){
						if (item == value) check = true;
					});
				} else {
					check = true;
				}
				return check && (options.data != value);
			},
			init : function(options){
				options.element.onkeydown = function(e){
					if (GetKeyCode(e) == 13){
						options.blur();
					}
				}
				if (options.list){
					var div = new Element('div',{style : "display:none;border:1px solid black;background-color:white;height:100px;overflow:auto;"});
					$(document.body).insert(div);
					new Autocompleter.Local(options.element,div,options.list,{
						tokens: [',','\n'],
						fullSearch: true,
						partialSearch: true,
						afterUpdateElement: function(a,b){
							var str = b.innerHTML.stripTags();
							if (options.obj.innerHTML != str){
								options.element.value = str;
								options.data = str;
								options.show(options);
								options.update(str);
								Inline.update();
							}
						}
					});
				}
			}
		}, arguments[0] || {}));
	}
});

InlineTextArea = Class.create({
	initialize: function(){
		Inline.create(Object.extend({
			show : function(options){
				options.obj.update(options.data.nl2br());
			},
			create : function(){
				return new Element('textarea',{
					style : 'position:absolute;display:none;'
				});
			},
			compare : function(options,value){
				return value.nl2br() != options.data.nl2br();
			},
			init : function(options){
				options.element.onkeydown = function(e){
					SetTab();
				}
				options.element.onkeypress = function(e){
					SetTab2(e);
				}
			},
			preShow : function(options){
				options.element.setStyle({
					'height' : Math.max(options.obj.getDimensions()['height'],100) + 'px'
				});
			}
		}, arguments[0] || {}));
	}
});

InlineTable = Class.create({
	initialize: function(){
		var regAll = new RegExp(/(("[^"]*\r?\n+[^"]*")|([^"\t\r\n]*))(\t|\r?\n)/g);
		var regMulti = new RegExp(/"([^"]*\r?\n+[^"]*)"(\t|\r?\n)$/);
		var regSingle = new RegExp(/(.*?)(\t|\r?\n)$/);
		Inline.create(Object.extend({
			target : function(options){
				var table = $(options.id) || $$(options.selector)[0];
				options.obj = table.select('tbody')[0];
				options.position = function(options){
					options.element.clonePosition(table);
					var height = table.select('thead')[0].getDimensions()['height'];
					options.element.setStyle({
						'top' : (parseInt(options.element.getStyle('top')) + height) + 'px'
					});
				}
			},
			convert : function(options){
				/*
				// シンプルなcsv形式用
				var tmp = options.data.split('\n');
				var data = [];
				tmp.each(function(item,i){
					data[i] = item.split('\t');
				});
				return data;
				*/

				// エクセルのセル内改行対応用
				var data = options.data || "\t\n";
				var tmp = data.match(regAll);
			//	$(document.body).insert(tmp.inspect());
				var arr = [[]];
				var col = 0;
				var row = 0;
				for (var i=0;i<tmp.length;++i){
					var obj = tmp[i];
					var isNl = (obj.substr(obj.length-1,1) != "\t");
					if (obj.substr(0,1) == '"'){
						arr[col][row] = obj.match(regMulti)[1].nl2br();
					} else {
						arr[col][row] = obj.match(regSingle)[1];
					}
					row++;
					if (isNl){
						col++;
						row = 0;
						arr.push([]);
					}
				}
				return arr.slice(0,arr.length-1);
			//	$(document.body).insert(arr.inspect());
			},
			show : function(options){
				var data = options.convert(options);
				options.obj.update();
				data.each(function(row){
					var tr = new Element('tr',{height : '10px',className : 'InlineData'});
					options.obj.insert(tr);
					row.each(function(col){
						tr.insert(new Element('td').insert(col));
					});
				});
			},
			attention : function(options){
				options.obj.onmouseover = function(){
					options.obj.addClassName('Inline');
				}
				options.obj.onmouseout = function(){
					options.obj.removeClassName('Inline');
				}
			},
			create : function(){
				return new Element('textarea',{
					style : 'position:absolute;display:none;'
				});
			},
			init : function(options){
				options.element.onkeydown = function(e){
					SetTab();
				}
				options.element.onkeypress = function(e){
					SetTab2(e);
				}
			},
			preShow : function(options){
				options.element.setStyle({
					'height' : Math.max(options.obj.getDimensions()['height'],100) + 'px'
				});
			}
		}, arguments[0] || {}));
	}
});



Prompt = Class.create({
	initialize : function(element,options){
	    if (!(element = $(element))) return;
	    var ref = this;
		this.options = Object.extend({
			image : ''
		}, options || {});
		element.addClassName('Prompt');
		var blur = function(){
			if (!element.value){
				element.setStyle({
					backgroundImage : 'url(' + ref.options.image + ')'
				});
			}
		}
		element.observe('focus',function(){
			element.setStyle({
				backgroundImage : ''
			});
		}).observe('blur',blur);
		blur();
	}
});





// 調整イベント
Event.observe(window, 'load', function(){

	// Inline更新時のメッセージオブジェクトを生成する。
	Inline.ans = new Element('div',{//
		style : 'display:none;position:fixed;left:5px;top:4px;background-color:#E0ECFF;color:blue;font-weight:bold;border:solid #666666;padding:2px;'
	}).insert('データ更新しました');
	$(document.body).insert(Inline.ans);

	// IEではなぜか1回目のclonePositionを失敗してしまうので、ここでやっておく。
	var tmp = new Element('textarea',{
		style : 'position:absolute;display:none;'
	});
	$(document.body).insert(tmp);
	tmp.clonePosition($(document.body));
	tmp.remove();

}, false);


