/**
 *
 * アイテム
 *
 */
function Item(elem) {
	this.elme = elem;
	this.itemid = Item.getID(elem);
}
Item.ACT_DELETE = "del";
Item.ACT_EDIT   = "edit";
Item.getID = function(elem) {
	var rowid = $(elem).parents("tr").attr('id');
	return rowid.substring(4, rowid.length);
}

Item.prototype = {
	action: function(data, callback) {
		var itemid = this.itemid;
		data.itemid = itemid;

		$.ajax({
			type: "post",
			dataType: "jsonp",
			data: data,
			url: "/item",
			success: function (data) { if ($.isFunction(callback)) callback.apply(this, [itemid]) }
		});

	},

	del: function(callback) {
		this.action({act:Item.ACT_DELETE}, callback);
	},

	purchased: function(callback) {
		this.action({act:Item.ACT_EDIT, purchased: 1}, callback);
	},

	edit: function(data, callback) {
		if (data == null) return;
		data.act = Item.ACT_EDIT;
		this.action(data, callback);
	}
}

/**
 * ItemImage
 */
function ItemImage(src) {
	img = new Image();
	img.src = src

	this.width  = 90;
	this.height = 90;

	if ((img.width <= this.width) && (img.height <= this.height)) {
		this.width  = img.width;
		this.height = img.height;
	} else {
		if (img.width > img.height) {
			this.height = (this.width / img.width) * img.height;
		} else {
			this.width = (this.height / img.height) * img.width;
		}
	}
}

/**
 * スター
 * 
 * TODO あとでリファクタリング (StarMarkクラスメソッドなど）
 */
function Star(elem, option) {
	var self = this;
	this.out_flag = true;
	$(elem).children("img")
		.mouseover(function(){
			$(this).css("cursor", "pointer");
			if (self.out_flag)
				self.prerank = self.rank(this);
			StarMark.mouseover(this);
			self.out_flag = false;
		})
		.mouseout(function(){
			self.out_flag = true;
			$(this).css("cursor", "default");
			StarMark.mouseout(self.prerank, this);
		})
		.click(function(){
			self.prerank = self.rank(this);
			if ((option == null) || (!option.uiOnly)) {
				var itemid = Item.getID(this);
				$.ajax({
					type: "post",
					dataType: "jsonp",
					data: {"itemid": itemid, "star": self.rank(this), "act": "edit"},
					url: "/item"
				});
			}
		})
		.dblclick(function(){
			self.prerank = 0;
			if ((option == null) || !option.uiOnly) {
				var itemid = Item.getID(this);
				$.ajax({
					type: "post",
					dataType: "jsonp",
					data: {"itemid": itemid, "star": 0, "act": "edit"},
					url: "/item"
				});
			}
		});
}
Star.prototype = {
	prerank: 0,
	rank: function(elem) {
		return StarMark.parent(elem).children("img[src="+ StarMark.MARK_SRC +"]").length
	}
}

function StarMark() {
}
StarMark.MARK_SRC = "/img/icon_star_ye.gif";
StarMark.NO_MARK_SRC = "/img/icon_star_wh.gif";

StarMark.mouseover = function(starmark) {
	StarMark.mark(starmark);
}

StarMark.mouseout = function(rank, elem) {
	if (rank == 0) {
		$(elem)
			.attr("src", StarMark.NO_MARK_SRC)
			.siblings("img").attr("src", StarMark.NO_MARK_SRC);
	} else {
		StarMark.mark(StarMark.parent(elem).children("img[name='"+ rank +"']"));
	}
}

StarMark.mark = function(starmark) {
	$(starmark)
		.attr("src", StarMark.MARK_SRC)
		.prevAll("img").attr("src", StarMark.MARK_SRC)
		.end()
		.nextAll("img").attr("src", StarMark.NO_MARK_SRC);
}

StarMark.parent = function(starmark) {
	return $(starmark).parent(".star");
}


/**
 *
 * パッド
 *
 */
