package hiro.yoshioka.sql.resource;

import hiro.yoshioka.util.StringUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

public class DBTable extends DBResource implements IDBTable {
	private static final long serialVersionUID = 999962501456L;
	private static IDBColumn[] EMPTY_COLUMN = new IDBColumn[0];

	/** TABLE_TYPE */
	protected TableType tableType = TableType.UNKNOWN;

	/** PROCEDURE_TYPE */
	protected ProcedureType _procedureType;

	protected final boolean fDictionary;

	protected boolean fTmpSelection;

	protected boolean fSelectAll;

	protected String fText;
	private String catalog;

	public static transient Object image;

	/**
	 * Constructs a new DBTable containing the DBSchema
	 * 
	 * @param schema
	 */
	public DBTable(IDBSchema schema) {
		super(schema);
		fDictionary = false;
	}

	public DBTable(DBDictionaryRoot droot) {
		super(droot);
		fDictionary = true;
	}

	public IDBColumn[] getColumns() {
		List list = listResources();
		return (IDBColumn[]) list.toArray(new IDBColumn[list.size()]);
	}

	@Override
	public IDBColumn[] getColumnsForSelectionDialog() {
		return getColumns();
	}

	public void setTableType(String value) {
		tableType = TableType.parse(value);
	}

	public void setTableType(TableType tableType) {
		this.tableType = tableType;
	}

	@Override
	public TableType getTableType() {
		return this.tableType;
	}

	public boolean isTable() {
		if (_procedureType == null) {
			return tableType.isTable();
		}
		return false;
	}

	public boolean isView() {
		if (_procedureType == null) {
			return tableType.isView();
		}
		return false;
	}

	public boolean isSynonym() {
		if (_procedureType == null) {
			return tableType.isSynonym();
		}
		return false;
	}

	public boolean isFunction() {
		if (_procedureType == null) {
			return false;
		}
		return _procedureType.isFunctionOrUnknown();
	}

	public boolean isProcudeure() {
		if (_procedureType == null) {
			return false;
		}
		return _procedureType.isProcedureOrUnknown();
	}

	@Override
	public ProcedureType getProcedureType() {
		return _procedureType;
	}

	public boolean isDictionary() {
		return fDictionary;
	}

	public boolean isSystem() {
		if (tableType == null) {
			return false;
		}
		return tableType.isSystem();
	}

	public String toString() {
		StringBuffer buf = new StringBuffer();
		if (fTmpSelection) {
			buf.append("【TMP:" + _children.size() + "】");
		}
		buf.append(getName());
		if (getComment().length() > 0) {
			buf.append(" 【" + getComment() + "】");
		}

		return buf.toString();
	}

	public void setComment(String remarks) {
		this.comment = remarks;
	}

	@Override
	public void slimUp() {

	}

	public void setProcedureType(ProcedureType procedureType) {
		_procedureType = procedureType;
	}

	public boolean contain(String pattern) {
		if (containKeyInNameOrComment(pattern.toUpperCase())) {
			return true;
		}
		if (listResources(pattern).size() > 0) {
			return true;
		}
		return false;
	}

	// String getIndexNames(IDBColumn column) {
	// if (!hasIndex()) {
	// return "";
	// }
	// StringBuffer buf = new StringBuffer();
	// for (Iterator ite = fIndexList.iterator(); ite.hasNext();) {
	// DBIndex element = (DBIndex) ite.next();
	// if (element.contain(column.getName(), IDB_COLUMN)) {
	// buf.append(element.getName()).append(", ");
	// }
	// }
	// if (buf.length() > 2) {
	// buf.setLength(buf.length() - 2);
	// }
	// return buf.toString();
	// }
	//
	// public boolean hasIndex(IDBColumn column) {
	// for (Iterator ite = fIndexList.iterator(); ite.hasNext();) {
	// DBIndex element = (DBIndex) ite.next();
	// if (element.contain(column.getName(), 0)) {
	// return true;
	// }
	// }
	// return false;
	// }

