/*
 * Created on 25-03-2003
 *
 * To change this generated comment go to 
 * Window>Preferences>Java>Code Generation>Code Template
 */
package net.sf.hibernate.tool.hbm2java;

import java.io.PrintWriter;
import java.util.Map;
import java.util.TreeSet;

import net.sf.hibernate.util.StringHelper;

import org.apache.commons.lang.StringUtils;

/**
 * @author max
 */
public abstract class AbstractRenderer implements Renderer {

	/**
	 * Returns the true name for the given fields class name. By true name is
	 * that it will return the Proxy for the class name if the class was
	 * defined with a proxy attribute.
	 * 
	 * If the Field has an <meta attribute="property-type"></meta> then that
	 * will overrule any other information.
	 * 	  
	 * @param field class name that we use to serach in class2classmap
	 * @param class2classmap a map from classname to classmappings
	 * @return String return either name or the proxy name of the classmap
	 */
	static protected String getTrueTypeName(Field field, Map class2classmap) {
		String name =
			(field.getClassType() != null)
				? field.getClassType().getFullyQualifiedName()
				: field.getType();

		if(field.getMeta("property-type")!=null) {
			name = field.getMetaAsString("property-type");
		}				
		ClassMapping cmap = (ClassMapping) class2classmap.get(name);

		if (cmap != null) {
			if (cmap.getProxy() != null) {
				return cmap.getProxy();
			}
		}
		return name;
	}

	static protected String getTrueTypeName(ClassName cn, Map class2classmap) {
		String name = cn.getFullyQualifiedName();
		ClassMapping cmap = (ClassMapping) class2classmap.get(name);

		if (cmap != null) {
			if (cmap.getProxy() != null) {
				return cmap.getProxy();
			}
		}
		return name;
	}

	/**
	 * Returns the last part of type if it is in the set of imports.
	 * e.g. java.util.Date would become Date, if imports contains 
	 * java.util.Date.
	 * 
	 * @param type
	 * @param imports
	 * @return String
	 */
	protected String shortenType(String type, TreeSet imports) {
        String result = type;
	    if( imports.contains(type) ) {
	      result = type.substring( type.lastIndexOf(StringHelper.DOT)+1 );
	    } 
	    else if( type.endsWith("[]") ) {
	        result = shortenType( type.substring(0, type.length()-2), imports ) + "[]";    
	    } else if (type.startsWith("java.lang.")) {
            result = type.substring("java.lang.".length());   
        }	  
        
        return result;
	}

	/**
	 * Convert string into something that can be rendered nicely into a javadoc
	 * comment.
	 * Prefix each line with a star ('*').
	 * @param string
	 */
	protected String toJavaDoc(String string, int indent) {
	    StringBuffer result = new StringBuffer();
	    
	    if(string!=null) {
	        String[] lines = StringUtils.split(string, "\n\r\f");
	        for (int i = 0; i < lines.length; i++) {
	            String docline = " * " + lines[i] + "\n";
	            result.append(StringUtils.leftPad(docline, docline.length() + indent));
	        }
	    }
	    
	    return result.toString();
	}

	public String getFieldScope(Field field, String localScopeName, String defaultScope) {
	    if (defaultScope==null) defaultScope = "private";
	    return ( field.getMeta(localScopeName)==null )? defaultScope : field.getMetaAsString(localScopeName);
	}

    protected String getPackageDeclaration(String savedToPackage, ClassMapping classMapping) {
        if (savedToPackage!=null && !savedToPackage.trim().equals("")) {
            return "package " + savedToPackage + ";";
        } else if ( classMapping.getGeneratedPackageName()!=null ) {
        	return "package " + classMapping.getGeneratedPackageName() + ";";
        }        
        return "";
    }

    protected void genPackageDelaration(String savedToPackage, ClassMapping classMapping, PrintWriter w) {
        String string = getPackageDeclaration(savedToPackage, classMapping);
        if(string.length()>0) {
            w.println(string);
        } else {
            w.println("// default package");
        }
    }
}
