
function rgb(rad, green, blue) {
	rad = parseInt(rad).toString(16);
	rad = (rad.length != 1) ? rad : '0' + rad;
	green = parseInt(green).toString(16);
	green = (green.length != 1) ? green : '0' + green;
	blue = parseInt(blue).toString(16);
	blue = (blue.length != 1) ? blue : '0' + blue;
	return '#' + rad + green + blue;
}

/**
 * 指定Elementの位置を返します。
 * 罫線には対応しておりません。
 * @param {Object} element
 * @return [top, left]
 */
function getElementPosition(element) {

	// 渡ってきたのがCKEditorの場合
	if (element instanceof CKEDITOR.editor) {
		return getPageEventCoordes();
	}

	var top = 0, left = 0;
	do {
		top += element.offsetTop || 0;
		left += element.offsetLeft || 0;
		element = element.offsetParent;
	} while (element);
	return [top, left];
}

/**
 * マウスイベントよりポインタの位置情報を取得します.
 * @return [top, left]
 */
function getPageEventCoordes() {
	var evt = window.event;
	var top = 0, left = 0;
	if (evt) {
		if (evt.pageX) {
			left = evt.pageX;
			top = evt.pageY;
		} else if (evt.clientX) {
			left = evt.clientX + document.body.scrollLeft - document.body.clientLeft;
			top = evt.clientY + document.body.scrollTop - document.body.clientTop;
			// html要素のスペースも含める
			if (document.body.parentElement && document.body.parentElement.clientLeft) {
				var bodParent = document.body.parentElement;
				left += bodParent.scrollLeft - bodParent.clientLeft;
				top += bodParent.scrollTop - bodParent.clientTop;
			}
		}
	} else {
		//alert('Does not have Event Object.'); // Debug
	}
	//alert('x:' + left + ' y:' + top); // Debug
	return [top, left];
}

/**
 * 色パレットを提供します
 * @param {Object} buttonName ボタン名
 * @param {Object} viewArea パレット表示領域
 * @param {Object} editor SmartEditor
 */
