/******************************************************************************
 * Copyright (C) 2013 Trek Global                                             *
 * Product: iDempiere ERP & CRM Smart Business Solution                       *
 * This program is free software; you can redistribute it and/or modify it    *
 * under the terms version 2 of the GNU General Public License as published   *
 * by the Free Software Foundation. This program is distributed in the hope   *
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.           *
 * See the GNU General Public License for more details.                       *
 * You should have received a copy of the GNU General Public License along    *
 * with this program; if not, write to the Free Software Foundation, Inc.,    *
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.                     *
 *****************************************************************************/

package org.adempiere.webui.panel;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;

import org.adempiere.webui.apps.ProcessParameterPanel;
import org.adempiere.webui.apps.form.WProcessParameter;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.ConfirmPanel;
import org.adempiere.webui.component.Panel;
import org.adempiere.webui.component.VerticalBox;
import org.adempiere.webui.factory.ButtonFactory;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.compiere.model.GridTab;
import org.compiere.model.MPInstancePara;
import org.compiere.model.MProcessDrillRule;
import org.compiere.model.MScheduler;
import org.compiere.model.MSysConfig;
import org.compiere.process.ProcessInfo;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Div;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Html;
import org.zkoss.zul.Vlayout;

/**
 * Form to capture process parameters for scheduler, etc
 */
@org.idempiere.ui.zk.annotation.Form
public class WProcessParameterForm extends ADForm
{
	/**
	 * generated serial id
	 */
	private static final long serialVersionUID = -2533099650671242190L;

	/** Form Controller */
	private WProcessParameter pp;

	private VerticalBox dialogBody;

	private Html message;

	private Panel centerPanel;

	private ProcessInfo processInfo;

	private String m_Name;

	private StringBuffer m_messageText = new StringBuffer();

	private String tableName = "";

	private ProcessParameterPanel parameterPanel;
	
	/* SysConfig USE_ESC_FOR_TAB_CLOSING */
	private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
	
	private final static CLogger log = CLogger.getCLogger(WProcessParameterForm.class);

	/**
	 * @param wpp
	 */
	public WProcessParameterForm(WProcessParameter wpp) {
		pp = wpp;
		initComponents();
	}

	@Override
	public Mode getWindowMode() {
		return Mode.HIGHLIGHTED;
	}

	@Override
	public boolean setVisible(boolean visible) {
		 boolean ok = super.setVisible(visible);
		 if (visible && getProcessInfo() != null && parameterPanel == null)
			 initForm();
		 return ok;
	}

	@Override
	public void onEvent(Event event) throws Exception {
		Component component = event.getTarget();
		if (component instanceof Button) {
			Button element = (Button)component;
			if ("Ok".equalsIgnoreCase(element.getId())) {
				onOK();
			} else if ("Cancel".equalsIgnoreCase(element.getId())) {
				onCancel();
			}
		} else {
			super.onEvent(event);
		}
	}
	
	/**
	 * Handle onCancel event
	 */
	private void onCancel() {
		// do not allow to close tab for Events.ON_CTRL_KEY event
		if(isUseEscForTabClosing)
			SessionManager.getAppDesktop().setCloseTabWithShortcut(false);

		this.dispose();
	}

	/**
	 * Handle onOk event
	 */
	private void onOK() {
		MPInstancePara[] paras = parameterPanel.getParameters();
		GridTab gridTab = super.getGridTab();
		if(gridTab != null)
			tableName = gridTab.getTableName();
		pp.saveParameters(paras, tableName);
		this.dispose();
	}

	@Override
	protected void initForm() {
		if (getProcessInfo() != null) {
			int AD_Process_ID = 0;
			GridTab gridTab = super.getGridTab();
			if(gridTab != null)
				tableName = gridTab.getTableName();
			if(tableName.equalsIgnoreCase(MScheduler.Table_Name)) {
				MScheduler scheduler = new MScheduler(Env.getCtx(), getProcessInfo().getRecord_ID(), null);
				AD_Process_ID = scheduler.getAD_Process_ID();
			}
			else if(tableName.equalsIgnoreCase(MProcessDrillRule.Table_Name)) {
				MProcessDrillRule drillRule = new MProcessDrillRule(Env.getCtx(), getProcessInfo().getRecord_ID(), null);
				AD_Process_ID = drillRule.getAD_Process_ID();
			}
			if (AD_Process_ID > 0) {
				processInfo = new ProcessInfo("", AD_Process_ID);
				init();
			}
		}
		this.setSizable(true);
		this.setClosable(true);
		if (!ThemeManager.isUseCSSForWindowSize()) {
			ZKUpdateUtil.setWindowWidthX(this, 500);
		} else {
			ZKUpdateUtil.setWidth(this, null);			
		}
		ZKUpdateUtil.setVflex(this, "min");
	}

