/******************************************************************************
 * The contents of this file are subject to the   Compiere License  Version 1.1
 * ("License"); You may not use this file except in compliance with the License
 * You may obtain a copy of the License at http://www.compiere.org/license.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.
 * The Original Code is Compiere ERP & CRM Smart Business Solution. The Initial
 * Developer of the Original Code is Jorg Janke. Portions created by Jorg Janke
 * are Copyright (C) 1999-2005 Jorg Janke.
 * All parts are Copyright (C) 1999-2005 ComPiere, Inc.  All Rights Reserved.
 * Contributor(s): ______________________________________.
 *****************************************************************************/
package com.ampiere.web.servlet;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.ParsePosition;
import java.util.Date;
import java.util.logging.Level;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.ecs.AlignType;
import org.apache.ecs.xhtml.div;
import org.apache.ecs.xhtml.form;
import org.apache.ecs.xhtml.i;
import org.apache.ecs.xhtml.input;
import org.apache.ecs.xhtml.p;
import org.apache.ecs.xhtml.script;
import org.apache.ecs.xhtml.table;
import org.apache.ecs.xhtml.td;
import org.apache.ecs.xhtml.tr;
import org.compiere.framework.Lookup;
import org.compiere.model.MAccountLookup;
import org.compiere.model.MLocationLookup;
import org.compiere.model.MLocatorLookup;
import org.compiere.model.MLookup;
import org.compiere.model.MLookupFactory;
import org.compiere.model.MPAttributeLookup;
import org.compiere.model.MPInstance;
import org.compiere.model.MPInstancePara;
import org.compiere.model.MProcess;
import org.compiere.model.MProcessPara;
import org.compiere.process.ProcessInfo;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.NamePair;
import org.compiere.util.Trx;
import org.compiere.util.WebDoc;
import org.compiere.util.WebEnv;
import org.compiere.util.WebSessionCtx;
import org.compiere.util.WebUtil;

import com.ampiere.util.AmpiereUtil;
import com.ampiere.util.Constants;


/**
 *	HTML Process and Report UI
 *
 *  @author Jorg Janke
 *  @version  $Id: WProcessDialog.java,v 1.1 2010/01/13 11:51:47 clmg Exp $
 */
public class WProcessDialog extends HttpServlet
{
	private static final long serialVersionUID = 3563547961645399121L;

	/**	Logger			*/
	protected CLogger	log = CLogger.getCLogger(getClass());

	/**
	 * Initialize global variables
	 */
	public void init(ServletConfig config)
		throws ServletException
	{
		super.init(config);
		if (!WebEnv.initWeb(config))
			throw new ServletException("WProcessDialog.init");
	}   //  init

