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 Matching extends Action {

    /** Logger. */
    private CLogger log = CLogger.getCLogger(this.getClass());
    
    /** Matching List Forward. */
    private static final String MATCHING_LIST = "matchinglist";

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

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

    /** Form ID. */
    private static final int FORM_ID = 108;
    
    /** Match Options           */
    private String[] matchOptions = new String[] {
        "C_Invoice_ID",
        "M_InOut_ID",
        "C_Order_ID" };

    /** Match Mode                  */
    private String[] matchMode = new String[] {
        "NotMatched",
        "Matched"};

    /** Invoice. */
    private static final int        MATCH_INVOICE = 0;
    /** Shipment. */
    private static final int        MATCH_SHIPMENT = 1;
    /** Order. */
    private static final int        MATCH_ORDER = 2;

    /**
     * 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);
        }

//        Env.setContext(wsc.ctx, 0, "IsSOTrx", "Y");
        wsc.ctx.setContext(0, "IsSOTrx", "Y");

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

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

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

        // Match from Label
        myForm.setMatchFromLabel(Msg.translate(wsc.ctx, "MatchFrom"));

        // Match From List
        ArrayList < HashMap > dataList = new ArrayList < HashMap > ();
        HashMap < String, Object > data;
        for (int i = 0; i < matchOptions.length; i++) {
            data = new HashMap < String, Object > ();
            data.put("key",i);
            data.put("value",Msg.getElement(wsc.ctx, matchOptions[i],false));
            dataList.add(data);
        }
        myForm.setMatchFromList(dataList);

        // Match to Label
        myForm.setMatchToLabel(Msg.translate(wsc.ctx, "MatchTo"));

        // Match To List
        dataList = new ArrayList < HashMap > ();
        switch(myForm.getMatchFrom()) {
        case MATCH_INVOICE :
            data = new HashMap < String, Object > ();
            data.put("key",1);
            data.put("value", Msg.getElement(wsc.ctx, matchOptions[MATCH_SHIPMENT],false));
            dataList.add(data);

            myForm.setMatchTo(MATCH_SHIPMENT);
            break;
        case MATCH_SHIPMENT :
            data = new HashMap < String, Object > ();
            data.put("key",0);
            data.put("value", Msg.getElement(wsc.ctx, matchOptions[MATCH_INVOICE],false));
            dataList.add(data);
            data = new HashMap < String, Object > ();
            data.put("key",2);
            data.put("value", Msg.getElement(wsc.ctx, matchOptions[MATCH_ORDER],false));
            dataList.add(data);

            myForm.setMatchTo(MATCH_INVOICE);
            break;
        case MATCH_ORDER :
            data = new HashMap < String, Object > ();
            data.put("key",1);
            data.put("value", Msg.getElement(wsc.ctx, matchOptions[MATCH_SHIPMENT],false));
            dataList.add(data);

            myForm.setMatchTo(MATCH_SHIPMENT);
            break;
        }
        myForm.setMatchToList(dataList);

        // Match mode Label
        myForm.setMatchModeLabel(Msg.translate(wsc.ctx, "MatchMode"));

        dataList = new ArrayList < HashMap > ();
        for (int i = 0; i < matchMode.length; i++) {
            data = new HashMap < String, Object > ();
            data.put("key",i);
            data.put("value", Msg.translate(wsc.ctx, matchMode[i]));
            dataList.add(data);
        }
        myForm.setMatchModeList(dataList);

        // Business Partner Label
        myForm.setBusinessPartnerLabel(Msg.translate(wsc.ctx, "C_BPartner_ID"));
        
        // Product Label
        myForm.setProductLabel(Msg.translate(wsc.ctx, "M_Product_ID"));
        
        // Date from Label
        myForm.setDateFromLabel(Msg.translate(wsc.ctx, "DateFrom"));
        
        // Date from Label
        myForm.setDateToLabel(Msg.translate(wsc.ctx, "DateTo"));
        
        // Search Label
        myForm.setSearchLabel(Msg.translate(wsc.ctx, "Search"));
        
        // Match From Text
        myForm.setMatchFromText(Msg.getElement(wsc.ctx, matchOptions[myForm.getMatchFrom()],false));

        // Match From Data List
        loadFromDataList(wsc, myForm);
        
        // Same Business Partner Label
        myForm.setSameBusinessPartnerLabel(Msg.translate(wsc.ctx, "SameBPartner"));

        // Same Product Label
        myForm.setSameProductLabel(Msg.translate(wsc.ctx, "SameProduct"));

        // Same Quantity Label
        myForm.setSameQuantityLabel(Msg.translate(wsc.ctx, "SameQty"));

        // Match To Text
        myForm.setMatchToText(Msg.getElement(wsc.ctx, matchOptions[myForm.getMatchTo()],false));

        // Match To Data List
        loadToDataList(wsc, myForm);
        
        // To Be Matched Label
        myForm.setToBeMatchedLabel(Msg.translate(wsc.ctx, "ToBeMatched"));

        // Matching Label
        myForm.setMatchingLabel(Msg.translate(wsc.ctx, "Matching"));

        // Match Difference Label
        myForm.setMatchDifferenceLabel(Msg.translate(wsc.ctx, "Difference"));

        // Process Label
        myForm.setProcessLabel(Msg.translate(wsc.ctx, "Process"));

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

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

        return mapping.findForward(MATCHING_LIST);

    }
    
    /**
     * Load From Data List.
     * @param wsc context
     * @param form Action From
     */
    private void loadFromDataList(
            final WebSessionCtx wsc,
            final MatchingForm form) {
        
        ArrayList < HashMap > dataList = form.getMatchFromDataList();
        if (dataList == null) {
            dataList = new ArrayList < HashMap > ();
        }
        HashMap < String, Object > data = new HashMap < String, Object > ();

        // Row Type
        data.put("RowType", "title");
        // ID
        data.put("ID", "");
        // Document Number
        data.put("DocumentNo", Msg.translate(wsc.ctx, "DocumentNo"));
        // Date
        data.put("Date", Msg.translate(wsc.ctx, "Date"));
        // Business Partner
        data.put("BusinessPartner", Msg.translate(wsc.ctx, "C_BPartner_ID"));
        // Line
        data.put("Line", Msg.translate(wsc.ctx, "Line"));
        // Product
        data.put("Product", Msg.translate(wsc.ctx, "M_Product_ID"));
        // Quantity
        data.put("Quantity", Msg.translate(wsc.ctx, "Qty"));
        // Matched
        data.put("Matched", Msg.translate(wsc.ctx, "Matched"));
        dataList.add(0,data);
        
        form.setMatchFromDataList(dataList);
    }

    /**
     * Load To Data List.
     * @param wsc context
     * @param form Action From
     */
    private void loadToDataList(
            final WebSessionCtx wsc,
            final MatchingForm form) {
        
        ArrayList < HashMap > dataList = form.getMatchToDataList();
        if (dataList == null) {
            dataList = new ArrayList < HashMap > ();
        }
        HashMap < String, Object > data = new HashMap < String, Object > ();

        // Row Type
        data.put("RowType", "title");
        // ID
        data.put("ID", "");
        // Document Number
        data.put("DocumentNo", Msg.translate(wsc.ctx, "DocumentNo"));
        // Date
        data.put("Date", Msg.translate(wsc.ctx, "Date"));
        // Business Partner
        data.put("BusinessPartner", Msg.translate(wsc.ctx, "C_BPartner_ID"));
        // Line
        data.put("Line", Msg.translate(wsc.ctx, "Line"));
        // Product
        data.put("Product", Msg.translate(wsc.ctx, "M_Product_ID"));
        // Quantity
        data.put("Quantity", Msg.translate(wsc.ctx, "Qty"));
        // Matched
        data.put("Matched", Msg.translate(wsc.ctx, "Matched"));
        dataList.add(0, data);

        form.setMatchToDataList(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

}
