package jp.co.cybec.laxide.model.base;

import jp.co.cybec.laxide.util.LetsAjaxUtil;

import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;
import org.jdom.Element;

/**
 * テキストエリアのモデルクラス
 * テキストエリアはプロパティの設定上、行数と文字数を入力するため、内部的に
 * ある倍率を掛けてIDE上に表示している
 * 
 * @author tokumaru
 *
 */
public class LetsAjaxTextAreaModel extends BaseModel {
	private String name = "name";

	public static final String P_NAME = "_name";

	private String value = "value";

	public static final String P_VALUE = "_value";

	private String cols = "20";

	public static final String P_COLS = "_cols";

	private String rows = "5";

	public static final String P_ROWS = "_rows";

	public static final String P_EVENT = "_event";

	public static final String P_DATASOURCE_ID = "_dataSourceId";

	private String dataSourceId = "dataSourceId";

	private int eventId = 1;

	private String events[] = {"", "onClick", "onDblClick ", "onMouseDown",
			"onKeyDown", "onKeyPress", "onKeyUp", "onMouseDown", "onMouseUp",
			"onMouseOver", "onMouseOut", "onMouseMove", "onChange", "onSelect" };

	/**	横幅の倍率 */
	private static int WIDTH_SCALE = 8;
	
	/**	高さの倍率 */
	private static int HEGHT_SCALE = 10;
	
	/* (non-Javadoc)
	 * @see jp.co.cybec.laxide.model.base.BaseModel#getBodyComponentXml()
	 */
	@Override
	public String getBodyComponentXml() {
		String html = "";
		html = html + getNameForXml();
		html = html + getValueForXml();
		html = html + getColsForXml();
		html = html + getRowsForXml();
		html = html + getCssClassNameForXml();
		html = html + getEventForXml() + getDataSourceIdForXml();
		return html;
	}

	/* (non-Javadoc)
	 * @see jp.co.cybec.laxide.model.base.AbstractModel#setAttribute(org.jdom.Element)
	 */
	@Override
	public void setAttribute(Element element) {
		super.setAttribute(element);
		String id = element
				.getAttributeValue(LetsAjaxLayoutConstant.LETSAJAX_ATTRIBUTE_ID);
		super.setId(id);
		super.setType(LetsAjaxLayoutConstant.LETSAJAX_BODY_TEXTAREA);
		setName(element
				.getAttributeValue(LetsAjaxLayoutConstant.LETSAJAX_ATTRIBUTE_NAME));
		setValue(element
				.getAttributeValue(LetsAjaxLayoutConstant.LETSAJAX_ATTRIBUTE_VALUE));
		setCols(element
				.getAttributeValue(LetsAjaxLayoutConstant.LETSAJAX_ATTRIBUTE_COLS));
		setRows(element
				.getAttributeValue(LetsAjaxLayoutConstant.LETSAJAX_ATTRIBUTE_ROWS));
		setConstraint(new Rectangle(Integer.parseInt(super.getX()), Integer
				.parseInt(super.getY()), Integer.parseInt(getCols()), Integer
				.parseInt(getRows())));
		String event = element
				.getAttributeValue(LetsAjaxLayoutConstant.LETSAJAX_ATTRIBUTE_EVENT);
		String dataSourceId = element
				.getAttributeValue(LetsAjaxLayoutConstant.LETSAJAX_ATTRIBUTE_DATASOURCEID);
		String cssClass = element
				.getAttributeValue(LetsAjaxLayoutConstant.LETSAJAX_ATTRIBUTE_CLASSNAME);
		
		setCssClassName(cssClass);
		setDataSourceId(dataSourceId);
		setEventId(1);
		for (int i = 0; i < events.length; i++) {
			if (event != null && event.equals(events[i])) {
				setEventId(i + 1);
				break;
			}
		}
	}

	/**
	 * テキストエリア名を設定します
	 * 
	 * @param valvue テキストエリア名
	 */
	public void setName(String valvue) {
		this.name = LetsAjaxUtil.checkNull(valvue);
		firePropertyChange(P_NAME, null, value);
	}