	/**
	 * Create components
	 */
	private void initComponents() {
		this.setBorder("normal");		
		dialogBody = new VerticalBox();
		ZKUpdateUtil.setHflex(dialogBody, "1");
		Vlayout dialogContent = new Vlayout();
		ZKUpdateUtil.setHflex(dialogContent, "1");
		ZKUpdateUtil.setVflex(dialogContent, "1");
		dialogContent.setSclass("dialog-content");
		dialogBody.appendChild(dialogContent);
		Div div = new Div();
		div.setId("message");
		message = new Html();
		div.appendChild(message);
		div.setStyle("max-height: 150pt; overflow: auto;");
		dialogContent.appendChild(div);
		centerPanel = new Panel();
		dialogContent.appendChild(centerPanel);
		Hbox hbox = new Hbox();
		ZKUpdateUtil.setWidth(hbox, "100%");
		hbox.setSclass("dialog-footer");
		Button btn = ButtonFactory.createNamedButton(ConfirmPanel.A_OK);
		btn.setId("Ok");
		btn.addEventListener(Events.ON_CLICK, this);
		hbox.appendChild(btn);

		btn = ButtonFactory.createNamedButton(ConfirmPanel.A_CANCEL);
		btn.setId("Cancel");
		btn.addEventListener(Events.ON_CLICK, this);

		hbox.appendChild(btn);
		hbox.setPack("end");
		dialogBody.appendChild(hbox);
		this.appendChild(dialogBody);		
		this.setSclass("popup-dialog process-parameter-form-dialog");
	}
	
	/**
	 * Init {@link #parameterPanel}
	 * @return true if init ok
	 */
	private boolean init()
	{
		//
		boolean trl = !Env.isBaseLanguage(Env.getCtx(), "AD_Process");
		String sql = "SELECT Name, Description, Help, IsReport, ShowHelp "
				+ "FROM AD_Process "
				+ "WHERE AD_Process_ID=?";
		if (trl)
			sql = "SELECT t.Name, t.Description, t.Help, p.IsReport, p.ShowHelp "
				+ "FROM AD_Process p, AD_Process_Trl t "
				+ "WHERE p.AD_Process_ID=t.AD_Process_ID"
				+ " AND p.AD_Process_ID=? AND t.AD_Language=?";

		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try
		{
			pstmt = DB.prepareStatement(sql, null);
			pstmt.setInt(1, processInfo.getAD_Process_ID());
			if (trl)
				pstmt.setString(2, Env.getAD_Language(Env.getCtx()));
			rs = pstmt.executeQuery();
			if (rs.next())
			{
				m_Name = rs.getString(1);
				//
				m_messageText.append("<b>");
				String s = rs.getString(2);		//	Description
				if (rs.wasNull())
					;
				else
					m_messageText.append(s);
				m_messageText.append("</b>");

				s = rs.getString(3);			//	Help
				if (!rs.wasNull())
					m_messageText.append("<p>").append(s).append("</p>");
			}
		}
		catch (SQLException e)
		{
			log.log(Level.SEVERE, sql, e);
			return false;
		}
		finally
		{
			DB.close(rs, pstmt);
		}

		if (m_Name == null)
			return false;
		//
		this.setTitle(m_Name);
		message.setContent(m_messageText.toString());

		processInfo.setAD_User_ID (Env.getAD_User_ID(Env.getCtx()));
		processInfo.setAD_Client_ID(Env.getAD_Client_ID(Env.getCtx()));
		processInfo.setTitle(m_Name);
		parameterPanel = new ProcessParameterPanel(m_WindowNo, processInfo);
		centerPanel.getChildren().clear();
		if ( parameterPanel.init() ) {
			centerPanel.appendChild(parameterPanel);
		} else {
			return false;
		}

		return true;
	}	//	init

	@Override
	public void setWidth(String width) {
		super.setWidth(width);
	}
	
}
