$.fn.dsave = function(url, addrow, allowEmptyRow) {
	if (!$.isset(allowEmptyRow))
		allowEmptyRow = false;

	var form = this;
	var tbody = form.find('tbody');
	if (tbody.length == 0)
		tbody = $('<tbody></tbody>').appendTo(form.find('table'));
	var add = $('<input type="button" />')
		.attr('id', 'dsave-add')
		.val('추가');
	var refresh = $('<input type="button" />')
		.attr('id', 'dsave-refresh')
		.val('새로고침');
	var save = $('<input type="submit" />')
		.addClass('strong')
		.val('저장');

	form.append(
		$('<div></div>')
			.addClass('submit')
			.append(add)
			.append(refresh)
			.append(save)
	).append($('<div></div>').css('clear', 'both'))

	form.dform({
		'submit': function() {
			if (form.attr('enctype') == 'multipart/form-data')
				return true;
			if (save.dformIsLoading())
				return false;
			save.dformLoading();
			$.post(form.attr('action'),
				form.serialize(), function(data) {
				save.dformLoaded();
				if (data == '__OK__') {
					$('<div class="msg"></div>')
						.html('저장되었습니다.')
						.appendTo(form)
						.delay(2000).fadeOut('slow', function() {
							$(this).remove();
						});
					form.trigger('init');
					return;
				}
				$('<div class="msg"></div>')
					.html('진행할 수 없습니다.' +
						(data == '' ? data : ' ('+data+')'))
					.appendTo(form)
					.delay(2000).fadeOut('slow', function() {
						$(this).remove();
					});
			}, 'text');
			return false;
		}
	});

	form.bind('addrow', addrow);

	form.bind('flush', function() {
		tbody.empty();
	});

	form.bind('loading', function() {
		form.data('loading', $('<span class="dsave-loading"></span>'));
		form.append(form.data('loading'));
	});

	form.bind('loaded', function() {
		form.data('loading').remove();
	});

	form.bind('init', function() {
		form.trigger('loading');
		$.get(url, '', function(data) {
			form.trigger('loaded');
			form.trigger('flush');

			if (data == null ||
				typeof data != 'object') {
				return;
			}

			if (data.length == 0) {
				if (allowEmptyRow == false) {
					add.click();
					return;
				} else if (typeof allowEmptyRow == 'function') {
					allowEmptyRow(add);
					return;
				}
			}

			$(data).each(function() {
				form.trigger('addrow', this);
			});
		}, 'json');
	});

	refresh.click(function() {
		form.trigger('init');
		return false;
	});

	add.click(function() {
		form.trigger('addrow').find('tr:last')
			.find('input[type="text"]:visible:first').focus();
		return false;
	});

	form.trigger('init');
	return this;
};

$.fn.dsaveDownToLast = function() {
	this.click(function() {
		var me = $(this).parents('tr');
		var you = me.parent().find('tr:last').not(me);
		if (you.length == 0)
			return false;
		you.after(me);
		return false;
	}).addClass('dsave-btn-down2').text('맨 아래로');
	return this;
};

$.fn.dsaveDown = function() {
	this.click(function() {
		var me = $(this).parents('tr');
		var you = me.next();
		if (you.length == 0)
			return false;
		you.after(me);
		return false;
	}).addClass('dsave-btn-down').text('아래로');
	return this;
};

$.fn.dsaveUp = function() {
	this.click(function() {
		var me = $(this).parents('tr');
		var you = me.prev();
		if (you.length == 0)
			return false;
		you.before(me);
		return false;
	}).addClass('dsave-btn-up').text('위로');
	return this;
};

$.fn.dsaveUpToFirst = function() {
	this.click(function() {
		var me = $(this).parents('tr');
		var you = me.parent().find('tr:first').not(me);
		if (you.length == 0)
			return false;
		you.before(me);
		return false;
	}).addClass('dsave-btn-up2').text('맨 위로');
	return this;
};

$.fn.dsaveUpDown = function() {
	$('<a></a>').dsaveDownToLast().appendTo(this);
	$('<a></a>').dsaveDown().appendTo(this);
	$('<a></a>').dsaveUp().appendTo(this);
	$('<a></a>').dsaveUpToFirst().appendTo(this);
	return this;
};

$.fn.dsaveTrash = function(form, row, rmLastOne, click) {
	if (!$.isset(rmLastOne))
		rmLastOne = false;

	$('<a></a>')
		.click(function() {
			if (!rmLastOne) {
				var _trs =
					$(this).parents('tr').parent().find('tr');
				if (_trs.length <= 1)
					return false;
			}

			if (row.uid != '') {
				$('<input type="hidden" />')
					.attr('name', 'delete[]')
					.val(row.uid)
					.appendTo(form);
			}

			$(this).parents('tr').remove();

			if ($.isset(click))
				click();
			return false;
		}).addClass('dsave-btn-del').text('제거').appendTo(this);
	return this;
}

$.fn.dsaveImagePreview = function() {
	this.wrap($('<span></span>').css('position', 'relative'))
	.click(function() {
		var me = $(this);
		if (!$(this).data('dsave-image-preview')) {
			$('.dsave-image-preview').clickOutside();
			var img = $('<img src="'+
					me.attr('href')+'" alt="" />')
				.addClass('dsave-image-preview')
				.css('position', 'absolute')
				.css('top', '0')
				.css('left', '0')
				.clickOutside(function() {
					$(this).remove();
					me.data('dsave-image-preview', null);
				});
			me.after(img).data('dsave-image-preview', img);
		} else {
			me.data('dsave-image-preview').click();
		}
		return false;
	});
};