	/**
	 * テキストエリア名を返します
	 * 
	 * @return テキストエリア名
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * .laxに設定するためのテキストエリア名を返します
	 * 
	 * @return .laxに設定するためのテキストエリア名
	 */
	private String getNameForXml() {
		if (this.name == null || (this.name != null && this.name.equals(""))) {
			return "";
		}
		return " name=\"" + this.name + "\" ";
	}

	/**
	 * テキストエリアのValue値を設定します
	 * 
	 * @param value テキストエリアのValue値
	 */
	public void setValue(String value) {
		this.value = LetsAjaxUtil.checkNull(value);
		firePropertyChange(P_VALUE, null, value);
	}

	/**
	 * テキストエリアのValue値を返します
	 * 
	 * @return テキストエリアのValue値
	 */
	public String getValue() {
		return this.value;
	}

	/**
	 * .laxファイルに設定するためのValue値を返します
	 * 
	 * @return .laxファイルに設定するためのValue値
	 */
	private String getValueForXml() {
		if (this.value == null || (this.value != null && this.value.equals(""))) {
			return "";
		}
		return " value=\"" + this.value + "\"";
	}

	/**
	 * cols属性を設定します
	 * 
	 * @param value cols属性
	 */
	public void setCols(String value) {
		this.cols = value;
		
		if (getConstraint() != null) {
			// ココで制約に高さ幅を設定することによってマウスでの大きさ変更を不可にしている
			getConstraint().width = Integer.parseInt(this.cols) * WIDTH_SCALE;
		}
		
		firePropertyChange(P_COLS, null, String.valueOf(Integer.parseInt(value) * WIDTH_SCALE));
	}

	/**
	 * cols属性値を返します
	 * 
	 * @return cols属性値
	 */
	public String getCols() {
		return String.valueOf(Integer.parseInt(this.cols) * WIDTH_SCALE);
	}

	/**
	 * .laxファイルに設定するcols属性値を返します
	 * 
	 * @return .laxファイルに設定するcols属性値
	 */
	private String getColsForXml() {
		if (this.cols == null || (this.cols != null && this.cols.equals(""))) {
			return "";
		}
		return " cols=\"" + this.cols + "\" ";
	}

	/**
	 * rows属性値を設定します
	 * 
	 * @param value rows属性値
	 */
	public void setRows(String value) {
		this.rows = value;
		
		if (getConstraint() != null) {
			// ココで制約に高さ幅を設定することによってマウスでの大きさ変更を不可にしている
			getConstraint().height = Integer.parseInt(this.rows) * HEGHT_SCALE;
		}
		
		firePropertyChange(P_ROWS, null, String.valueOf(Integer.parseInt(value) * HEGHT_SCALE));
	}

	/**
	 * rows属性値を返します
	 * 
	 * @return rows属性値
	 */
	public String getRows() {
		return String.valueOf(Integer.parseInt(this.rows) * HEGHT_SCALE);
	}

	/**
	 * .laxファイルに設定するためのrows属性値を返します
	 * 
	 * @return .laxファイルに設定するためのrows属性値
	 */
	private String getRowsForXml() {
		if (this.rows == null || (this.rows != null && this.rows.equals(""))) {
			return "";
		}
		return " rows=\"" + this.rows + "\" ";
	}

	/* (non-Javadoc)
	 * @see jp.co.cybec.laxide.model.base.AbstractModel#getPropertyDescriptors()
	 */
	public IPropertyDescriptor[] getPropertyDescriptors() {
		IPropertyDescriptor[] descriptors = new IPropertyDescriptor[] {
				new TextPropertyDescriptor(P_ID, "ID"),
				new TextPropertyDescriptor(P_NAME, "名称"),
				new TextPropertyDescriptor(P_VALUE, "値"),
				new TextPropertyDescriptor(P_COLS, "文字数"),
				new TextPropertyDescriptor(P_ROWS, "行数"),
				new TextPropertyDescriptor(P_CLASS_NAME, "CSSクラス名"),
				new ComboBoxPropertyDescriptor(P_EVENT, "イベント", events),
				new TextPropertyDescriptor(P_DATASOURCE_ID, "DATASOURCEID") };
		return descriptors;
	}

