/*
 * Paraselene
 * Copyright (c) 2009  Akira Terasaki
 * このファイルは同梱されているLicense.txtに定めた条件に同意できる場合にのみ
 * 利用可能です。
 */
package paraselene;

import java.net.*;
import java.io.*;
import paraselene.tag.*;
import paraselene.css.*;

/**
 * 色を示す文字列。スレッドセーフです。
 */
public class Color extends PlainText implements AttributeValuable, CSSValuable {
	private static final long serialVersionUID = 2L;
	private int red = -1, green = -1, blue = -1;

	/**
	 * 複製の作成。
	 * @return 複製。
	 */
	public synchronized HTMLPart getReplica() {
		return new Color( red, green, blue );
	}

	/**
	 * コンストラクタ。
	 * @param s 文字列。
	 */
	public Color( String s ) {
		setText( s );
	}

	/**
	 * 色の設定。
	 * @param s 文字列。
	 */
	public void setText( String s ) {
		if ( s == null ) {
			super.setText( s );
			return;
		}
		s = s.trim();
		if ( s.isEmpty() ) {
			super.setText( s );
			return;
		}
		if ( s.charAt( 0 ) != '#' ) {
			setColor( WebColor.valueOf( s.toUpperCase() ) );
			return;
		}
		char[]	org = s.toCharArray();
		char[]	ch = new char[7];
		int	org_len = org.length - 1;
		int	ch_len = ch.length - 1;
		for ( ; org_len >= 1 && ch_len >= 1; org_len--, ch_len-- ) ch[ch_len] = org[org_len];
		for ( ; ch_len >= 1; ch_len-- )	ch[ch_len] = '0';
		setColor( Integer.parseInt( new String( ch, 1, 2 ), 16 ),
			Integer.parseInt( new String( ch, 3, 2 ), 16 ),
			Integer.parseInt( new String( ch, 5, 2 ), 16 ) );
	}

	/**
	 * コンストラクタ。
	 * @param wc 規定色。
	 */
	public Color( WebColor wc ) {
		setColor( wc );
	}

	/**
	 * 色の設定。
	 * @param wc 規定色。
	 */
	public void setColor( WebColor wc ) {
		setColor( wc.red, wc.green, wc.blue );
	}

	/**
	 * コンストラクタ。全てのパラメータは下位１バイトのみ取り出して使用する。
	 * @param r 赤(0x00 ～ 0xff)。負数の場合、transparent となります。
	 * @param g 緑(0x00 ～ 0xff)。負数の場合、transparent となります。
	 * @param b 青(0x00 ～ 0xff)。負数の場合、transparent となります。
	 */
	public Color( int r, int g, int b ) {
		setColor( r, g, b );
	}

	/**
	 * 色の設定。全てのパラメータは下位１バイトのみ取り出して使用する。
	 * @param r 赤(0x00 ～ 0xff)。負数の場合、transparent となります。
	 * @param g 緑(0x00 ～ 0xff)。負数の場合、transparent となります。
	 * @param b 青(0x00 ～ 0xff)。負数の場合、transparent となります。
	 */
	public synchronized void setColor( int r, int g, int b ) {
		if ( r < 0 || g < 0 || b < 0 ) {
			red = green = blue = -1;
			super.setText( "transparent" );
		}
		else {
			red = r & 0xff;
			green = g & 0xff;
			blue = b & 0xff;
			super.setText( String.format( "#%06X", (red << (8*2)) | (green << 8) | blue ) );
		}
	}

	/**
	 * 赤の取得。
	 * @return 赤。transparent の場合、-1 を返します。
	 */
	public int getRed() {
		return red;
	}

	/**
	 * 緑の取得。
	 * @return 緑。transparent の場合、-1 を返します。
	 */
	public int getGreen() {
		return green;
	}

	/**
	 * 青の取得。
	 * @return 青。transparent の場合、-1 を返します。
	 */
	public int getBlue() {
		return blue;
	}
}