	/*
	 * (non-Javadoc)
	 * 
	 * @see hiro.yoshioka.sql.resource.IDBTable#setSelectAll()
	 */
	public void setSelectAll() {
		fSelectAll = true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see hiro.yoshioka.sql.resource.IDBTable#getSelectAll()
	 */
	public boolean getSelectAll() {
		// TODO Auto-generated method stub
		return fSelectAll;
	}

	public boolean hasText() {
		if (fText == null || fText.length() == 0) {
			return false;
		}
		return true;
	}

	public boolean hasPk() {
		List<IDBResource> alllist = listResources();
		for (int i = 0; i < alllist.size(); i++) {
			IDBColumn col = (IDBColumn) alllist.get(i);
			if (col.isPkey()) {
				return true;
			}
		}
		return false;
	}

	public void putResource(String key, IDBResource child) {
		super.putResource(key, child);
	}

	public int[] getPkPositions() {
		List<IDBResource> alllist = listResources();
		List<Integer> retList = new ArrayList<Integer>();
		for (int i = 0; i < alllist.size(); i++) {
			IDBColumn col = (IDBColumn) alllist.get(i);
			if (col.isPkey()) {
				retList.add(new Integer(i));
			}
		}
		int[] retInt = new int[retList.size()];
		for (int i = 0; i < retInt.length; i++) {
			retInt[i] = retList.get(i);
		}
		return retInt;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see hiro.yoshioka.sql.resource.IDBTable#isShadow()
	 */
	public boolean isShadow() {
		return fTmpSelection;
	}

	/**
	 * コンテンツアシスト用IDBColumn List返却。
	 * 
	 * @return アシスト用IDBColumn List
	 */
	public List<IDBResource> getProposal(IDBSchema another,
			String schemaString, String tableNameString, String columnString,
			Set<String> aliasSet) {
		if (schemaString.length() > 0) {// スキーマ、テーブル 又はエイリアスがあり
			if (tableNameString.length() > 0) {
				if (columnString.length() > 0) { // 全て指定
					return startsWithResourceLists(columnString);
				}
				return listResources();
			}
			for (String alias : aliasSet) {
				if (alias.equalsIgnoreCase(schemaString)) {// エイリアスが一致
					if (columnString.length() > 0) {
						return startsWithResourceLists(columnString);
					}
					return listResources();
				}
			}
			if (getName().equalsIgnoreCase(schemaString)) {// テーブル名が一致
				if (columnString.length() > 0) { // 全て指定
					return startsWithResourceLists(columnString);
				}
				return listResources();
			}
			if (another != null && !another.equals(getParent())) {
				List<IDBResource> list = new ArrayList<IDBResource>();
				if (getParent() != null
						&& getParent().getUName().startsWith(schemaString)) {
					list.add(this);
				}
				return list;
			}
			return Collections.EMPTY_LIST;
		}
		if (columnString.length() == 0) {
			return listResources();
		}
		return startsWithResourceLists(columnString);
	}

	public String getImageString() {
		if (isProcudeure()) {
			return "\u24c5";
		} else if (isFunction()) {
			return "\u24bb";
		} else if (isView()) {
			return "\u24cb";
		} else if (isSynonym()) {
			return "\u24c8";
		} else {
			return "\u24c9";
		}
	}

	/**
	 * @return Returns the fText.
	 */
	public String getText() {
		return fText;
	}

	/**
	 * @param text
	 *            The fText to set.
	 */
	public void setText(String text) {
		fText = StringUtil
				.nvl(text)
				.replaceAll(
						"(TABLE|VIEW|SYNONYM|PROCEDURE|FUNCTION)\\s+\"(\\w+)\"[.]\"(\\w+)\"",
						"$1 $2.$3");
	}

	public IDBColumn[] getInputColumns() {
		if (isProcudeure() || isFunction()) {
			ArrayList<IDBColumn> list = new ArrayList<IDBColumn>();
			List<IDBResource> alllist = listResources();
			for (int i = 0; i < alllist.size(); i++) {
				IDBColumn col = (IDBColumn) alllist.get(i);
				if (col.isColumnIn() || col.isColumnInOut()) {
					list.add(col);
				}
			}
			return list.toArray(new IDBColumn[list.size()]);
		}
		return EMPTY_COLUMN;
	}

	public IDBColumn getReturnColumn() {
		if (isProcudeure() || isFunction()) {
			List<IDBResource> alllist = listResources();
			for (int i = 0; i < alllist.size(); i++) {
				IDBColumn col = (IDBColumn) alllist.get(i);
				if (col.isColumnReturn()) {
					return col;
				}
			}
		}
		return null;
	}

	public IDBColumn[] getOutputColumns() {
		if (isProcudeure() || isFunction()) {
			ArrayList<IDBColumn> list = new ArrayList<IDBColumn>();
			List<IDBResource> alllist = listResources();
			for (int i = 0; i < alllist.size(); i++) {
				IDBColumn col = (IDBColumn) alllist.get(i);
				if (col.isColumnOut() || col.isColumnInOut()
						|| col.isColumnReturn()) {
					list.add(col);
				}
			}
			return list.toArray(new IDBColumn[list.size()]);
		}
		return EMPTY_COLUMN;
	}

	public DBCrossRefference[] getCrossReferences() {
		DBIndexRoot root = ((DBRoot) getParent().getParent()).getDBIndexRoot();
		return root.getCrossReferences(this);
	}

	@Override
	public Object getImage() {
		return image;
	}

	public IDBTable clone() {
		DBTable ret = new DBTable((IDBSchema) getParent());
		ret.setTableType(tableType);
		ret.setProcedureType(_procedureType);
		ret.fTmpSelection = fTmpSelection;
		ret.fSelectAll = fSelectAll;
		ret.fText = fText;
		ret.name = name;
		ret._children = _children;

		return ret;
	}

	@Override
	public void removeAllColumns() {
		_children.clear();
	}

	public String getCatalog() {
		return catalog == null ? StringUtil.EMPTY_STRING : catalog;
	}

	public String getUCatalog() {
		return getCatalog().toUpperCase();
	}

	public void setCatalog(String tableCat) {
		this.catalog = tableCat;
	}

	// @Override
	// public void generateColumnsOf(ResultSetMetaData rs_meta)
	// throws SQLException {
	// if (rs_meta == null || rs_meta.getColumnCount() == 0) {
	// return;
	// }
	// for (int i = 1; i <= rs_meta.getColumnCount(); i++) {
	// DBColumn column = new DBColumn(this);
	// column.setName(rs_meta.getColumnName(i));
	// column.setComment(rs_meta.getColumnLabel(i));
	// column.setDataType(rs_meta.getColumnType(i));
	// column.setDataTypeString(rs_meta.getColumnTypeName(i));
	// this.putResource(column.getName(), column);
	// }
	// }

}