function Pad() {
}
Pad.prototype = {
	add: function(callback) {
		if (pad_name = prompt('新しく作成するパッド名を入力してください','')) {
			$.ajax({
				dataType: 'jsonp',
				type: 'POST',
				data: {'pad_name': pad_name},
				url: '/pad',
				success: function(data) { 
					if ($.isFunction(callback)) {
						callback.apply(this, [pad_name, data])
					} else {
						location.reload();
					}
				},
				error: function() { alert('パッドの作成に失敗しました。') }
			});
		}
	},

	copy: function(padid, user_name, init_name) {
		if (pad_name = prompt('コピー先のパッド名を入力してください', init_name)) {
			$.ajax({
				type: "post",
				dataType: 'jsonp',
				type: 'POST',
				data: {act:"copy", "padid":padid, "user_name":user_name, 'pad_name': pad_name },
				url: '/pad',
				success: function(data) {
					if (data.status == "error") {
						alert('パッドのコピーに失敗しました。');
					} else {
						location.href = data.href;
					}
				},
				error: function() { alert('パッドのコピーに失敗しました。') }
			});
		}
	}
}

/**
 *
 * メニュー
 *
 * TODO Menuアイテムを作成する
 */
function Menu(owner, menu, option) {
	var self = this;
	this.owner = $(owner);
	this.menu = $(menu);
	this.option = (option == null) ? {} : option;

	this.owner
		.click(function(e){
			var click = $.isFunction(self.option.click) ? self.option.click.apply(this, []) : (self.option.click == null ? true : self.option.click);
			if (click) {
				self.show();
				this.focus();
			}
			e.preventDefault();
		})
		.blur(function(){
			if (!menu.children(".menu_item").hasClass("menu_item_over")) {
				self.menu.hide();
			}
		});

	this.menu
		.hide()
		.css({"position":"absolute"})
		.appendTo("body")
		.children(".menu_item")
		.mouseover(function(){$(this).addClass("menu_item_over")})
		.mouseout(function(){$(this).removeClass("menu_item_over")})

}
Menu.prototype = {
	show: function() {
		var offset = this.owner.offset();
		var left = (this.option.x == "left") ? offset.left : offset.left + this.owner.width() - this.menu.width();

		this.menu.css({
			"top": offset.top + this.owner.height() + 3,
			"left": left
		}).slideToggle(50);
	},
	close: function() {
		this.menu.hide();
	}
}

/**
 *
 * EditableText
 *
 */
function EditableText(option) {
	this.option = option;
	var self = this;

	$(option.elem)
		.click(function(){
			var elem = this;
			var to = $(elem);
			if (to.children(":input").size() > 0) return;
			var old_text = this.old_text = to.text();
			var css = (option.css == null) ? {} : option.css;
			var input = this.input = $('<input type="text" />')
				.addClass((option.input_class == null) ? "" : option.input_class)
				.css((option.css == null) ? {} : option.css)
				.val(old_text)
				.keypress(function(e){
					switch (e.keyCode) {
						case 13: self.update(elem); break;
						case 27: self.restore(elem, old_text); break;
					}
				})
				.blur(function(){ self.update(elem); })

			if (option.width == 'fit') {
				input.width(to.width());
			} else if (option.width != null) {
				input.width(option.width);
			}

			if (option.height != null) input.height(option.height);

			to.empty().append(input);
			input.select();
		})
}
EditableText.prototype = {
	update: function(elem) {
		var text = elem.input.val();
		if ($.isFunction(this.option.is_default)) {
			if (this.option.is_default.apply(elem, [text])) {
				text = this.option.default_value;
				elem.input.val(text);
			}
		}
		if ((text != elem.old_text) && $.isFunction(this.option.update)) this.option.update.apply(elem, [text, elem.old_text]);
		this.restore(elem, text);
	},
	restore: function(elem, text) {
		$(elem).empty().text(text);
	}
}


/**
 *
 * EditText
 *
 */
