package net.sourceforge.rtf.template.velocity;

import net.sourceforge.rtf.template.AbstractRTFDocumentTransformer;

/**
 * RTF Velocity Transformer which transform RTF Document to RTF Document with
 * Velocity Macro.
 * 
 * @version 1.0.0
 * @author <a href="mailto:angelo.zerr@gmail.com">Angelo ZERR</a>
 * 
 */
public class RTFVelocityTransformerImpl extends AbstractRTFDocumentTransformer {

    protected String getMacroEndForEach() {
        return "#end";
    }

    /**
     * Return velocity name used into #foreach for the field name fieldname. eg :
     * <ul>
     * <li>for fieldname <b>developers.Name</b>, this function return
     * $item_developers (if withGetter = false) and $item_developers.Name (if
     * withGetter = true) </li>
     * <li>for fieldname <b>developers.Roles.Name</b>, this function return
     * $item_developers_roles (if withGetter = false) and
     * $item_developers_roles.Name (if withGetter = true) </li>
     * </ul>
     * 
     * @param fieldName
     *            field name to translate into velocity name.
     * @param withGetter
     *            true if getter must be returned and false otherwise.
     * @return
     */
    protected String getObjectValueList(String fieldName,
            String fieldNameWithListInfo, boolean withGetter) {
        String objectName = "";
        if (fieldNameWithListInfo != null && fieldNameWithListInfo.length() > 0) {
            // eg : $workspace.[Developers].manager.Name must be transformed
            // into $item_workspace_Developers.manager.Name
            int indexLastEndedArray = fieldNameWithListInfo.lastIndexOf("]");
            if (indexLastEndedArray > 0) {
                // Test if there is several object after list (eg:manager.Name)
                if (fieldNameWithListInfo.indexOf(".", indexLastEndedArray + 2) > 0) {
                    String s = fieldNameWithListInfo.substring(0,
                            indexLastEndedArray);
                    s = s.replaceAll("\\[", "");
                    objectName = getObjectValueList(s, true);
                    objectName = objectName.replace('.', '_');
                    if (!withGetter)
                        return objectName;
                    else {
                        return objectName
                                + fieldNameWithListInfo.substring(
                                        indexLastEndedArray + 1,
                                        fieldNameWithListInfo.length());
                    }
                }
            }
        }

        // HERE : After list there is one getter

        // OLD transformation :
        return getObjectValueList(fieldName, withGetter);
    }

    protected String getObjectValueList(String fieldName, boolean withGetter) {
        String objectName = "";
        String getterName = "";
        if (fieldName.startsWith("$"))
            fieldName = fieldName.substring(1);
        objectName = fieldName;
        // get the 2 string betwew the last .
        // ex : $project.Name => objectName=project and getterName=Name
        // ex : $developer.Roles.Name => objectName=Roles and getterName=Name
        int dotLastIndex = fieldName.lastIndexOf(".");
        if (dotLastIndex != -1) {
            objectName = fieldName.substring(0, dotLastIndex);
            objectName = objectName.replace('.', '_');
            getterName = fieldName.substring(dotLastIndex + 1, fieldName
                    .length());
        }
        if (withGetter && getterName.length() > 0)
            return "$item_" + objectName + "." + getterName;
        else
            return "$item_" + objectName;
    }

    protected String getForeach(String fieldName, String fieldNameWithListInfo) {
        // Remove $ character
        if (fieldName.startsWith("$"))
            fieldName = fieldName.substring(1);
        String objectName = getObjectValueList(fieldName,
                fieldNameWithListInfo, false);
        String objectNameList = getItemListName(fieldName,
                fieldNameWithListInfo);
        StringBuffer foreachVelocity = new StringBuffer("");
        foreachVelocity.append("#foreach(");
        foreachVelocity.append(objectName);
        foreachVelocity.append(" in ");
        foreachVelocity.append("$" + objectNameList);
        foreachVelocity.append(" )");
        return foreachVelocity.toString();
    }

    protected String getMacroPageBreak(String itemNameList,
            String rtfPageBreakContent) {
        return "#if($velocityCount < $" + itemNameList + ".size()) "
                + rtfPageBreakContent + "#end";
    }

    protected String getMacroPageBreak(String itemNameList,
            String rtfPageBreakContent, int groupByPerPageBreak) {
        return " #if($velocityCount < $" + itemNameList
                + ".size() && $velocityCount%"
                + String.valueOf(groupByPerPageBreak) + "==0) "
                + rtfPageBreakContent + "#end ";
    }

    protected String getMacroIf(String condition) {
        return "#if (" + condition + ")";
    }

    protected String getMacroEndIf() {
        return "#end";
    }

    protected String getMacroElse() {
        return "#else";
    }

}
