/*
 * Copyright 2003 Code Futures, Ltd. All rights reserved.
 *
 * This is vendor code. Use is subject to license terms.
 *
 * Author: Andy Grove
 * Date: 30-Jul-2003
 * Time: 06:31:08
 *  
 * Visit http://www.codefutures.com for more information.
 */
package com.codefutures.firestorm.codegen.dto;

import com.codefutures.jingo.source.dom.JClass;
import com.codefutures.jingo.source.dom.JAttribute;
import com.codefutures.jingo.source.dom.JMethod;
import com.codefutures.jingo.source.factory.SourceFactory;
import com.codefutures.jingo.source.helper.SourceHelper;
import com.codefutures.jingo.source.helper.CodeWriter;
import com.codefutures.firestorm.project.dom.TableDao;
import com.codefutures.firestorm.project.dom.TableDaoColumn;
import com.codefutures.firestorm.project.dom.DaoField;
import com.codefutures.firestorm.api.codegen.CommonOptions;
import com.codefutures.firestorm.codegen.dao.DaoConst;
import com.codefutures.firestorm.codegen.dao.DaoCodeGenHelper;
import com.codefutures.firestorm.codegen.dao.DaoNaming;

/**
 * Generates a DTO representing a relational table.
 */
public class GenTableDto
{
	public static JClass generate(
	        TableDao dao,
	        DtoProviderOptions options)
	{
		JClass c = SourceFactory.createClass(
		        options.getPackageName(),
		        SourceHelper.capitalize( dao.getJavaName() )
		        + DaoConst.DTO_SUFFIX
		);

		c.addImport( "java.io.Serializable" );
		c.addImplements( "Serializable");

		DaoCodeGenHelper.addRequiredImports( c, dao );

		TableDaoColumn col[] = dao.getColumnList();
		for (int i = 0; i < col.length; i++)
		{
			String attrName = SourceHelper.decapitalize(col[i].getJavaName());

			JAttribute attr = c.createAttribute(
			        DaoCodeGenHelper.simplify(col[i].getJavaType()),
			        attrName
			);

			attr.setJavaDoc(
			        "This attribute maps to the column "
			        + col[i].getSqlName()
			        + " in the "
			        + dao.getSqlName()
			        + " table."
			);

			DaoCodeGenHelper.createDtoAccessorMethods(
			        c,
			        col[i].getJavaType(),
			        col[i].getJavaName(),
			        col[i].isNullable()
			);

			// create isNull attribute for primitives
			if (col[i].getJavaType().indexOf('.')<0)
			{
				attr = c.createAttribute(
				        "boolean",
				        attrName + "Null"
				);

				attr.setJavaDoc(
				        "This attribute represents whether the primitive attribute "
				        + attrName + " is null."
				);

				attr.setInitialValue( "true" );

				c.createAccessorMethods( attr );
			}

		}

        c.createEqualsMethod();
        c.createHashCodeMethod();

		if (dao.hasPrimaryKey())
		{
			createGetPkMethod(c, dao);
		}

		DaoCodeGenHelper.createToStringMethod( c, dao.getColumnList() );

		return c;
	}

	private static void createGetPkMethod(JClass c, TableDao dao)
	{
		String pkClassName = DaoNaming.getDaoPkName( dao );

		JMethod m = c.createMethod(
		        pkClassName,
		        DaoConst.CREATE_PK_METHOD
		);

		CodeWriter w = m.getCodeWriter();

		StringBuffer buf = new StringBuffer();
		buf.append( "return new " );
		buf.append( pkClassName );
		buf.append( "(" );

		DaoField pk[] = dao.getPrimaryKeyColumnList();
		for (int i = 0; i < pk.length; i++)
		{
			if (i>0)
			{
				buf.append( ", " );
			}
			buf.append( pk[i].getJavaName() );
		}
		buf.append( ")" );

		w.writeStatement( buf.toString() );

		w.close();
	}

}