function EditText(option) {
	this.option = option;

	if (option.label_edit   == null) { option.label_edit   = "[編集]"; }
	if (option.label_update == null) { option.label_update = "[更新]"; }
	if (option.label_cancel == null) { option.label_cancel = "[キャンセル]"; }

	var self = this;
	$(option.trigger).click(function(e){
		e.preventDefault();

		var to = this;
		var trigger = $(to);
		if (trigger.text() == option.label_update) {
			self.update(to);
			if ($.isFunction(option.finalize)) option.finalize.apply(self, [to, to.elem]);
		} else {
			var elem = this.elem = $.isFunction(option.elem) ? option.elem.apply(self, [trigger]) : $(option.elem);
			var old_text = this.old_text = elem.html().replace(/<.*?br.*?>/gi, "\n");
			var input = this.input = $((option.input_type == 'textarea') ? '<textarea />' : '<input type="text" />')
							.addClass((option.input_class == null) ? "" : option.input_class)
							.css((option.css == null) ? {} : option.css)
							.width($.isFunction(option.width) ? option.width.apply(self, [elem]) : (isNaN(option.width) ? 80 : option.width))
							.val(old_text.replace(/<.*?br.*?>/gi, "\n").replace(/&amp;/gi, "&"));

			if ($.isFunction(option.init)) option.init.apply(self, [to, elem]);

			if (option.input_type == 'textarea') {
				input.height($.isFunction(option.height) ? option.height.apply(self, [elem]) : (isNaN(option.height) ? 80 : option.height));
			} else {
				input.keypress(function(e){
					switch (e.keyCode) {
						case 13: self.update(to); break;
						case 27: self.restore(to, old_text); break;
					}
				});
			}

			var cancel = this.cancel = $("<a />")
							.text(option.label_cancel)
							.click(function(){
								trigger.text(option.label_edit);
								elem.html(old_text.replace(/\n/g, "<br/>"));
								input.remove();
								$(this).remove();
								if ($.isFunction(option.finalize)) option.finalize.apply(self, [to, elem]);
							});

			elem.empty();
			if (elem.parent().is("a")) {
				elem.parent().before(input);
			} else {
				elem.append(input);
			}
			input.select();
			trigger.text(option.label_update).after(cancel);
		}
	});
}
EditText.prototype = {
	update: function(to) {
		var text = to.input.val();
		if ((text != to.old_text) && $.isFunction(this.option.update)) {
			this.option.update.apply(to, [text, to.old_text]);
		}
		this.restore(to, text);
	},
	restore: function(to, text) {
		to.elem.html(text.replace(/\n/g, "<br/>").replace(/&/gi, "&amp;"));
		$(to).text(this.option.label_edit);
		to.input.remove();
		to.cancel.remove();
	}
}


/**
 *
 * タグ
 *
 */
function Tag(elem) {
	new EditText({
		elem: function(trigger){return $(trigger).parent().find(".tag_text");},
		trigger: $(elem).children(".tag_edit"),
		input_class: "editable_text",
		width: function(elem) { return elem.width() < 80 ? 80 : elem.width(); },
		update: function(text, old_text) {
			$.ajax({
				dataType: 'jsonp',
				type: "post",
				data: {"act": "edit", "tag": text, "padid": $(this).parent().children("input[name=padid]").val()},
				url: "/pad"
			});
		}
	});
}

/**
 *
 * アクションアイテム
 *
 */
function ActionItem(item) {
	this.item = $(item);
	this.enabled = true;
}
ActionItem.prototype = {
	enable: function() {
		if (this.enabled) return;
		this.enabled = true;

		this.item.removeClass("action_item_disabled")
		.find("img").each(function(){
			var src = new String(this.src);
			var ext = src.substring(src.lastIndexOf("."), src.length);
			this.src = src.substring(0, src.lastIndexOf('_disabled')) + ext;
		});
	},

	disable: function() {
		if (!this.enabled) return;
		this.enabled = false;

		this.item.addClass("action_item_disabled")
		.find("img").each(function(){
			var src = new String(this.src);
			var ext = src.substring(src.lastIndexOf("."), src.length);
			this.src = src.substring(0, src.lastIndexOf(".")) + '_disabled' + ext;
		});
	},

	toggle: function(enabled) {
		if (enabled) {
			this.enable();
		} else {
			this.disable();
		}
	}
}

function Message(msg) {
	this.msg = msg
}
Message.prototype = {
	show: function() {
		msg = $("<div/>")
			.hide()
			.addClass("message")
			.text(this.msg)
			.appendTo("body");

		msg.css({
				"position": "absolute",
				"top": "50%",
				"left": "50%",
				"overflow": "hidden",
				"margin": "-" + msg.height() + "px 0 0 -" + msg.width() + "px"
			})
			.show()

		setTimeout(function(){msg.fadeOut(3000);}, 2000);
		setTimeout(function(){msg.remove();}, 10000);
	}
}

