/*
 * ICESOFT COMMERCIAL SOURCE CODE LICENSE V 1.1
 *
 * The contents of this file are subject to the ICEsoft Commercial Source
 * Code License Agreement V1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of the
 * License at
 * http://www.icesoft.com/license/commercial-source-v1.1.html
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations under
 * the License.
 *
 * Copyright 2009-2015 ICEsoft Technologies Canada, Corp. All Rights Reserved.
 */
package com.icesoft.faces.facelets.example.expandabletable;

import com.icesoft.faces.facelets.component.expandabletable.ExpandableRecord;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.GregorianCalendar;

/**
 * <p>The <code>SalesRecordsManager</code> class is responsible for constructing
 * the list of <code>SalesGroupRecordBean</code> beans which will be bound to a
 * expandableTable component.  This construction process is currently static
 * but could easily be configured to work with Hibernate or DAO implementation.
 * </p>
 */
public class SalesRecordsManager implements Serializable {
    //List of records to be returned to the dataTable component
    private ArrayList inventoryGroupItemBeans;
    //saves if the manager has been initialized or not
    private boolean isInit;
    // css style related constants
    public static final String GROUP_INDENT_STYLE_CLASS = "groupRowIndentStyle";
    public static final String GROUP_ROW_STYLE_CLASS = "groupRowStyle";
    public static final String CHILD_INDENT_STYLE_CLASS = "childRowIndentStyle";
    public static final String CHILD_ROW_STYLE_CLASS = "childRowStyle";
    //Holds the column names, needed to build the expandableTable component   
    private ArrayList columnNames = new ArrayList();

    /**
     * SalesRecordsManager constructor.  Runs init method to initialize the
     * list of records to be used by the expandableTable component.
     */
    public SalesRecordsManager() {
        init();
    }

    /**
     * Initialize method, used to build and populate the list to
     * be used by the expandableTable custom component.
     */
    private void init() {
        //check if the manager has been initiatated
        if (isInit) {
            return;
        }
        isInit = true;

        //initiate the list
        if (inventoryGroupItemBeans != null) {
            inventoryGroupItemBeans.clear();
        } else {
            inventoryGroupItemBeans = new ArrayList(10);
        }

        //Build the array list group items

        //Tuesday's Group
        SalesRecord salesRecord = new SalesRecord();
        salesRecord.setDescription("Tuesday's Items");
        salesRecord.setDate(new GregorianCalendar(2006, 5, 2));

        ExpandableRecord salesRecordGroup =
                new ExpandableRecord(GROUP_INDENT_STYLE_CLASS,
                        GROUP_ROW_STYLE_CLASS,
                        inventoryGroupItemBeans, false,
                        salesRecord, "parent");

        //Add Tuesday's Children
        SalesRecord childRecord = new SalesRecord();
        childRecord.setDescription("2mm Torx screws");
        childRecord.setDate(new GregorianCalendar(2006, 6, 3));
        childRecord.setQuantity(6);
        childRecord.setPrice(0.25);
        ExpandableRecord childSalesGroup =
                new ExpandableRecord(CHILD_INDENT_STYLE_CLASS,
                        CHILD_ROW_STYLE_CLASS,
                        childRecord,
                        "child");
        salesRecordGroup.addChildRecord(childSalesGroup);
        childRecord = new SalesRecord();
        childRecord.setDescription("5mm Torx screws");
        childRecord.setDate(new GregorianCalendar(2006, 7, 2));
        childRecord.setQuantity(6);
        childRecord.setPrice(0.25);
        childSalesGroup =
                new ExpandableRecord(CHILD_INDENT_STYLE_CLASS,
                        CHILD_ROW_STYLE_CLASS,
                        childRecord, "child");
        salesRecordGroup.addChildRecord(childSalesGroup);
        //Calculate Tuesday's Group Quantity and Price
        salesRecord = (SalesRecord) salesRecordGroup.getRecord();
        salesRecord.setQuantity(calcQuantity(salesRecordGroup));
        salesRecord.setPrice(calcPrice(salesRecordGroup));

        //Wednesdays Group
        salesRecord = new SalesRecord();
        salesRecord.setDescription("Wednesday's Items");
        salesRecord.setDate(new GregorianCalendar(2006, 6, 2));
        salesRecordGroup =
                new ExpandableRecord(GROUP_INDENT_STYLE_CLASS,
                        GROUP_ROW_STYLE_CLASS,
                        inventoryGroupItemBeans, true,
                        salesRecord, "parent");
        //Add Wednesday's Children
        childRecord = new SalesRecord();
        childRecord.setDescription("Steel Hammer");
        childRecord.setDate(new GregorianCalendar(2006, 6, 6));
        childRecord.setQuantity(1);
        childRecord.setPrice(35.0);
        childSalesGroup =
                new ExpandableRecord(CHILD_INDENT_STYLE_CLASS,
                        CHILD_ROW_STYLE_CLASS,
                        childRecord, "child");
        salesRecordGroup.addChildRecord(childSalesGroup);
        childRecord = new SalesRecord();
        childRecord.setDescription("Bag of 10# nails");
        childRecord.setDate(new GregorianCalendar(2006, 6, 6));
        childRecord.setQuantity(2);
        childRecord.setPrice(15.0);
        childSalesGroup =
                new ExpandableRecord(CHILD_INDENT_STYLE_CLASS,
                        CHILD_ROW_STYLE_CLASS,
                        childRecord, "child");
        salesRecordGroup.addChildRecord(childSalesGroup);
        childRecord = new SalesRecord();
        childRecord.setDescription("Bag of 15# nails");
        childRecord.setDate(new GregorianCalendar(2006, 6, 6));
        childRecord.setQuantity(5);
        childRecord.setPrice(15.0);
        childSalesGroup =
                new ExpandableRecord(CHILD_INDENT_STYLE_CLASS,
                        CHILD_ROW_STYLE_CLASS,
                        childRecord, "child");
        salesRecordGroup.addChildRecord(childSalesGroup);
        //Calculate Wednesday's Group Quantity and Price
        salesRecord = (SalesRecord) salesRecordGroup.getRecord();
        salesRecord.setQuantity(calcQuantity(salesRecordGroup));
        salesRecord.setPrice(calcPrice(salesRecordGroup));

        //Thursday's Group
        salesRecord = new SalesRecord();
        salesRecord.setDescription("Thursday's Items");
        salesRecord.setDate(new GregorianCalendar(2006, 7, 2));
        salesRecordGroup =
                new ExpandableRecord(GROUP_INDENT_STYLE_CLASS,
                        GROUP_ROW_STYLE_CLASS,
                        inventoryGroupItemBeans, false,
                        salesRecord, "parent");
        //Add Thursday's Children
        childRecord = new SalesRecord();
        childRecord.setDescription("B&D Table Saw");
        childRecord.setDate(new GregorianCalendar(2006, 6, 15));
        childRecord.setQuantity(1);
        childRecord.setPrice(310.0);
        childSalesGroup =
                new ExpandableRecord(CHILD_INDENT_STYLE_CLASS,
                        CHILD_ROW_STYLE_CLASS,
                        childRecord, "child");
        salesRecordGroup.addChildRecord(childSalesGroup);
        //Calculate Thursday's Group Quantity and Price
        salesRecord = (SalesRecord) salesRecordGroup.getRecord();
        salesRecord.setQuantity(calcQuantity(salesRecordGroup));
        salesRecord.setPrice(calcPrice(salesRecordGroup));

        //Create the list of column names to be used by the expandableTable
        //custom facelets component.
        columnNames.add("description");
        columnNames.add("date");
        columnNames.add("quantity");
        columnNames.add("price");
        columnNames.add("total");
    }