var ColorPallet = function(buttonName, viewArea, editor, command) {
	if (!editor && !command) {
		this.button = $(buttonName);
		this.view = $(viewArea);
		this.view.innerHTML = this.create();
		Event.observe(document, 'keydown', this.hotkey.bind(this), false);
		Event.observe(this.button, 'focus', this.show.bind(this));
		Event.observe(this.button, 'blur', this.hide.bind(this));
		this.setValue();
	} else {
		this.view = $(viewArea);
		this.view.innerHTML = this.create();
		Event.observe(document, 'keydown', this.hotkey.bind(this), false);
		this.button = $(buttonName);
		Event.observe(this.button, 'click', this.toggle.bind(this));
		this.editor = editor;
		this.setEvent(command);
	}
}
ColorPallet.prototype.create = function() {

	var output = [],
	colors = CKEDITOR.config.colorButton_colors.split( ',' );

	// Render the "Automatic" button.
	output.push(
		'<a class="cke_colorauto" _cke_focus=1 hidefocus=true' +
			' title="自動"' +
			' onclick=""' +
			' href="javascript:void(\'自動\')">' +
			'<table cellspacing=0 cellpadding=0 width="100%">' +
				'<tr>' +
					'<td style="border: 0px;">' +
						'<span class="cke_colorbox" style="background-color:#000"></span>' +
					'</td>' +
					'<td colspan=7 align=center style="border: 0px;">' +
						'自動' +
					'</td>' +
				'</tr>' +
			'</table>' +
		'</a>' +
		'<table cellspacing=0 cellpadding=0 width="100%">' );

	// Render the color boxes.
	for ( var i = 0 ; i < colors.length ; i++ )
	{
		if ( ( i % 8 ) === 0 )
			output.push( '</tr><tr>' );

		var colorCode = colors[ i ];
		// 色名称はCKEditorのインスタンスが保持している.ここでは取れない
//		var colorLabel = CKEDITOR.editor.lang.colors[ colorCode ] || colorCode;
		var colorLabel = colorCode;
		output.push(
			'<td style="border: 0px;">' +
				'<a class="cke_colorbox" _cke_focus=1 hidefocus=true' +
					' title=""' +
					' onclick=""' +
					' href="javascript:void(\'', colorLabel, '\')">' +
					'<span class="cke_colorbox" style="background-color:#', colorCode, '"></span>' +
				'</a>' +
			'</td>' );
	}

	// Render the "More Colors" button.
//	if ( config.colorButton_enableMore )
//	{
//		output.push(
//			'</tr>' +
//			'<tr>' +
//				'<td colspan=8 align=center>' +
//					'<a class="cke_colormore" _cke_focus=1 hidefocus=true' +
//						' title="', lang.more, '"' +
//						' onclick="CKEDITOR.tools.callFunction(', clickFn, ',\'?\',\'', type, '\');return false;"' +
//						' href="javascript:void(\'', lang.more, '\')">',
//						lang.more,
//					'</a>' +
//				'</td>' );	// It is later in the code.
//	}

	output.push( '</tr></table>' );

	return output.join( '' );

	// 旧カラーパレット
//	var html = '<table  bgcolor="#000000"><tbody>';
//	var color = '';
//	var hex = new Array('f','c','9','6','3','0');
//	for (var i=0; i < 6; i++) {
//		for (var j=0; j < 6; j++) {
//			for (var k=0; k < 6; k++) {
//				var hexColor = hex[i] + hex[i] + hex[j] + hex[j] + hex[k] + hex[k];
//				color += '<td style="background-color: #' + hexColor + '"></td>';
//			}
//		}
//		html += '<tr>' + color + '</tr>';
//		color = '';
//	}
//	for (var i = 0; i < 6; i++) {
//		var hexColor = hex[i] + hex[i] + hex[i] + hex[i] + hex[i] + hex[i];
//		color += '<td style="background-color: #' + hexColor + '"></td>';
//	}
//	html += '<tr>' + color + '</tr>';
//	html += '</tbody></table>';
//	return html;
}
ColorPallet.prototype.show = function() {
	var pallet = this.view.style;
	var offset = getElementPosition(this.button);
	pallet.top = offset[0] + 30 + 'px';
	pallet.left = offset[1] + 'px';
	pallet.width = '150px';
	pallet.height = '135px';
	pallet.backgroundColor = '#ffffff';
	pallet.display = 'block';
}
ColorPallet.prototype.hide = function() {
	var pallet = this.view.style;
	pallet.display = 'none';
}
ColorPallet.prototype.toggle = function(event) {
	if (this.view.style.display != 'block') this.show();
	else this.hide();
}
ColorPallet.prototype.hotkey = function(event) {
	if (event.keyCode == '27') this.hide(); // 'Esc'
}
ColorPallet.prototype.setEvent = function(command) {
	Event.observe(document.body, 'mousedown', function(e) {
		e = e || window.event;
		var element = e.target || e.srcElement;
		var tag = element.tagName.toLowerCase();
		if (tag == 'span' && this.findAncestorById(element, this.view.id)) {
			if (!command) command = 'forecolor';
			var colors = element.style.backgroundColor;
			var opt = colors;
			if (colors.indexOf('#') == -1) {
				colors = eval('[' + colors.substring(colors.indexOf('(') + 1, colors.indexOf(')')) + ']');
				opt = rgb(colors[0], colors[1], colors[2]);
			}
			this.editor.execCmd(command, opt);
			//this.editor.makeHTML();
			this.hide();
		} else if (tag == 'body') this.hide();
	}.bind(this));
}
ColorPallet.prototype.setValue = function() {
	Event.observe(document.body, 'mousedown', function(e) {
		e = e || window.event;
		var element = e.target || e.srcElement;
		var tag = element.tagName.toLowerCase();
		if (tag == 'span' && this.findAncestorById(element, this.view.id)) {
			var colors = element.style.backgroundColor;
			var opt = colors;
			if (colors.indexOf('#') == -1) {
				colors = eval('[' + colors.substring(colors.indexOf('(') + 1, colors.indexOf(')')) + ']');
				opt = rgb(colors[0], colors[1], colors[2]);
			}
			this.button.value = opt.substring(1);
			if (this.button.onchange) {
				this.button.onchange();
			} else if (this.changeEvent) {
				this.changeEvent();
			}
			this.hide();
		} else if (tag == 'body') this.hide();
	}.bind(this));
}
ColorPallet.prototype.findAncestorById = function(element, id) {
	var parent = element.parentNode;
	if (parent) {
		if (parent.id == id) {
			return true;
		} else {
			return this.findAncestorById(parent, id);
		}
	} else {
		return false;
	}
}
ColorPallet.prototype.setChangeEvent = function(event) {
	this.changeEvent = event;
}
