package ${omAgentImplPackage};

import java.io.Serializable;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import ${omPojoPackage}.*;
import ${omDaoPackage}.*;
import ${omAgentPackage}.*;

import org.asyrinx.joey.om.agent.AgentAssociation;
import org.asyrinx.joey.om.agent.impl.AgentAssociationImpl;
import org.asyrinx.joey.om.Entity;
import org.asyrinx.joey.om.SearchCondition;

/**
 */
public class ${table.getJavaName()}AgentImpl implements ${table.getJavaName()}Agent {
	/**
	 *  
	 */
	public ${table.getJavaName()}AgentImpl(${table.getJavaName()}Dao dao) {
		super();
		this.dao = dao;
	}
	private final ${table.getJavaName()}Dao dao;

	protected AgentAssociation newDefaultAssociation() {
		final AgentAssociationImpl associationImpl = new AgentAssociationImpl();
		associationImpl.addUsingAgent(${table.getJavaName()}Agent.class);
		return associationImpl;
	}

	/* (non-Javadoc)
	 * @see org.asyrinx.joey.om.EntityService#newEntity()
	 */
	public Entity newEntity() {
		return dao.newEntity();
	}
	
	/* (non-Javadoc)
	 * @see org.asyrinx.joey.om.EntityService#restoreBeforeSave(org.asyrinx.joey.om.Entity)
	 */
	public void restoreBeforeSave(Entity entity) {
		dao.restoreBeforeSave(entity);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see jp.co.tecowl.tz2md.om.agent.ArrivalAgent#loadEntity(java.io.Serializable)
	 */
	public Entity loadEntity(Serializable key) {
		return load(key, newDefaultAssociation());
	}

	/* (non-Javadoc)
	 * @see org.asyrinx.joey.om.EntityService#deleteEntity(java.io.Serializable)
	 */
	public void deleteEntity(Serializable key) {
	}
	
	/* (non-Javadoc)
	 * @see org.asyrinx.joey.om.EntityService#saveEntity(java.lang.Object)
	 */
	public void saveEntity(Object entity) {
		if (entity instanceof ${table.getJavaName()} )
			dao.save((${table.getJavaName()}) entity);
		else
			throw new RuntimeException("entity is not a ${table.getJavaName()}.");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see jp.co.tecowl.tz2md.om.agent.ArrivalAgent#select(org.asyrinx.joey.om.SearchCondition)
	 */
	public List select(SearchCondition condition) {
		return list(condition, newDefaultAssociation());
	}

	public ${table.getJavaName()} load(Serializable key, AgentAssociation association) {
		if (key == null)
			return null;
		if ("0".equals(String.valueOf(key)))
			return null;
		if (association.isLoaded(key, ${table.getJavaName()}.class))
			return (${table.getJavaName()}) association.getLoaded(key, ${table.getJavaName()}.class);
		final ${table.getJavaName()} obj = dao.load(key);
		addToAssociation(obj, association);
		restore(obj, association);
		return obj;
	}

	public List list(SearchCondition condition, AgentAssociation association) {
		final List results = dao.select(condition);
		for (Iterator iter = results.iterator(); iter.hasNext();) {
			final ${table.getJavaName()} obj = (${table.getJavaName()}) iter.next();
			if (!association.isLoaded(obj.getPrimaryKey(), ${table.getJavaName()}.class)) {
				addToAssociation(obj, association);
				restore(obj, association);
			}
		}
		return results;
	}

#foreach( $fk in $table.getForeignKeys() )
	#set( $fkTable = $fk.getForeignTableObject() )
	#set( $fkPropNameLow = $fk.getPropertyNameInLocal() )
	#set( $fkPropName = ${stringUtils.capitalize( $fkPropNameLow )} )
	#set( $agentObjName = "${stringUtils.uncapitalize( $fkTable.getJavaName() )}Agent" )
	#set( $indexFk = $fk.getIndex() )
	public List listBy${fk.getJavaName()}(${fkTable.getJavaName()} ref, AgentAssociation association) {
		if (ref == null)
			return Collections.EMPTY_LIST;
		if ("0".equals(String.valueOf(ref.getPrimaryKey())))
			return Collections.EMPTY_LIST;
		${table.getJavaName()}Dao.${indexFk.getJavaName()} condition = new ${table.getJavaName()}Dao.${indexFk.getJavaName()}();
	#foreach($localColName in $indexFk.getColumns() )
		#set( $localCol = $table.getColumn( $localColName ) )
	    #set( $fieldName = $stringUtils.capitalize( $localCol.getJavaName() ) )
		#set( $foreignColName = ${fk.getLocalForeignMapping().get( $localColName )} )
		#set( $foreignCol = ${fk.getForeignTableObject().getColumn( $foreignColName )} )
		#if ( $localCol.isSelectFieldType() )
		condition.get${fieldName}Set().getEntryByValue(ref.get${foreignCol.getJavaName()}().getValue()).setSelected(true);
		#elseif ( $localCol.isMemoFieldType() || $localCol.isTextFieldType() ) 
		condition.set${fieldName}( String.valueOf(ref.get${foreignCol.getJavaName()}()) );
		#elseif ( $localCol.isDateFieldType() ) 
		condition.set${fieldName}Max( condition.getDateFormat().format(ref.get${foreignCol.getJavaName()}()) );
		condition.set${fieldName}Min( condition.getDateFormat().format(ref.get${foreignCol.getJavaName()}()) );
		#else
		condition.set${fieldName}Max( String.valueOf(ref.get${foreignCol.getJavaName()}()) );
		condition.set${fieldName}Min( String.valueOf(ref.get${foreignCol.getJavaName()}()) );
		#end
	#end
		return list(condition, association);
	}
#end

	public void addToAssociation(${table.getJavaName()} obj, AgentAssociation association) {
		if (obj == null)
			return ;
		if (association.isLoaded(obj.getPrimaryKey(), ${table.getJavaName()}.class))
			return;
		association.addLoaded(obj.getPrimaryKey(), obj);
#foreach( $fk in $table.getForeignKeys() )
	#set( $fkTable = $fk.getForeignTableObject() )
	#set( $fkPropNameLow = $fk.getPropertyNameInLocal() )
	#set( $fkPropName = ${stringUtils.capitalize( $fkPropNameLow )} )
	#set( $agentObjName = "${stringUtils.uncapitalize( $fkTable.getJavaName() )}Agent" )
		${agentObjName}.addToAssociation(obj.get${fkPropName}(), association);
#end
#foreach ( $ref in $table.getReferrers() )
	#set( $refTable = $ref.getTable() )
	#set( $refPropNameLowS = $ref.getPropertyNameInReferred( true ) )
	#set( $refPropNameS = ${stringUtils.capitalize( $refPropNameLowS )} )
	#set( $agentObjName = "${stringUtils.uncapitalize( $refTable.getJavaName() )}Agent" )
		for (Iterator iter = obj.get${refPropNameS}().iterator(); iter.hasNext();) {
			${refTable.getJavaName()} element = (${refTable.getJavaName()}) iter.next();
			${agentObjName}.addToAssociation(element, association);
		}
#end
	}

	public void restore(${table.getJavaName()} obj, AgentAssociation association) {
		if (obj == null)
			return ;
#foreach( $fk in $table.getForeignKeys() )
	#set( $fkTable = $fk.getForeignTableObject() )
	#set( $fkPropNameLow = $fk.getPropertyNameInLocal() )
	#set( $fkPropName = ${stringUtils.capitalize( $fkPropNameLow )} )
	#set( $agentObjName = "${stringUtils.uncapitalize( $fkTable.getJavaName() )}Agent" )
		${agentObjName}.addToAssociation(obj.get${fkPropName}(), association);
		restore$fkPropName(obj, association);
#end
#foreach ( $ref in $table.getReferrers() )
	#set( $refTable = $ref.getTable() )
	#set( $refPropNameLowS = $ref.getPropertyNameInReferred( true ) )
	#set( $refPropNameS = ${stringUtils.capitalize( $refPropNameLowS )} )
		restore${refPropNameS}(obj, association);
#end
	}

#foreach( $fk in $table.getForeignKeys() )
	#set( $fkTable = $fk.getForeignTableObject() )
	#set( $fkPropNameLow = $fk.getPropertyNameInLocal() )
	#set( $fkPropName = ${stringUtils.capitalize( $fkPropNameLow )} )
	#set( $agentObjName = "${stringUtils.uncapitalize( $fkTable.getJavaName() )}Agent" )
	protected void restore$fkPropName(${table.getJavaName()} obj, AgentAssociation association) {
		if (obj == null)
			return ;
		if (association.isLoaded(obj.get${fkPropName}()))
			return;
		final Serializable key = obj.get${fkPropName}Key();
		if (association.canUseAgent(${stringUtils.uncapitalize( $fkTable.getJavaName() )}Agent)) {
			final ${fkTable.getJavaName()} referred = ${stringUtils.uncapitalize( $fkTable.getJavaName() )}Agent.load(key, association);
			obj.set${fkPropName}(referred);
		}
	}
	
#end
#foreach ( $ref in $table.getReferrers() )
	#set( $refTable = $ref.getTable() )
	#set( $refPropNameLow = $ref.getPropertyNameInReferred( false ) )
	#set( $refPropNameLowS = $ref.getPropertyNameInReferred( true ) )
	#set( $refPropName = ${stringUtils.capitalize( $refPropNameLow )} )
	#set( $refPropNameS = ${stringUtils.capitalize( $refPropNameLowS )} )
	#set( $agentObjName = "${stringUtils.uncapitalize( $refTable.getJavaName() )}Agent" )
	private void restore${refPropNameS}(${table.getJavaName()} obj, AgentAssociation association) {
		if (obj == null)
			return ;
		if (association.canUseAgent($agentObjName )) {
			List list = ${agentObjName}.listBy${ref.getJavaName()}(obj, association);
			for (Iterator iter = list.iterator(); iter.hasNext();) {
				final ${refTable.getJavaName()} ref = ($refTable.getJavaName()) iter.next();
				obj.add${refPropName}(ref);
			}
		}
	}
#end

#set( $usedAgentTable = $helper.newInstance("java.util.HashSet")  )
#foreach( $fk in $table.getForeignKeys() )
	#set( $fkTable = $fk.getForeignTableObject() )
	#if( ! $usedAgentTable.contains( $fkTable ) )
	// $fk.getName() $fkTable.getJavaName() $usedAgentTable.add( $fkTable )
	#set( $agentObjName = "${stringUtils.uncapitalize( $fkTable.getJavaName() )}Agent" )
	private ${fkTable.getJavaName()}Agent $agentObjName  = null;

	public void set${fkTable.getJavaName()}Agent(${fkTable.getJavaName()}Agent $agentObjName ) {
		this.$agentObjName  = $agentObjName ;
	}
	#else		
	// $fk.getName() $fkTable.getJavaName() 
	#end
#end
#foreach ( $ref in $table.getReferrers() )
	#set( $refTable = $ref.getTable() )
	#if( ! $usedAgentTable.contains( $refTable ) )
	// $ref.getName() $refTable.getJavaName() $usedAgentTable.add( $refTable )
	#set( $agentObjName = "${stringUtils.uncapitalize( $refTable.getJavaName() )}Agent" )
	private ${refTable.getJavaName()}Agent $agentObjName  = null;

	public void set${refTable.getJavaName()}Agent(${refTable.getJavaName()}Agent $agentObjName ) {
		this.$agentObjName  = $agentObjName ;
	}
	#else		
	// $refTable.getName() $refTable.getJavaName() 
	#end
#end
}
