/***********************************************************************
 * This file is part of iDempiere ERP Open Source                      *
 * http://www.idempiere.org                                            *
 *                                                                     *
 * Copyright (C) Contributors                                          *
 *                                                                     *
 * This program is free software; you can redistribute it and/or       *
 * modify it under the terms of the GNU General Public License         *
 * as published by the Free Software Foundation; either version 2      *
 * of the License, or (at your option) any later version.              *
 *                                                                     *
 * 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., 51 Franklin Street, Fifth Floor, Boston,          *
 * MA 02110-1301, USA.                                                 *
 *                                                                     *
 * Contributors:                                                       *
 * - Diego Ruiz                        								   *
 **********************************************************************/
package org.adempiere.webui.window;
import java.util.Map;
import java.util.logging.Level;
import org.adempiere.util.Callback;
import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.component.Messagebox;
import org.adempiere.webui.editor.WChosenboxListEditor;
import org.adempiere.webui.editor.WChosenboxSearchEditor;
import org.adempiere.webui.editor.WEditor;
import org.adempiere.webui.editor.WNumberEditor;
import org.adempiere.webui.editor.WPasswordEditor;
import org.adempiere.webui.editor.WSearchEditor;
import org.adempiere.webui.editor.WStringEditor;
import org.adempiere.webui.editor.WTableDirEditor;
import org.compiere.model.MLookup;
import org.compiere.util.CLogMgt;
import org.compiere.util.CLogger;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Trace;
import org.compiere.util.Util;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
/**
 * Static method for message and input dialog
 */
public final class Dialog {
	
    private static final CLogger logger = CLogger.getCLogger(Dialog.class);
    
    private Dialog() {
    }
    
