package com.capgemini.reports.formatting;

import com.capgemini.framework.common.BeanHelper;

import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Creates a Javascript table declaration, along with content. The table is 2D, with line numbers [0..n] as dimension 1, and whatever you want as dimension 2.<br>
 * Example output with table name 'tab', and two provided maps:
 * <ul>
 * <li>map1={key1=val1, key2=val2}</li>
 * <li>map2={key1=val3, key2=val4}
 * </ul>
 * Expected output:
 * <p>
 * <code> var tab = new Array();<br>
 * tab[0] = new Array();<br>
 * tab[0]['key1'] = val1<br>
 * tab[0]['key2'] = val2<br>
 * tab[1] = new Array();<br>
 * tab[1]['key1'] = val3<br>
 * tab[1]['key2'] = val4</code>
 * <p>
 * Note: keys may not even be coherent between lines.
 */
public class JsTableCreator {

    final StringBuilder content = new StringBuilder();
    final String tableName;
    int lineCount;

    /**
     * Creates a js table, with the provided name. The table is 2D, with line numbers as dimension 1, and whatever you want as dimension 2.
     * 
     * @param tableName the table name.
     */
    public JsTableCreator(final String tableName) {
        this.tableName = tableName;
        this.content.append("\nvar ").append(tableName).append(" = new Array();\n");
        this.lineCount = 0;
    }

    /**
     * Adds a line showing for each map key, the associated value.
     * 
     * @param lineContent the {@link Map}
     */
    public void addLine(final Map<String, String> lineContent) {
        content.append('\n');
        String thisLine = "\t" + tableName + "[" + lineCount + "]";
        content.append(thisLine).append(" = new Array();\n");
        for (Entry<String, String> entry : lineContent.entrySet()) {
            content.append(thisLine).append("['").append(entry.getKey()).append("'] = '").append(entry.getValue()).append("';\n");
        }
        lineCount++;
    }

    /**
     * Adds the provided bean's content to a line in the table.
     * 
     * @param aJavaBean JAVA bean
     */
    public void addBean(final Object aJavaBean) {
        Map<String, String> theAttMap = BeanHelper.toStringMap(aJavaBean);
        addLine(theAttMap);
    }

    /**
     * Adds a line formed by the bean's contents, as well as the map's content.
     * 
     * @param map the map
     * @param aJavaBean the bean
     */
    public void addLineAndBean(final Map<String, String> map, final Object aJavaBean) {
        content.append('\n');
        String thisLine = "\t" + tableName + "[" + lineCount + "]";
        content.append(thisLine).append(" = new Array();\n");
        Map<String, String> lineContent = BeanHelper.toStringMap(aJavaBean);
        lineContent.putAll(map);
        for (Entry<String, String> entry : lineContent.entrySet()) {
            content.append(thisLine).append("['").append(entry.getKey()).append("'] = '").append(entry.getValue()).append("';\n");
        }
        lineCount++;
    }

    /**
     * Adds the provided beans' content to a line in the table.
     * 
     * @param someJavaBeans a {@link Collection} of JAVA beans
     */
    public void addAllBean(final Collection<Object> someJavaBeans) {
        for (Object aBean : someJavaBeans) {
            addBean(aBean);
        }
    }

    @Override
    public String toString() {
        return content.toString();
    }

}