	/**
	 *	Process the HTTP Get request.
	 *	Initial Call
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException
	{
		//  Get Session attributes
	  	WebSessionCtx wsc = WebSessionCtx.get(request);
		if (wsc == null)
		{
			WebUtil.createTimeoutPage(request, response, this, null);
			return;
		}
		
		WebDoc doc = null;
		//  Get Parameter: Menu_ID
		int processId = WebUtil.getParameterAsInt(request, "processId");
		int windowNo = WebUtil.getParameterAsInt(request, "windowNo");
		int record_ID = WebUtil.getParameterAsInt(request, "recordId");

		if (processId > 0)
		{
			log.info("doGet - processId=" + processId);
			doc = createParameterPage(windowNo, wsc, processId, record_ID, request);
		}
		else
		{
			String fileName = WebUtil.getParameter(request, "File");
			int AD_PInstance_ID = WebUtil.getParameterAsInt(request, "AD_PInstance_ID");
			log.info("doGet - AD_PInstance_ID=" + AD_PInstance_ID 
				+ ", File=" + fileName);
			String error = streamResult (request, response, AD_PInstance_ID, fileName);
			if (error == null)
				return;
			doc = WebDoc.createWindow(error);
		}
		if (doc == null) {
			doc = WebDoc.createWindow("Process Not Found");
		}

		// Add body onUnload event, close all popup window when unload 
		doc.getBody().setOnUnload("closeMyChildren();");

		//
		WebUtil.createResponse(request, response, this, null, doc, false);
	}   //  doGet

	/**
	 *  Process the HTTP Post request.
	 *  Get Parameters and Process
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException
	{
		//  Get Session attributes
	  	WebSessionCtx wsc = WebSessionCtx.get(request);
		if (wsc == null)
		{
			WebUtil.createTimeoutPage(request, response, this, null);
			return;
		}
		int AD_Process_ID = WebUtil.getParameterAsInt(request, "AD_Process_ID");
		int record_ID = WebUtil.getParameterAsInt(request, "record_ID");
		log.info("doGet - AD_Process_ID=" + AD_Process_ID);
		if (AD_Process_ID == 0)
		{
			WebUtil.createErrorPage(request, response, this, "No Process");
			return;
		}

		WebDoc doc = createProcessPage(request, AD_Process_ID, record_ID);

		// Add body onUnload event, close all popup window when unload 
		doc.getBody().setOnUnload("closeMyChildren();");

		WebUtil.createResponse(request, response, this, null, doc, false);
	}   //  doPost

	
	/**************************************************************************
	 * 	Create Parameter Page
	 *	@param AD_Menu_ID Menu
	 *	@return Page
	 */
	private WebDoc createParameterPage (int windowNo, WebSessionCtx wsc, int AD_Process_ID, int record_ID, HttpServletRequest request)
	{
		MProcess process = MProcess.get(wsc.ctx, AD_Process_ID);
		//	need to check if Role can access
		if (process == null)
		{
			WebDoc doc = WebDoc.createWindow("Process Not Found");
			return doc;
		}

		boolean trl = !Env.isBaseLanguage(wsc.language, "AD_Process");
		if (trl) {
			StringBuffer sql = new StringBuffer();
			sql.append( "SELECT " )
			   .append( "    AD_Process_Trl.NAME, " )
			   .append( "    AD_Process_Trl.DESCRIPTION, " )
			   .append( 			"    AD_Process_Trl.HELP " )
			   .append( "FROM AD_PROCESS, AD_Process_Trl " )
			   .append( "WHERE AD_PROCESS.AD_Process_ID=AD_Process_Trl.AD_Process_ID " )
			   .append( "  AND AD_PROCESS.AD_Process_ID=? " )
			   .append( "  AND AD_Process_Trl.AD_Language=? " );

			PreparedStatement pstmt = null;
			try
			{
				pstmt = DB.prepareStatement (sql.toString(), null);
				pstmt.setInt (1, process.getAD_Process_ID() );
				pstmt.setString (2, wsc.language.getAD_Language());

				ResultSet rs = pstmt.executeQuery ();
				if (rs.next())
				{
					process.setName( rs.getString(1) );
					process.setHelp( rs.getString(2) );
					process.setDescription( rs.getString(3) );
				}
				rs.close ();
				pstmt.close ();
				pstmt = null;
			}
			catch (Exception e)
			{
				log.log(Level.SEVERE, sql.toString(), e);
			}
			try
			{
				if (pstmt != null)
					pstmt.close ();
				pstmt = null;
			}
			catch (Exception e)
			{
				pstmt = null;
			}
		}


		request.setAttribute(Constants.IS_POPUP_WINDOW, Constants.ENABLED);//clmg 2009/02/15
		WebDoc doc = WebDoc.createWindow(process.getName());
		String processName = "process" + process.getAD_Process_ID();

		StringBuffer sb = new StringBuffer();
		sb.append("function processDialogSubmit() {\n")
			.append("var progressObj = document.getElementById('progress000');\n")
	        .append("if (progressObj != null) {\n")
	        .append("    progressObj.style.display='block';\n")
	        .append("}\n")
	        .append("var okObj = document.getElementById('PopupOk');\n")
	        .append("if (okObj != null) {\n")
	        .append("    okObj.disabled = true;\n")
	        .append("}\n")
	        .append("return true;\n")
	        .append("}\n");
		doc.getHead().addElement(new script(sb.toString()));

		// For date picker
		AmpiereUtil.addDatePicker(doc.getHead(), wsc);

//		td center = doc.addWindowCenter(false);
		td tdCenter = doc.addTd();
		div center = (div)new div().setID("body");//clmg 2009/02/15
		tdCenter.addElement(center);//clmg 2009/02/15
		tdCenter.setClass("popupInfoTable");
		if (process.getDescription() != null)
			center.addElement(new p(new i(process.getDescription())));
		if (process.getHelp() != null)
			center.addElement(new p(process.getHelp(), AlignType.LEFT));

		//
		form myForm = new form ("WProcessDialog").setName(processName);
		myForm.setStyle("margin: 0;");
		myForm.setOnSubmit("return processDialogSubmit();");
		myForm.addElement(new input(input.TYPE_HIDDEN, "AD_Process_ID", process.getAD_Process_ID()));
		myForm.addElement(new input(input.TYPE_HIDDEN, "record_ID", record_ID));
		table myTable = new table("0", "0", "2", "100%", null);
		myTable.setID("WProcessDialogParameter");

		//
		String sql = null;
		if (Env.isBaseLanguage( wsc.ctx, "AD_Process_Para"))
			sql = "SELECT p.Name, p.Description, p.Help, "
				+ "p.AD_Reference_ID, p.AD_Process_Para_ID, "
				+ "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, "
				+ "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, "
				+ "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode "
				+ "FROM AD_Process_Para p"
				+ " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) "
				+ "WHERE p.AD_Process_ID=?"		//	1
				+ " AND p.IsActive='Y' "
				+ "ORDER BY SeqNo";
		else
			sql = "SELECT t.Name, t.Description, t.Help, "
				+ "p.AD_Reference_ID, p.AD_Process_Para_ID, "
				+ "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, "
				+ "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, "
				+ "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode "
				+ "FROM AD_Process_Para p"
				+ " INNER JOIN AD_Process_Para_Trl t ON (p.AD_Process_Para_ID=t.AD_Process_Para_ID)"
				+ " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) "
				+ "WHERE p.AD_Process_ID=?"		//	1
				+ " AND t.AD_Language='" + Env.getAD_Language( wsc.ctx) + "'"
				+ " AND p.IsActive='Y' "
				+ "ORDER BY SeqNo";

		//	Create Fields
		try
		{
			PreparedStatement pstmt = DB.prepareStatement(sql, null);
			pstmt.setInt(1, process.getAD_Process_ID());
			ResultSet rs = pstmt.executeQuery();
			Lookup lookup = null;
			while (rs.next())
			{
				boolean retValue = false;
				int displayType = rs.getInt("AD_Reference_ID");
				if (DisplayType.isLookup(displayType))
					retValue = true;
				else if (displayType == DisplayType.Location
					|| displayType == DisplayType.Locator
					|| displayType == DisplayType.Account
					|| displayType == DisplayType.PAttribute)
					retValue = true;

				//  Create Lookup, if not ID
				if (retValue)
				{
					try
					{
						if (DisplayType.isLookup(displayType)){
//							lookup = new MLookup (MLookupFactory.getLookupInfo (
//									wsc.ctx,
//									windowNo,
//									rs.getInt("AD_Process_Para_ID"),
//									rs.getInt("AD_Reference_ID"),
//									Env.getLanguage(wsc.ctx),
//									rs.getString("ColumnName"),
//									rs.getInt("AD_Reference_Value_ID"),
//									false,
//									rs.getString("ValidationCode")
//									),0);
							MLookup mLookup = new MLookup(wsc.ctx, windowNo, rs.getInt("AD_Reference_ID"));
							lookup= mLookup.initialize(MLookupFactory.getLookupInfo (
									wsc.ctx,
									windowNo,
									rs.getInt("AD_Reference_ID"),
									rs.getInt("AD_Process_Para_ID"),
									Env.getLanguage(wsc.ctx),
									rs.getString("ColumnName"),
									rs.getInt("AD_Reference_Value_ID"),
									false,
									rs.getString("ValidationCode")
									));
						}
						else if (displayType == DisplayType.Location)   //  not cached
						{
							MLocationLookup ml = new MLocationLookup (wsc.ctx, windowNo);
							lookup = ml;
						}
						else if (displayType == DisplayType.Locator)
						{
							MLocatorLookup ml = new MLocatorLookup (wsc.ctx, windowNo);
							ml.setOnly_Warehouse_ID(AmpiereUtil.getOnly_Warehouse_ID(wsc.ctx, windowNo));
							lookup = ml;
						}
						else if (displayType == DisplayType.Account)    //  not cached
						{
							MAccountLookup ma = new MAccountLookup (wsc.ctx, windowNo);
							lookup = ma;
						}
						else if (displayType == DisplayType.PAttribute)    //  not cached
						{
							MPAttributeLookup pa = new MPAttributeLookup (wsc.ctx, windowNo);
							lookup = pa;
						}
						//
						if (lookup != null)
							lookup.loadComplete();
					}
					catch (Exception e)     //  Cannot create Lookup
					{
						CLogger.get().log(Level.SEVERE, "No LookupInfo for " + rs.getString("ColumnName"), e);
					}
				}
				
				/**
				int displayLength = 0;
				if ( rs.getInt("AD_Reference_ID") == DisplayType.Date ) {
					displayLength = 10*16;
				} else if ( rs.getInt("AD_Reference_ID") == DisplayType.DateTime ) {
					displayLength = 20*16;
				} else if ( rs.getInt("AD_Reference_ID") == DisplayType.Time ) {
					displayLength = 10*16;
				} else {
					displayLength = rs.getInt("FieldLength")*16;
				}
				**/
				
				int displayLength = 20*12;
				
				WebField wField = new WebField (
						windowNo,
						wsc,
						rs.getString("ColumnName"),
						rs.getString("Name"),
						rs.getString("Description"),
						//	no display length
						rs.getInt("AD_Reference_ID"),
						rs.getInt("FieldLength"),
						displayLength,
						false,
						// 	not r/o, ., not error, not dependent
						false,
						rs.getString("IsMandatory").equals("Y"),
						false,
						false,
						false,
						process.getAD_Process_ID(),
						false
						);

				td toField = null;
				if (rs.getString("IsRange").equals("Y")) {
					WebField wFieldTo = new WebField (
							windowNo,
							wsc,
							rs.getString("ColumnName") + "To",
							rs.getString("Name"),
							rs.getString("Description"),
							rs.getInt("AD_Reference_ID"),
							rs.getInt("FieldLength"),
							displayLength,
							false,
							false,
							rs.getString("IsMandatory").equals("Y"),
							false,
							false,
							false,
							process.getAD_Process_ID(),
							false
							);
					toField = wFieldTo.getField(
							lookup,
							createDefault(
									wsc,
									rs.getString("DefaultValue2"),
									rs.getInt("AD_Reference_ID")
									),
							rs.getInt("AD_Process_Para_ID")
							);
				} else {
					toField = new td(WebEnv.NBSP);
				}

				//	Add to Table
				myTable.addElement(new tr()
					.addElement(wField.getLabel().setAlign(AlignType.RIGHT))//2009/02/15
					.addElement(wField.getField(
							lookup,
							createDefault(
									wsc,
									rs.getString("DefaultValue"),
									rs.getInt("AD_Reference_ID")
									),
							rs.getInt("AD_Process_Para_ID")
							)
					)
					.addElement(toField));

			}
			rs.close();
			pstmt.close();
		}
		catch(SQLException e)
		{
			log.log(Level.SEVERE, sql, e);
		}
		
		//	プロセスを開始しますか？//clmg 2009/03/06
		td confirmTd = new td();
		confirmTd.setColSpan(3);
		confirmTd.setTagText("プロセスを開始しますか？");
		myTable.addElement(new tr().addElement(confirmTd));

		//	Submit
		div bottomDiv = (div)new div().setClass("bottomMenuRight");//clmg 2009/02/15
		table bottomTable = new table();//clmg 2009/02/15
		bottomDiv.addElement(bottomTable);//clmg 2009/02/15
		bottomTable.addElement(new tr().addElement(AmpiereUtil.createButtons(wsc.ctx, true)));

		myForm.addElement(myTable);
		myForm.addElement(bottomDiv);//clmg 2009/02/15

		center.addElement(myForm);//clmg 2009/02/15

		return doc;
	}	//	createParameterPage

	
	/**************************************************************************
	 * 	Create Parocess Page
	 *	@param AD_Process_ID Process
	 *	@return Page
	 */
	private WebDoc createProcessPage (HttpServletRequest request, int AD_Process_ID, int record_ID)
	{
	  	WebSessionCtx wsc = WebSessionCtx.get (request);
		MProcess process = MProcess.get (wsc.ctx, AD_Process_ID);
		//	need to check if Role can access
		if (process == null)
		{
			WebDoc doc = WebDoc.createWindow("Process Not Found");
			return doc;
		}

		WebDoc doc = WebDoc.createWindow(process.getName());
		
		// For date picker
		AmpiereUtil.addDatePicker(doc.getHead(), wsc);

		td center = doc.addWindowCenter(false);
		center.setClass("popupInfoTable");
		if (process.getDescription() != null)
			center.addElement(new p(new i(process.getDescription())));
		if (process.getHelp() != null)
			center.addElement(new p(process.getHelp(), AlignType.LEFT));
		
		//	Create Process Instance
		MPInstance pInstance = fillParameter (request, process);

		ProcessInfo pi = new ProcessInfo (process.getName(), process.getAD_Process_ID());
//		pi.setAD_User_ID(Env.getAD_User_ID(wsc.ctx));
//		pi.setAD_Client_ID(Env.getAD_Client_ID(wsc.ctx));
		pi.setAD_User_ID(wsc.ctx.getAD_User_ID());
		pi.setAD_Client_ID(wsc.ctx.getAD_Client_ID());
		pi.setAD_PInstance_ID(pInstance.getAD_PInstance_ID());
		pi.setRecord_ID(record_ID);
		
		//	Start
		boolean processOK = false;
		if (process.isJavaProcess())
		{
			Trx trx = Trx.get(Trx.createTrxName("WebPrc"), true);
			try
			{
				processOK = process.processIt(pi, trx);
				trx.commit();
				trx.close();
			}
			catch (Throwable t)
			{
				trx.rollback();
				trx.close();
			}
			if (!processOK || pi.isError())
			{
				center.addElement(new p("Error:" + pi.getSummary(), 
					AlignType.LEFT).setClass("Cerror"));
				processOK = false;
			}
//			center.addElement(new p().addElement(pi.getSummary())); //clmg 2009/03/23
			center.addElement(pi.getLogInfo(true));
		}

		//	Info
		p p = new p();
		p.addElement(Msg.translate(wsc.ctx, "ProcessOK") );
		center.addElement(p);

		//	Submit
		table bottomTable = new table("0", "0", "0", "102%", "topLine");
		bottomTable.addElement(new tr().addElement(AmpiereUtil.createButtons(wsc.ctx, false)));
		center.addElement(bottomTable);

		if ( process.isReport() ) {
			// For print popup window
			StringBuffer sb = new StringBuffer();
			sb.append( "openPrintWindow(" )
			  .append( "\"/compiere/ampiere/WPrintReport\"," )
			  .append( "\"PrintReport\" );" );
			doc.getHead().addElement(new script( sb.toString() ));
	
//			Env.setContext( wsc.ctx, "AD_Process_ID", AD_Process_ID );
//			Env.setContext( wsc.ctx, "AD_PInstance_ID", pInstance.getAD_PInstance_ID() );
			wsc.ctx.setContext( "AD_Process_ID", AD_Process_ID );
			wsc.ctx.setContext( "AD_PInstance_ID", pInstance.getAD_PInstance_ID() );
		}

		return doc;
	}	//	createProcessPage
	
