/*	ServletBridge.java

	Purpose:
		
	Description:
		
	History:
		2013/6/25 by Dennis

	Copyright (C) 2010 Potix Corporation. All Rights Reserved.
*/
package org.zkoss.zssex.ui;

import java.io.Serializable;

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

import org.zkoss.json.JSONObject;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Session;
import org.zkoss.zk.ui.http.WebManager;
import org.zkoss.zk.ui.sys.WebAppCtrl;
import org.zkoss.zkplus.embed.Bridge;
import org.zkoss.zssex.ui.impl.BridgeFix;

/**
 * A abstract util wrapping {@link Bridge} provide easier functionality for a servlet
 * @author dennis
 * @since 3.0.0
 */
public abstract class UpdateBridge implements Serializable {
	private static final long serialVersionUID = -1023233887618980089L;
	
	final protected ServletContext _servletContext;
	final protected HttpServletRequest _request;
	final protected HttpServletResponse _response;
	final protected String _desktopId;
	
	public UpdateBridge(ServletContext servletContext, HttpServletRequest req, HttpServletResponse resp,String desktopId){
		this._servletContext = servletContext;
		this._request = req;
		this._response = resp;
		this._desktopId = desktopId;
	}

	public boolean hasDesktop(){
		return findDesktopIfAny(_servletContext, _request, _desktopId)!=null;
	}
	/**
	 * Process the bridge, find the desktop and call {@link #process(Desktop)}, and return the zk ajax update script
	 */
	public String process (){
		Desktop desktop = findDesktopIfAny(_servletContext, _request, _desktopId);
		
		if(desktop==null){
			throw new IllegalStateException("can't find zk desktop by id "+_desktopId);
		}else{
			BridgeFix zbridge = new BridgeFix();
			zbridge.start(_servletContext, _request, _response, desktop);
			try{
				process(desktop);
				String zkjs = zbridge.getResult();
				return zkjs;
			}catch(Exception e){
				throw new RuntimeException(e.getMessage(),e);
			}finally{
				zbridge.close();
			}
		}
	}
	
	/**
	 * find desktop in a servlet context for a request.
	 * @param ctx
	 * @param request
	 * @param desktopId
	 * @return
	 */
	public static Desktop findDesktopIfAny(ServletContext ctx, HttpServletRequest request, String desktopId){
		final Session sess = WebManager.getSession(ctx, request, false);
		if(sess!=null){
			Desktop desktop = ((WebAppCtrl)sess.getWebApp()).getDesktopCache(sess).getDesktopIfAny(desktopId);
			return desktop;
		}
		return null;
	}
	public static Desktop findDesktop(ServletContext ctx, HttpServletRequest request, String desktopId){
		final Session sess = WebManager.getSession(ctx, request, false);
		if(sess!=null){
			Desktop desktop = ((WebAppCtrl)sess.getWebApp()).getDesktopCache(sess).getDesktop(desktopId);
			return desktop;
		}
		return null;
	}
	
	protected abstract void process(Desktop desktop) throws Exception;
	
}
