package com.ampiere.web.struts.form;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
import java.util.logging.Level;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.compiere.model.MForm;
import org.compiere.util.CLogger;
import org.compiere.util.Ctx;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.WebSessionCtx;

import com.ampiere.util.Constants;

/**
 * @author siqinbilige
 */
public class ChargeAccount extends Action {

    /** Logger. */
    private CLogger log = CLogger.getCLogger(this.getClass());
    
    /** Account List Forward. */
    private static final String ACCOUNT_LIST = "accountlist";

    /** Action Form. */
    private static final String ACTION_FORM = "ChargeAccountForm";

    /** Global Error Forward. */
    private static final String ERROR_FORWARD = "error";

    /** Form ID. */
    private static final int FORM_ID = 105;

    /**
     * Action execute.
     * @param mapping mapping
     * @param actionForm actionForm
     * @param request request
     * @param response response
     * @throws Exception Exception
     * @return ActionForward
     * @see org.apache.struts.action.Action#execute(
     *      org.apache.struts.action.ActionMapping,
     *      org.apache.struts.action.ActionForm,
     *      javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse)
     */
    public final ActionForward execute(
            final ActionMapping mapping,
            final ActionForm actionForm,
            final HttpServletRequest request,
            final HttpServletResponse response)
    throws Exception {
    	
		//201001 
        WebSessionCtx wscTest = WebSessionCtx.get(request); 
        if (wscTest == null) {
            log.log(Level.SEVERE, "Session Time Out.");
            request.setAttribute(Constants.SESSION_TIMEOUT_INFO, "Session Time Out. Please login again.");
            return mapping.findForward(Constants.SESSION_TIMEOUT);
        }
        //--201001    	

        log.fine("Begin " + this.getClass().getName() + ";execute");

        WebSessionCtx wsc = WebSessionCtx.get(request); 
        if (wsc == null) {
            log.log(Level.SEVERE, "Session Time Out.");
            return mapping.findForward(ERROR_FORWARD);
        }

        MForm form = getForm(wsc.ctx, FORM_ID);
//        Env.setContext(wsc.ctx, "FormName", form.getName());
        wsc.ctx.setContext("FormName", form.getName());

        ChargeAccountForm myForm =
            (ChargeAccountForm) request.getAttribute(ACTION_FORM);
        if (myForm == null) {
            myForm = (ChargeAccountForm) actionForm;
            if (myForm == null) {
                myForm = new ChargeAccountForm();
            }
        }
        
        // Main Window Title
        myForm.setMainWindowTitle(form.getName() + " - " + wsc.loginInfo);

        // Page title.
        myForm.setPageTitle(form.getName());

        // Charge New Account Label
        myForm.setChargeNewLabel(Msg.translate(wsc.ctx, "ChargeNewAccount"));

        // Charge New Key Label
        myForm.setKeyLabel(Msg.translate(wsc.ctx, "Value"));

        // Expense Label
        myForm.setExpenseLabel(Msg.translate(wsc.ctx, "Expense"));
        myForm.setExpense("on");

        // Key Name Label
        myForm.setNameLabel(Msg.translate(wsc.ctx, "Name"));

        // Generate Label
        myForm.setGenerateLabel(Msg.translate(wsc.ctx, "Create"));

        // Charge From Account Label
        myForm.setChargeFromLabel(Msg.translate(wsc.ctx, "ChargeFromAccount"));

        // Account List
        myForm.setAccountList(getAccountList(wsc));

        // Save form to request.
        request.setAttribute(ACTION_FORM, myForm);

        log.fine("End " + this.getClass().getName() + ";execute");

        return mapping.findForward(ACCOUNT_LIST);

    }
    
    /**
     * Get Account List.
     * @param wsc context
     * @return Account List
     */
    private ArrayList getAccountList(final WebSessionCtx wsc) {
        
        ArrayList < HashMap > dataList = new ArrayList < HashMap > ();
        HashMap < String, Object > data = new HashMap < String, Object > ();

//        int accountSchemaId = Env.getContextAsInt(wsc.ctx, "$C_AcctSchema_ID");
        int accountSchemaId = wsc.ctx.getContextAsInt("$C_AcctSchema_ID");
        int accountElementId = 0;
        //  get Element
        String sql = "SELECT C_Element_ID FROM C_AcctSchema_Element "
            + "WHERE ElementType='AC' AND C_AcctSchema_ID=?";
        try {
            PreparedStatement pstmt = DB.prepareStatement(sql, null);
            pstmt.setInt(1, accountSchemaId);
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()) {
                accountElementId = rs.getInt(1);
            }
            rs.close();
            pstmt.close();
        } catch (SQLException e) {
            log.log(Level.SEVERE, sql, e);
        }