	/**
	 * 	Fill Parameter
	 *	@param request request
	 *	@param process process
	 */
	private MPInstance fillParameter(HttpServletRequest request, MProcess process)
	{
        WebSessionCtx wsc = WebSessionCtx.get (request);
		MPInstance pInstance = new MPInstance (process, 0);
		//
		MPInstancePara[] iParams = pInstance.getParameters();
		for (int pi = 0; pi < iParams.length; pi++)
		{
			MPInstancePara iPara = iParams[pi];
			String key = iPara.getParameterName();
			MProcessPara pPara = process.getParameter(key);
			if (pPara == null)
			{
				log.log(Level.SEVERE, "Parameter not found: " + key);
				continue;
			}
			
			String valueString = WebUtil.getParameter (request, key);
			String valueStringTo = "";
			if( pPara.isRange() ) {
				valueStringTo = WebUtil.getParameter (request, key+"To");
			}
			/**
			 *  TODO
			 */
			if( key.endsWith( "ID") && "-1".equals( valueString )){
				valueString = "0";
			}
			
			log.fine("fillParameter - " + key + " = " + valueString);
			Object value = valueString;
			Object valueTo = valueStringTo;

			if (valueString != null && valueString.length() == 0)
				value = null;
			if (valueStringTo != null && valueStringTo.length() == 0)
				valueTo = null;
			//	No Value
			if (value == null && valueTo == null)
			{
			//	if (pPara.isMandatory())
			//		log.log(Level.WARNING,"fillParameter - " + key 
			//			+ " - empty - mandatory!");
			}
			else
			{
				//	Convert to Type
				try
				{
					if(value!=null){
						if (DisplayType.isNumeric(pPara.getAD_Reference_ID()) 
							|| DisplayType.isID(pPara.getAD_Reference_ID()))
						{
							BigDecimal bd = null;
							if ( value instanceof BigDecimal )
								bd = (BigDecimal)value;
							else if (value instanceof Integer)
								bd = new BigDecimal (((Integer)value).intValue());
							else
								bd = new BigDecimal (value.toString());
							iPara.setP_Number(bd);
							if ( DisplayType.isID(pPara.getAD_Reference_ID())){
								NamePair obj = pPara.getLookup().get(bd);
								iPara.setInfo( obj.getName() );
							} else {
								iPara.setInfo( bd.toString() );
							}
							log.fine("fillParameter - " + key
									+ " = " + valueString + " (=" + bd + "=)");
						}
						else if (DisplayType.isDate(pPara.getAD_Reference_ID()))
						{
                            Date date = null;
                            if (value instanceof Timestamp)
                                date = wsc.dateTimeFormat.parse(value.toString(),new ParsePosition(0));
                            else
                                date = wsc.dateFormat.parse(value.toString(),new ParsePosition(0));
                            iPara.setP_Date((Timestamp)date);
                            iPara.setInfo( value.toString() );
                            log.fine("fillParameter - " + key
                                + " = " + valueString + " (=" + date + "=)");
						}
						else
						{
							iPara.setP_String(value.toString());
							iPara.setInfo( value.toString() );
						}
					}

					if(valueTo!=null){
						if (DisplayType.isNumeric(pPara.getAD_Reference_ID()) 
							|| DisplayType.isID(pPara.getAD_Reference_ID()))
						{
							BigDecimal bd = null;
							if ( value instanceof BigDecimal )
								bd = (BigDecimal)valueTo;
							else if (value instanceof Integer)
								bd = new BigDecimal (((Integer)valueTo).intValue());
							else
								bd = new BigDecimal (valueTo.toString());
							iPara.setP_Number_To(bd);
							if ( DisplayType.isID(pPara.getAD_Reference_ID())){
								NamePair obj = pPara.getLookup().get(bd);
								iPara.setInfo_To( obj.getName() );
							} else {
								iPara.setInfo_To( bd.toString() );
							}
							log.fine("fillParameter - " + key
									+ " = " + valueStringTo + " (=" + bd + "=)");
						}
						else if (DisplayType.isDate(pPara.getAD_Reference_ID()))
						{
                            Date date = null;
                            if (valueTo instanceof Timestamp)
                                date = wsc.dateTimeFormat.parse(valueTo.toString(),new ParsePosition(0));
                            else
                                date = wsc.dateFormat.parse(valueTo.toString(),new ParsePosition(0));
                            iPara.setP_Date((Timestamp)date);
                            iPara.setInfo( valueTo.toString() );
                            log.fine("fillParameter - " + key
                                + " = " + valueString + " (=" + date + "=)");
						}
						else
						{
							iPara.setP_String_To(valueTo.toString());
							iPara.setInfo_To( valueTo.toString() );
						}
					}
//

					iPara.save();
				}
				catch (Exception e)
				{
					log.warning("fillParameter - " + key
						+ " = " + valueString + " (" + value
						+ ") " + value.getClass().getName()
						+ " - " + e.getLocalizedMessage());
				}
			}	//	not null
		}	//	instance parameter loop
		
		return pInstance;
	}	//	fillParameter