    /**
     * Cleans up the resources used by this class.  This method could be
     * called when a session destroyed event is called.
     */
    public void dispose() {
        isInit = false;
        if (inventoryGroupItemBeans != null) {
            ExpandableRecord tmp;
            ArrayList tmpList;
            for (int i = 0; 1 < inventoryGroupItemBeans.size(); i++) {
                tmp = (ExpandableRecord) inventoryGroupItemBeans.get(i);
                tmpList = tmp.getChildRecords();
                if (tmpList != null) {
                    tmpList.clear();
                }
            }
            inventoryGroupItemBeans.clear();
        }
    }

    /**
     * Gets the list of <code>ExpandableRecord</code> which will be used by the
     * expandableTable custom component.
     *
     * @return inventorGroupItemBeans array list of parent ExpandableRecord
     *         objects.
     */
    public ArrayList getSalesGroupRecordBeans() {
        return inventoryGroupItemBeans;
    }

    /**
     * Gets the list of column names which will be used by the
     * expandableTable custom component.
     *
     * @return columnNames array list of column names.
     */
    public ArrayList getColumnNames() {
        return columnNames;
    }

    /**
     * Calculates the quantity for the parent <code>ExpandableRecord</code>
     * objects.
     *
     * @param salesRecordGroup parent ExpandableRecord object.
     * @return total           quantity calculated.
     */
    private int calcQuantity(ExpandableRecord salesRecordGroup) {
        ArrayList childRecords = salesRecordGroup.getChildRecords();
        int total = 0;
        SalesRecord tmp;
        for (Object childRecord : childRecords) {
            tmp = (SalesRecord) ((ExpandableRecord) childRecord).getRecord();
            total += tmp.getQuantity();
        }
        return total;
    }

    /**
     * Calculates the price for the parent ExpandableRecord Object.
     *
     * @param salesRecordGroup parent ExpandableRecord object.
     * @return total           price calculated.
     */
    private double calcPrice(ExpandableRecord salesRecordGroup) {
        ArrayList childRecords = salesRecordGroup.getChildRecords();
        double total = 0.0;
        SalesRecord tmp;
        for (int i = 0; i < childRecords.size(); i++) {
            tmp = (SalesRecord) ((ExpandableRecord) childRecords.get(i)).getRecord();
            total += tmp.getPrice();
        }
        return total;
    }
}