        if (accountElementId == 0) {
            return dataList;
        }

//        Env.setContext(wsc.ctx, 0, "AccountElementId", accountElementId);
        wsc.ctx.setContext(0, "AccountElementId", accountElementId);
        
        data.put("RowType", "title");
        data.put("Select", Msg.getMsg(wsc.ctx, "Select"));
        data.put("Value", Msg.translate(wsc.ctx, "Value"));
        data.put("Name", Msg.translate(wsc.ctx, "Name"));
        data.put("Expense", Msg.getMsg(wsc.ctx, "Expense"));
        dataList.add(data);

        sql = "SELECT C_ElementValue_ID,Value, Name, AccountType "
            + "FROM C_ElementValue "
            + "WHERE AccountType IN ('R','E')"
            + " AND IsSummary='N'"
            + " AND C_Element_ID=? "
            + "ORDER BY 2";
        try {
            PreparedStatement pstmt = DB.prepareStatement(sql, null);
            pstmt.setInt(1, accountElementId);
            ResultSet rs = pstmt.executeQuery();
            while (rs.next()) {
                data = new HashMap < String, Object > ();
                data.put("RowType", "data");
                data.put("Select", rs.getInt(1));
                data.put("Value", rs.getInt(2));
                data.put("Name", rs.getString(3));
                data.put("Expense", new Boolean(rs.getString(4).equals("E")));
                dataList.add(data);
            }
            rs.close();
            pstmt.close();
        } catch (SQLException e) {
            log.log(Level.SEVERE, sql, e);
        }

        //  Other Defaults
//        int clientId        = Env.getAD_Client_ID(wsc.ctx);
        int clientId        = wsc.ctx.getAD_Client_ID();
        int taxCategoryId   = 0;

        //  TaxCategory
        sql = "SELECT C_TaxCategory_ID FROM C_TaxCategory "
            + "WHERE IsDefault='Y' AND AD_Client_ID=?";
        try {
            PreparedStatement pstmt = DB.prepareStatement(sql, null);
            pstmt.setInt(1, clientId);
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()) {
                taxCategoryId = rs.getInt(1);
            }
            rs.close();
            pstmt.close();
        } catch (SQLException e) {
            log.log(Level.SEVERE, sql, e);
        }

//        Env.setContext(wsc.ctx, 0, "TaxCategoryID", taxCategoryId);
        wsc.ctx.setContext(0, "TaxCategoryID", taxCategoryId);
        
        return dataList;
    }
    
    /**
     *  Get Form from Form ID.
     *  @param ctx Properties
     *  @param formId Form ID
     *  @return form
     */
    private MForm getForm(final Ctx ctx, final int formId) {

        // Get Form from Form ID
        MForm form = new MForm(ctx, formId, null);
        
        boolean trl = !Env.isBaseLanguage(ctx, "AD_Form");
        if (trl) {
            String sql = "SELECT t.Name, t.Description, t.Help "
                       + "FROM AD_Form f INNER JOIN AD_Form_Trl t"
                       + " ON (f.AD_Form_ID=t.AD_Form_ID AND AD_Language=?)"
                       + "WHERE f.AD_Form_ID=?";
            try {
                PreparedStatement pstmt = DB.prepareStatement(sql, null);
                if (trl) {
                    pstmt.setString(1, Env.getAD_Language(ctx));
                    pstmt.setInt(2, formId);

                    ResultSet rs = pstmt.executeQuery();
                    if (rs.next()) {
                        form.setName(rs.getString(1));
                        form.setDescription(rs.getString(2));
                        form.setHelp(rs.getString(3));
                    }
                    rs.close();
                    pstmt.close();
                }
            } catch (SQLException e) {
                log.log(Level.SEVERE, sql, e);
            }
        }

        return form;
    }   //  getForm
}