    /**
     * Construct a message from the AD_Message and the additional message
     *
     * @param adMessage	AD_Message string
     * @param message additional message
     * @return The translated AD_Message appended with the additional message
     */
    private static String constructMessage(String adMessage, String message, Object ... args) {
		StringBuffer out = new StringBuffer();
		if (!Util.isEmpty(adMessage)) {
			out.append(getADMessage(adMessage, args));
		}
		if (!Util.isEmpty(message)) {
			if (out.length() > 0)
				out.append("
");
			out.append(message);
		}
		return out.toString();
	}
    
    /**
     * @param adMessage
     * @param args
     * @return translated message
     */
    private static String getADMessage(String adMessage, Object ... args) {
    	String message;
    	if (args != null && args.length > 0)
    		message = Msg.getMsg(Env.getCtx(), adMessage, args);
    	else
    		message = Msg.getMsg(Env.getCtx(), adMessage);
    	
    	return message;
    }
	/**
	 *	Display dialog with a warning icon
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
	 */    
    public static void warn(int windowNo, String adMessage) {
        warn(windowNo, adMessage, null, null);
    }
	/**
	 *	Display a dialog with a warning icon
	 *
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
	 *	@param	title		Message box title
	 */    
    public static void warn(int windowNo, String adMessage, String title) {
        warn(windowNo, adMessage, null, title);
    }
	/**
	 *	Display a dialog with a warning icon
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
	 *	@param	additionalMessage		Additional message
	 *	@param	title		If none then one will be generated
	 */
    public static void warn(int windowNo, String adMessage, String additionalMessage, String title) {
    	if (logger.isLoggable(Level.INFO)) 
    		logger.info(adMessage + " - " + additionalMessage);
    	String dialogTitle = getDialogTitle(title, windowNo);
    	String out = constructMessage(adMessage, additionalMessage);
		String message = formatDialogMessage(out);
		Messagebox.showDialog(message, dialogTitle, Messagebox.OK, Messagebox.EXCLAMATION);
    }
    
    /**
     * @param title
     * @param windowNo
     * @return title for dialog
     */
    private static String getDialogTitle(String title, int windowNo) {
    	return title == null ? AEnv.getDialogHeader(Env.getCtx(), windowNo) : title;
    }
    /**
     * Replace "\n" with "<br>" tag.
     * @param originalMessage
     * @return message
     */
    private static String formatDialogMessage(String originalMessage) {
    	return originalMessage.replace("\n", "
");
    }
        
	/**
	 *	Display dialog with an error icon
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
	 */
    
    public static void error(int windowNo, String adMessage) {
        error(windowNo, adMessage, null);
    }
	/**
	 *	Display dialog with an error icon
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
	 *	@param	additionalMessage         Additional message
	 */
    public static void error(int windowNo, String adMessage, String additionalMessage) {
    	error(windowNo, adMessage, additionalMessage, (Callback)null);
    }
    
    /**
	 *	Display dialog with an error icon
	 *
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
	 *	@param	additionalMessage		Additional message
	 *  @param  callback
	 */
    public static void error(int windowNo, String adMessage, String additionalMessage, Callback callback) {
    	error(windowNo, adMessage, additionalMessage, callback, null);
    }
    
    /**
	 *	Display dialog with an error icon
	 *
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
	 *	@param	additionalMessage		Additional message
	 *  @param	title		If none then one will be generated
	 */
    public static void error(int windowNo, String adMessage, String additionalMessage, String title) {
    	error(windowNo, adMessage, additionalMessage, (Callback)null, title);
    }
    
	/**
	 *	Display dialog with an error icon
	 *
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
	 *	@param	additionalMessage		Additional message
	 *  @param  callback
	 *  @param	title		If none then one will be generated
	 */
    public static void error(int windowNo, String adMessage, String additionalMessage, Callback callback, String title) {
		if (logger.isLoggable(Level.INFO)) 
			logger.info(adMessage + " - " + additionalMessage);
		if (CLogMgt.isLevelFinest()) {
			Trace.printStack();
		}
		String dialogTitle = getDialogTitle(title, windowNo);
    	String out = constructMessage(adMessage, additionalMessage);
		String message = formatDialogMessage(out);
        
		Messagebox.showDialog(message, dialogTitle, Messagebox.OK, Messagebox.ERROR, callback);
    }
    /**
	 * Ask Question with question icon and (OK) (Cancel) buttons
	 * @deprecated 
	 * @param	windowNo	Number of Window
	 * @param	adMessage	Message to be translated
	 * @return true, if OK
	 */
    @Deprecated(forRemoval = true, since = "11")
    public static boolean ask(int windowNo, String adMessage) {
    	return ask(windowNo, adMessage, "");
    }
    
    /**
	 *	Ask Question with question icon and (OK) (Cancel) buttons
	 *
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
	 *	@param	callback
	 *	@return ignore, use callback instead.
	 */    
    public static boolean ask(int windowNo, String adMessage, final Callback callback) {
    	return ask(null, windowNo, adMessage, callback);
    }
    /**
	 * Ask Question with question icon and (OK) (Cancel) buttons
	 *
	 * @deprecated
	 * @param	windowNo	Number of Window
	 * @param	adMessage	Message to be translated
	 * @param	additionalMessage			Additional clear text message
	 * @return true, if OK
	 */
    @Deprecated(forRemoval = true, since = "11")
    public static boolean ask(int windowNo, String adMessage, String additionalMessage) {
    	return ask(windowNo, adMessage, additionalMessage, (Callback)null);
    }
    
    /**
	 *	Ask Question with question icon and (OK) (Cancel) buttons
	 *
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
	 *	@param	additionalMessage			Additional clear text message
     *  @param callback
	 *	@return ignore, use callback instead.
	 */    
    public static boolean ask(int windowNo, String adMessage, String additionalMessage, final Callback callback) {
    	return ask(null, windowNo, adMessage, additionalMessage, callback);
    }
    
    /**
	 *	Ask Question with question icon and (OK) (Cancel) buttons
	 *
     *  @param  title
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
     *  @param  callback
     *  @param  args
	 *	@return ignore, use callback instead.
	 */
    public static boolean ask(String title, int windowNo, String adMessage, final Callback callback, Object ... args) {
    	return ask(title, windowNo, adMessage, null, callback, args);
    }
    
    /**
	 *	Ask Question with question icon and (OK) (Cancel) buttons
	 *
	 *	@param	windowNo	Number of Window
	 *	@param	title		Title of the dialog panel
	 *	@param	adMessage   Message to be translated
	 *	@param	msg			Additional clear text message
     *  @param  callback
	 *	@return ignore, use callback instead.
	 */        
    public static boolean ask(int windowNo, String title, String adMessage, String msg, final Callback callback) {
    	return ask(title, windowNo, adMessage, msg, callback);
    }
    
    /**
	 *	Ask Question with question icon and (OK) (Cancel) buttons
	 *
     *  @param  title
	 *	@param	windowNo	Number of Window
	 *	@param	adMessage	Message to be translated
	 *	@param	additionalMessage			Additional clear text message
     *  @param  callback
     *  @param  args
	 *	@return ignore, use callback instead.
	 */
    public static boolean ask(String title, int windowNo, String adMessage, String additionalMessage, final Callback callback, Object ... args) {
    	Callback msgCallback = getMessageCallback(callback);
    	String message = constructMessage(adMessage, additionalMessage, args);
		String dialogTitle = getDialogTitle(title, windowNo);
    	message = formatDialogMessage(message);
    	
        int response = Messagebox.showDialog(message, dialogTitle, 
        		Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION, msgCallback, (msgCallback == null));
        return (response == Messagebox.OK);
    }
    
    /**
     * Create Callback instance that will act as proxy for the "Callback<Boolean>" parameter.
     * @param callback
     * @return Callback instance
     */
    private static Callback getMessageCallback(final Callback callback) {
    	Callback msgCallback = null;
    	if (callback != null) {
    		msgCallback = new Callback() {
				@Override
				public void onCallback(Integer result) {
					boolean b = result != null && result.intValue() == Messagebox.OK;
					callback.onCallback(b);
				}
			};
    	}
    	
    	return msgCallback;
    }
    
    /**
     * @param message
     * @param lookup
     * @param editorType
     * @param callback
     * @param desktop
     * @param windowNo
     */
	public static void askForInput(final String message, MLookup lookup, int editorType, final Callback