	/* (non-Javadoc)
	 * @see jp.co.cybec.laxide.model.base.AbstractModel#getPropertyValue(java.lang.Object)
	 */
	public Object getPropertyValue(Object id) {
		if (id.equals(P_ID)) {
			return super.id;
		} else if (id.equals(P_NAME)) {
			return this.name;
		} else if (id.equals(P_VALUE)) {
			return this.value;
		} else if (id.equals(P_COLS)) {
			return this.cols;
		} else if (id.equals(P_ROWS)) {
			return this.rows;
		} else if (id.equals(P_EVENT)) {
			return new Integer(this.eventId - 1);
		} else if (id.equals(P_DATASOURCE_ID)) {
			return dataSourceId;
		} else if (id.equals(P_CLASS_NAME)) {
			return getCssClassName();
		}
		
		return null;
	}

	/* (non-Javadoc)
	 * @see jp.co.cybec.laxide.model.base.AbstractModel#isPropertySet(java.lang.Object)
	 */
	public boolean isPropertySet(Object id) {
		if (id.equals(P_NAME)) {
			return true;
		} else if (id.equals(P_VALUE)) {
			return true;
		} else if (id.equals(P_COLS)) {
			return true;
		} else if (id.equals(P_ROWS)) {
			return true;
		} else if (id.equals(P_EVENT)) {
			return true;
		} else if (id.equals(P_DATASOURCE_ID)) {
			return true;
		} else if (id.equals(P_CLASS_NAME)) {
			return true;
		} else {
			return false;
		}
	}

	/* (non-Javadoc)
	 * @see jp.co.cybec.laxide.model.base.AbstractModel#setPropertyValue(java.lang.Object, java.lang.Object)
	 */
	public void setPropertyValue(Object id, Object value) {
		if (id.equals(P_NAME)) {
			setName((String) value);
		} else if (id.equals(P_VALUE)) {
			setValue((String) value);
		} else if (id.equals(P_COLS)) {
			setCols(LetsAjaxUtil.getDigitValue(this.cols, (String)value));
		} else if (id.equals(P_ROWS)) {
			setRows(LetsAjaxUtil.getDigitValue(this.rows, (String)value));
		} else if (id.equals(P_EVENT)) {
			setEventId(((Integer) value).intValue() + 1);
		} else if (id.equals(P_DATASOURCE_ID)) {
			setDataSourceId((String) value);
		} else if (id.equals(P_CLASS_NAME)) {
			setCssClassName((String) value);
		}
	}

	/**
	 * データソースIDを返します
	 * 
	 * @return dataSourceId データソースID
	 */
	public String getDataSourceId() {
		return dataSourceId;
	}

	/**
	 * データソースIDを設定します
	 * 
	 * @param dataSourceId データソースID
	 */
	public void setDataSourceId(String dataSourceId) {
		this.dataSourceId = LetsAjaxUtil.checkNull(dataSourceId);
		firePropertyChange(P_DATASOURCE_ID, null, dataSourceId);
	}

	/**
	 * .laxに設定するためのデータソースIDを返します
	 * 
	 * @return .laxに設定するためのデータソースID
	 */
	private String getDataSourceIdForXml() {
		if (this.dataSourceId == null
				|| (this.dataSourceId != null && this.dataSourceId.equals(""))) {
			return "";
		}
		return " dataSourceId=\"" + this.dataSourceId + "\"";
	}

	/**
	 * イベントIDを返します
	 * 
	 * @return event イベントID
	 */
	public int getEventId() {
		return eventId;
	}

	/**
	 * イベントIDを設定します
	 * 
	 * @param event イベントID
	 */
	public void setEventId(Integer eventId) {
		this.eventId = LetsAjaxUtil.checkNull(eventId);
		
		firePropertyChange(P_EVENT, null, this.eventId);
	}

	/**
	 * .laxファイルに設定するためのイベントIDを返します
	 * 
	 * @return .laxファイルに設定するためのイベントID
	 */
	private String getEventForXml() {
		return " event=\"" + events[eventId - 1] + "\"";
	}
}