	/**
	 * 	Stream Result
	 *	@param request request
	 *	@param response response
	 *	@param AD_PInstance_ID instance id
	 *	@param fileName file to stream
	 *	@return message
	 */
	private String streamResult (HttpServletRequest request, HttpServletResponse response,
		int AD_PInstance_ID, String fileName)
	{
		if (AD_PInstance_ID == 0)
			return "Your process not found";
	  	WebSessionCtx wsc = WebSessionCtx.get (request);
		Object value = wsc.ctx.get("AD_PInstance_ID=" + AD_PInstance_ID);
		if (value == null || !value.equals("ok"))
			return "Process Instance not found";
		//
		if (fileName == null || fileName.length() == 0)
			return "No Process Result";
		File file = new File (fileName);
		if (!file.exists())
			return "Process Result not found: " + file;
		//	OK
		return WebUtil.streamFile(response, file);
	}	//	streamResult

	/**
	 *	Create Default Object type.
	 *  @param value string
	 *  @return type dependent converted object
	 */
	private Object createDefault ( WebSessionCtx wsc, String value, int referenceId )
	{
		//	true NULL
		if (value == null || value.toString().length() == 0)
			return null;

		if ( "@#Date@".equals( value ) ) {
//			return Env.getContextAsDate( wsc.ctx,"#Date" ) ;
			return wsc.ctx.getContextAsTime( "#Date" ) ;
		} else if ( "Y".equals( value ) || "N".equals( value ) ) {
			return "Y".equals( value );
		} else if ( value.startsWith( "@" ) ) {
//			String id = Env.getContext( wsc.ctx, value.substring(1,value.length()-1) );
			String id = wsc.ctx.getContext(value.substring(1,value.length()-1) );
			if ( id == null || id.length() == 0 )
				return new Integer( 0 );
			else
				return new Integer( id );
		} else if ( referenceId == DisplayType.Locator || referenceId == DisplayType.Quantity  ) {
			return new Integer( value );
		} else if ( referenceId == DisplayType.Number || referenceId == DisplayType.Amount ) {
			return new BigDecimal( value );
		} else {
			return value;
		}
	}	//	createDefault
}   //  WProcess
