/**
 * 
 * This software is licensed under the GNU General Public License v3 or later.
 * 
 * It 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 3 of the License, or 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, see <http://www.gnu.org/licenses/>.
 * 
 */

package com.cloud.consoleproxy;


import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPOutputStream;

import org.apache.log4j.Logger;

import com.cloud.console.AuthenticationException;
import com.cloud.console.ConsoleCanvas;
import com.cloud.console.ConsoleCanvas2;
import com.cloud.console.ITileScanListener;
import com.cloud.console.Region;
import com.cloud.console.RfbProto;
import com.cloud.console.RfbProtoAdapter;
import com.cloud.console.RfbViewer;
import com.cloud.console.TileInfo;
import com.cloud.console.TileTracker;

public class ConsoleProxyViewer implements java.lang.Runnable, RfbViewer, RfbProtoAdapter, ITileScanListener {
	private static final Logger s_logger = Logger.getLogger(ConsoleProxyViewer.class);
	
	public final static int STATUS_ERROR = -1;
	public final static int STATUS_UNINITIALIZED = 0;
	public final static int STATUS_CONNECTING = 1;
	public final static int STATUS_INITIALIZING = 2;
	public final static int STATUS_NORMAL_OPERATION = 3;
	public final static int STATUS_AUTHENTICATION_FAILURE = 100;
	
	public final static int SHIFT_KEY_MASK = 64;
	public final static int CTRL_KEY_MASK = 128;
	public final static int META_KEY_MASK = 256;
	public final static int ALT_KEY_MASK = 512;
	
	int id = getNextId();
	boolean compressServerMessage = false;
	long createTime = System.currentTimeMillis();
	long lastUsedTime = System.currentTimeMillis();
	int status;
	boolean dropMe = false;
	boolean viewerInReuse = false; 
	
	String host;
	int port;
	String tag = "";
	
	RfbProto rfb;
	Thread rfbThread;
	OutputStream clientStream;
	String clientStreamInfo;
	String passwordParam;
	
	ViewerOptions options;
	Frame vncFrame;
	ConsoleCanvas vc;
	Container vncContainer;
	
	boolean ajaxViewer = false;
	long ajaxSessionId = 0;
	TileTracker tracker;
	Object tileDirtyEvent;
	boolean dirtyFlag = false;
	boolean justCreated = true;
	AjaxFIFOImageCache ajaxImageCache = new AjaxFIFOImageCache(2);
	
	String cursorUpdatesDef;
	String eightBitColorsDef;
	
	int deferScreenUpdates;
	int deferCursorUpdates;
	int deferUpdateRequests;
	
	int[] encodingsSaved;
	int nEncodingsSaved;

	boolean framebufferResized = false;
	int resizedFramebufferWidth;
	int resizedFramebufferHeight;
	
	boolean cursorMoved = false;
	int lastCursorPosX;
	int lastCursorPosY;
	
	boolean cursorShapeChanged = false;
	int lastCursorShapeEncodingType;
	int lastCursorShapeHotX;
	int lastCursorShapeHotY;
	int lastCursorShapeWidth;
	int lastCursorShapeHeight;
	byte[] lastCursorShapeData;
	
	static int id_count = 1;
	synchronized static int getNextId() {
		return id_count++;
	}

	public void init() {
		initProxy();
	}
	
	private void initProxy() {
		options = new ViewerOptions();
		options.viewOnly = true;

		cursorUpdatesDef = null;
		eightBitColorsDef = null;
		
		tracker = new TileTracker();
		tracker.initTracking(64, 64, 800, 600);

		if(rfbThread != null) {
			if(rfbThread.isAlive()) {
				dropMe = true;
				viewerInReuse = true;
				rfb.close();
				
				try {
					rfbThread.join();
				} catch (InterruptedException e) {
					s_logger.warn("InterruptedException while waiting for RFB thread to exit");
				}
				viewerInReuse = false;
			}
		}
		
		dropMe = false;
		rfbThread = new Thread(this);
		rfbThread.setName("RFB Thread " + rfbThread.getId() + " >" + host + ":"
				+ port);
		rfbThread.start();

		tileDirtyEvent = new Object();
	}
	
	public synchronized boolean justCreated() {
		if(justCreated) {
			justCreated = false;
			return true;
		}
		return false;
	}
	
	public boolean isDropped() {
		return dropMe;
	}
	
	public void run() {
		createCanvas(0, 0);

		int retries = 0;
		while (!dropMe) {
			try {
				s_logger.info("Connecting to VNC server");
				status = STATUS_CONNECTING;
				connectAndAuthenticate();
				retries = 0; // reset the retry count
				status = STATUS_INITIALIZING;
				doProtocolInitialisation();
				vc.rfb = rfb;
				vc.setPixelFormat();

				// if we have a client current connected, when we have reconnected to the server and
				// received a new ServerInit info (in doProtocolInitialisation()), we will
				// convert it into frame buffer size change to make sure following on updates
				// don't fall out of range
				//
				if(clientStream != null) {
					// 128 bytes will be enough for this single PDU
					s_logger.info("Send init framebuffer size (" + rfb.framebufferWidth + ", " + rfb.framebufferHeight + ")");
					
					ByteArrayOutputStream bos = new ByteArrayOutputStream(128);
					try {
						vc.encodeFramebufferResize(rfb.framebufferWidth, rfb.framebufferHeight, bos);
					} catch(IOException e) {
					}
					writeToClientStream(bos.toByteArray());
				}
				
				vc.rfb.writeFramebufferUpdateRequest(0, 0,
						vc.rfb.framebufferWidth, vc.rfb.framebufferHeight,
						true);
				status = STATUS_NORMAL_OPERATION;
				vc.processNormalProtocol();
			} catch (AuthenticationException e) {
				status = STATUS_AUTHENTICATION_FAILURE;
				String msg = e.getMessage();
				s_logger.warn("Authentication exception, msg: " + msg + "sid: " + this.passwordParam);
			} catch (Exception e) {
				status = STATUS_ERROR;
				if(s_logger.isDebugEnabled())
					s_logger.debug("Exception : ", e);
			} finally {
				// String oldName = Thread.currentThread().getName();
				encodingsSaved = null;
				nEncodingsSaved = 0;
				
				s_logger.info("Close current RFB");
				synchronized (this) {
					if (rfb != null) {
						rfb.close();
					}
				}
			}
			if (dropMe) {
				break;
			}
			if (status == STATUS_AUTHENTICATION_FAILURE) {
				break;
			} else {
				retries++;
				if(retries > ConsoleProxy.reconnectMaxRetry) {
					s_logger.info("Exception caught, retry has reached to maximum : " + retries + ", will give up and disconnect client");
					break;
				}
				
				s_logger.info("Exception caught, retrying in 1 second, current retry:" + retries);
				
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// ignored
				}
			}
		}
		
		// make sure we remove it from the management map upon main thread termination
		dropMe = true;
		
		// if we are reusing the viewer object, we shouldn't remove it from the map
		// this can also prevent deadlock in initProxy() while initProxy tries to join
		// the thread, as initProxy() is called with ConsoleProxy.connectionMap being locked
		// while CoonsoleProxy.removeViewer() here will attempt to lock it from another thread
		if(!viewerInReuse)		
			ConsoleProxy.removeViewer(this);
		s_logger.info("RFB thread terminating");
	}
	
	void connectAndAuthenticate() throws Exception {
		s_logger.info("Initializing...");
		
		s_logger.info("Ensure ip route towards host " + host);
		ConsoleProxy.ensureRoute(host);		
		
		s_logger.info("Connecting to " + host + ", port " + port + "...");
		rfb = new RfbProto(host, port, this);
		s_logger.info("Connected to server");

		rfb.readVersionMsg();
		s_logger.info("RFB server supports protocol version "
				+ rfb.serverMajor + "." + rfb.serverMinor);

		rfb.writeVersionMsg();
		s_logger.info("Using RFB protocol version " + rfb.clientMajor
				+ "." + rfb.clientMinor);

		int secType = rfb.negotiateSecurity();
		int authType;
		if (secType == RfbProto.SecTypeTight) {
			s_logger.info("Enabling TightVNC protocol extensions");
			rfb.initCapabilities();
			rfb.setupTunneling();
			authType = rfb.negotiateAuthenticationTight();
		} else {
			authType = secType;
		}

		switch (authType) {
		case RfbProto.AuthNone:
			s_logger.info("No authentication needed");
			rfb.authenticateNone();
			break;
		case RfbProto.AuthVNC:
			s_logger.info("Performing standard VNC authentication");
			if (passwordParam != null) {
				rfb.authenticateVNC(passwordParam);
			} else {
				throw new AuthenticationException("Bad password");
			}
			break;
		default:
			throw new Exception("Unknown authentication scheme " + authType);
		}
	}
	
	static void authenticationExternally(String host, String port, String tag, String sid, String ticket) throws AuthenticationException {
/*		
		if(ConsoleProxy.management_host != null) {
			try {
				boolean success = false;
				URL url = new URL(ConsoleProxy.management_host + "/console?cmd=auth&vm=" + getTag() + "&sid=" + passwordParam);
				
				URLConnection conn = url.openConnection();
				
				// setting TIMEOUTs to avoid possible waiting until death situations
				conn.setConnectTimeout(5000);
				conn.setReadTimeout(5000);
				
		        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
		        String inputLine;
		        if ((inputLine = in.readLine()) != null) { 
		            if(inputLine.equals("success"))
		            	success = true;
		        }
		        in.close();
		        
		        if(!success) {
		        	if(s_logger.isInfoEnabled())
		        		s_logger.info("External authenticator failed authencation request for vm " + getTag() + " with sid " + passwordParam);
		        	
					throw new AuthenticationException("Unable to contact external authentication source " + ConsoleProxy.management_host);
		        }
			} catch (MalformedURLException e) {
				s_logger.error("Unexpected exception " + e.getMessage(), e);
			} catch(IOException e) {
				s_logger.error("Unable to contact external authentication source due to " + e.getMessage(), e);
				throw new AuthenticationException("Unable to contact external authentication source " + ConsoleProxy.management_host);
			}
		} else {
			s_logger.warn("No external authentication source being setup.");
		}
*/
		if(!ConsoleProxy.authenticateConsoleAccess(host, port, tag, sid, ticket)) {
    		s_logger.warn("External authenticator failed authencation request for vm " + tag + " with sid " + sid);
        	
			throw new AuthenticationException("External authenticator failed request for vm " + tag + " with sid " + sid);
		}
	}
	
	void doProtocolInitialisation() throws IOException {
		rfb.writeClientInit();
		rfb.readServerInit();
		setEncodings();
	}
	
	void setEncodings() {
		setEncodings(false);
	}
	
	void setEncodings(boolean autoSelectOnly) {
		if (options == null || rfb == null || !rfb.inNormalProtocol)
			return;

		int preferredEncoding = options.preferredEncoding;
		if (preferredEncoding == -1) {
			long kbitsPerSecond = rfb.kbitsPerSecond();
			if (nEncodingsSaved < 1) {
				// Choose Tight or ZRLE encoding for the very first update.
				// Logger.log(Logger.INFO, "Using Tight/ZRLE encodings");
				preferredEncoding = RfbProto.EncodingTight;
			} else if (kbitsPerSecond > 2000
					&& encodingsSaved[0] != RfbProto.EncodingHextile) {
				// Switch to Hextile if the connection speed is above 2Mbps.
				s_logger.info("Throughput " + kbitsPerSecond
						+ " kbit/s - changing to Hextile encoding");
				preferredEncoding = RfbProto.EncodingHextile;
			} else if (kbitsPerSecond < 1000
					&& encodingsSaved[0] != RfbProto.EncodingTight) {
				// Switch to Tight/ZRLE if the connection speed is below 1Mbps.
				s_logger.info("Throughput " + kbitsPerSecond
						+ " kbit/s - changing to Tight/ZRLE encodings");
				preferredEncoding = RfbProto.EncodingTight;
			} else {
				// Don't change the encoder.
				if (autoSelectOnly)
					return;
				preferredEncoding = encodingsSaved[0];
			}
		} else {
			// Auto encoder selection is not enabled.
			if (autoSelectOnly)
				return;
		}

		int[] encodings = new int[20];
		int nEncodings = 0;

		encodings[nEncodings++] = preferredEncoding;
		if (options.useCopyRect) {
			encodings[nEncodings++] = RfbProto.EncodingCopyRect;
		}

		if (preferredEncoding != RfbProto.EncodingTight) {
			encodings[nEncodings++] = RfbProto.EncodingTight;
		}
		if (preferredEncoding != RfbProto.EncodingZRLE) {
			encodings[nEncodings++] = RfbProto.EncodingZRLE;
		}
		if (preferredEncoding != RfbProto.EncodingHextile) {
			encodings[nEncodings++] = RfbProto.EncodingHextile;
		}
		if (preferredEncoding != RfbProto.EncodingZlib) {
			encodings[nEncodings++] = RfbProto.EncodingZlib;
		}
		if (preferredEncoding != RfbProto.EncodingCoRRE) {
			encodings[nEncodings++] = RfbProto.EncodingCoRRE;
		}
		if (preferredEncoding != RfbProto.EncodingRRE) {
			encodings[nEncodings++] = RfbProto.EncodingRRE;
		}

		if (options.compressLevel >= 0 && options.compressLevel <= 9) {
			encodings[nEncodings++] = RfbProto.EncodingCompressLevel0
					+ options.compressLevel;
		}
		if (options.jpegQuality >= 0 && options.jpegQuality <= 9) {
			encodings[nEncodings++] = RfbProto.EncodingQualityLevel0
					+ options.jpegQuality;
		}

		if (options.requestCursorUpdates) {
			encodings[nEncodings++] = RfbProto.EncodingXCursor;
			encodings[nEncodings++] = RfbProto.EncodingRichCursor;
			if (!options.ignoreCursorUpdates)
				encodings[nEncodings++] = RfbProto.EncodingPointerPos;
		}

		encodings[nEncodings++] = RfbProto.EncodingLastRect;
		encodings[nEncodings++] = RfbProto.EncodingNewFBSize;

		boolean encodingsWereChanged = false;
		if (nEncodings != nEncodingsSaved) {
			encodingsWereChanged = true;
		} else {
			for (int i = 0; i < nEncodings; i++) {
				if (encodings[i] != encodingsSaved[i]) {
					encodingsWereChanged = true;
					break;
				}
			}
		}

		if (encodingsWereChanged) {
			try {
				rfb.writeSetEncodings(encodings, nEncodings);
				if (vc != null) {
					vc.softCursorFree();
				}
			} catch (Exception e) {
				s_logger.error(e.toString(), e);
			}
			encodingsSaved = encodings;
			nEncodingsSaved = nEncodings;
		}
	}

	protected void startRecording() throws IOException {
	}
	
	protected void stopRecording() throws IOException {
	}
	
	void createCanvas(int maxWidth, int maxHeight) {
		vc = new ConsoleCanvas2(this, maxWidth, maxHeight);
		
	    if (!options.viewOnly)
	        vc.enableInput(true);
	}
	
	synchronized void writeToClientStream(byte[] bs) {
		// writeToClientStream swallows exceptions to make sure problems writing
		// to client stream do not impact the main loop
		if (clientStream != null) {
			try {
				lastUsedTime = System.currentTimeMillis();
				synchronized (clientStream) {
					clientStream.write(bs);
					clientStream.flush();
				}
			} catch (IOException e) {
				if(s_logger.isDebugEnabled()) {
					s_logger.debug("Writing to client stream failed, reason: " + e.getMessage());
				}
				try {
					clientStream.close();
				} catch (IOException ioe){
					// ignore
				}
				clientStream = null;
				clientStreamInfo = null;
			  }
		}
	}
	
	//
	// Implement RfbViewer interface
	//
	public boolean isProxy() {
		return true;
	}
	
	public boolean hasClientConnection() {
		// always return false if the viewer is AJAX viewer
		if(ajaxViewer)
			return false;
		
		return clientStream != null;
	}
	
	public RfbProto getRfb() {
		return rfb;
	}
	
	public Dimension getScreenSize() {
		return (new Frame()).getToolkit().getScreenSize();
		// return vncFrame.getToolkit().getScreenSize();
	}
	
	public Dimension getFrameSize() {
		// return vncFrame.getSize();
		return getScreenSize();
	}
	
	public int getScalingFactor() {
		return options.scalingFactor;
	}
	
	public int getCursorScaleFactor() {
		return options.scaleCursor;
	}
	
	public boolean ignoreCursorUpdate() {
		return options.ignoreCursorUpdates;
	}
	
	public int getDeferCursorUpdateTimeout() {
		return 0;
		// return deferCursorUpdates; 
	}
	
	public int getDeferScreenUpdateTimeout() {
		return 0;
		// return deferScreenUpdates;
	}
	
	public int getDeferUpdateRequestTimeout() {
		return 0;
		//return deferUpdateRequests;
	}
	
	public int setPixelFormat(RfbProto rfb) throws IOException {
		if (options.eightBitColors) {
	        rfb.writeSetPixelFormat(8, 8, false, true, 7, 7, 3, 0, 3, 6);
	        return 1;
		} else {
			rfb.writeSetPixelFormat(32, 24, false, true, 255, 255, 255, 16, 8, 0);
			return 4;
		}
	}
	
	public void onInputEnabled(boolean enable) {
		// do nothing in proxy viewer
	}
	
	public void onFramebufferSizeChange(int w, int h) {
		tracker.resize(vc.scaledWidth, vc.scaledHeight);

		synchronized(this) {
			framebufferResized = true;
			resizedFramebufferWidth = w;
			resizedFramebufferHeight = h;
		}
		
		signalTileDirtyEvent();
	}
	
	public void onFramebufferUpdate(int x, int y, int w, int h) {
		if(s_logger.isTraceEnabled())
			s_logger.trace("Frame buffer update {" + x + "," + y + "," + w + "," + h + "}");
		tracker.invalidate(new Rectangle(x, y, w, h));
		
		signalTileDirtyEvent();
	}
	
	public void onFramebufferCursorMove(int x, int y) {
		synchronized(this) {
			cursorMoved = true;
			lastCursorPosX = x;
			lastCursorPosY = y;
		}
		
		signalTileDirtyEvent();
	}
	
	public void onFramebufferCursorShapeChange(int encodingType,
		    int xhot, int yhot, int width, int height, byte[] cursorData) {

		synchronized(this) {
			cursorShapeChanged = true;
			
			lastCursorShapeEncodingType = encodingType;
			lastCursorShapeHotX = xhot;
			lastCursorShapeHotY = yhot;
			lastCursorShapeWidth = width;
			lastCursorShapeHeight = height;
			lastCursorShapeData = cursorData;
		}
		
		signalTileDirtyEvent();
	}
	
	public void onDesktopResize() {
		if(vncFrame != null)
			vncFrame.pack();
	}
	
	public void onFrameResize(Dimension newSize) {
		if(vncFrame != null)
			vncFrame.setSize(newSize);
	}
	
	public void onDisconnectMessage() {
		// do nothing in viewer mode
	}
	
	public void onBellMessage() {
		Toolkit.getDefaultToolkit().beep();
	}
	
	public void onPreProtocolProcess(byte[] bs) throws IOException {
		
		if(s_logger.isTraceEnabled())
			s_logger.trace("Send " + (bs != null ? bs.length  : 0) + " bytes (original) to client");

		if (!ajaxViewer && bs != null && clientStream != null) {
			if(s_logger.isInfoEnabled())
				s_logger.info("getSplit got " + bs.length + " bytes");
			if (compressServerMessage && bs.length > 10000) {
				ByteArrayOutputStream bos = new ByteArrayOutputStream(256000);
				GZIPOutputStream gos = new GZIPOutputStream(bos, 65536);
				gos.write(bs);
				gos.finish();
				byte[] nbs = bos.toByteArray();
				gos.close();
				int n = nbs.length;
				
				if(s_logger.isInfoEnabled())
					s_logger.info("Compressed " + bs.length + "=>" + n);
				
				byte[] b = new byte[6];
				b[0] = (byte) 250;
				b[1] = 2;
				b[2] = (byte) ((n >> 24) & 0xff);
				b[3] = (byte) ((n >> 16) & 0xff);
				b[4] = (byte) ((n >> 8) & 0xff);
				b[5] = (byte) (n & 0xff);
				
				// make sure two seperated writes completed atomically
				synchronized(clientStream) {
					writeToClientStream(b);
					writeToClientStream(nbs);
				}
			} else {
				if(s_logger.isInfoEnabled())
					s_logger.info("Send uncompressed " + bs.length + " bytes to client");
				
				writeToClientStream(bs);
			}
		} else {
			if(s_logger.isTraceEnabled())
				s_logger.trace("Client is not connected, ignore forwarding " + (bs != null ? bs.length : 0) + " bytes to client");
		}
		
	    rfb.sis.setSplit();
	}
	
	public boolean onPostFrameBufferUpdateProcess(boolean cursorPosReceived) throws IOException {
		boolean fullUpdateNeeded = false;
		
		// Defer framebuffer update request if necessary. But wake up
		// immediately on keyboard or mouse event. Also, don't sleep
		// if there is some data to receive, or if the last update
		// included a PointerPos message.
		if (deferUpdateRequests > 0 && rfb.is.available() == 0 && !cursorPosReceived) {
		  synchronized(vc.rfb) {
		    try {
		      vc.rfb.wait(deferUpdateRequests);
		    } catch (InterruptedException e) {
		    }
		  }
		}

		// Before requesting framebuffer update, check if the pixel
		// format should be changed. If it should, request full update
		// instead of an incremental one.
		if (options.eightBitColors != (vc.bytesPixel == 1)) {
			vc.setPixelFormat();
			fullUpdateNeeded = true;
		}

		return fullUpdateNeeded;
	}
	
	public void onProtocolProcessException(IOException e) {
		byte[] bs = new byte[2];
		bs[0] = (byte)250;
		bs[1] = 1;
		writeToClientStream(bs);
	}
	
	public Socket createConnection(String host, int port) throws IOException {
		Socket sock = new Socket();
		sock.setSoTimeout(ConsoleProxy.readTimeoutSeconds*1000);
		sock.setKeepAlive(true);
		sock.connect(new InetSocketAddress(host, port), 30000);
		return sock;
	}
	
	public void writeInit(OutputStream os) throws IOException {
	    if (options.shareDesktop) {
	        os.write(1);
	    } else {
	    	os.write(0);
	    }
	}
	
	public void swapMouseButton(Integer[] masks) {
	    if (options.reverseMouseButtons2And3) {
	    	Integer temp = masks[1];
	    	masks[1] = masks[0];
	    	masks[0] = temp;
	      }
	}
	
	public boolean onTileChange(Rectangle rowMergedRect, int row, int col) {
		// currently we don't do scan-based client update
		return true;
	}
	
	public void onRegionChange(List<Region> regionList) {
		// obsolute
	}
	
	private void signalTileDirtyEvent() {
		synchronized(tileDirtyEvent) {
			dirtyFlag = true;
			tileDirtyEvent.notifyAll();
		}
	}
	
	public String getTag() {
		return tag;
	}
	
	public void setTag(String tag) {
		this.tag = tag;
	}
	
	//
	// AJAX Image manipulation 
	//
	public void copyTile(Graphics2D g, int x, int y, Rectangle rc) {
		if(vc != null && vc.memImage != null) {
			synchronized(vc.memImage) {
				g.drawImage(vc.memImage, x, y, x + rc.width, y + rc.height, 
					rc.x, rc.y, rc.x + rc.width, rc.y + rc.height, null);
			}
		}
	}
	
	public byte[] getFrameBufferJpeg() {
		int width = 800;
		int height = 600;
		if(vc != null) {
			width = vc.scaledWidth;
			height = vc.scaledHeight;
		}
		
		if(s_logger.isTraceEnabled())
			s_logger.trace("getFrameBufferJpeg, w: " + width + ", h: " + height);
		
		BufferedImage bufferedImage = new BufferedImage(width, height,
				BufferedImage.TYPE_3BYTE_BGR);
		if(vc != null && vc.memImage != null) {
			synchronized(vc.memImage) {
				Graphics2D g = bufferedImage.createGraphics();
				g.drawImage(vc.memImage, 0, 0, width, height, 0, 0, width, height, null);
			}
		}
		
		byte[] imgBits = null;
		try {
			imgBits = jpegFromImage(bufferedImage);
		} catch (IOException e) {
		}
		return imgBits;
	}
	
	public byte[] getTilesMergedJpeg(List<TileInfo> tileList, int tileWidth, int tileHeight) {
		
		int width = Math.max(tileWidth, tileWidth*tileList.size());
		BufferedImage bufferedImage = new BufferedImage(width, tileHeight,
			BufferedImage.TYPE_3BYTE_BGR);
		
		if(s_logger.isTraceEnabled())
			s_logger.trace("Create merged image, w: " + width + ", h: " + tileHeight);
		
		if(vc != null && vc.memImage != null) {
			synchronized(vc.memImage) {
				Graphics2D g = bufferedImage.createGraphics();
				int i = 0;
				for(TileInfo tile : tileList) {
					Rectangle rc = tile.getTileRect();
					
					if(s_logger.isTraceEnabled())
						s_logger.trace("Merge tile into jpeg from (" + rc.x + "," + rc.y + "," + (rc.x + rc.width) + "," + (rc.y + rc.height) + ") to (" + i*tileWidth + ",0)" );
					
					g.drawImage(vc.memImage, i*tileWidth, 0, i*tileWidth + rc.width, rc.height, 
						rc.x, rc.y, rc.x + rc.width, rc.y + rc.height, null);
					
					i++;
				}
			}
		}
		
		byte[] imgBits = null;
		try {
			imgBits = jpegFromImage(bufferedImage);
			
			if(s_logger.isTraceEnabled())
				s_logger.trace("Merge jpeg image size: " + imgBits.length + ", tiles: " + tileList.size());
		} catch (IOException e) {
		}
		return imgBits;
	}
	
	public byte[] jpegFromImage(BufferedImage image) throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream(128000);
		javax.imageio.ImageIO.write(image, "jpg", bos);
		
		byte[] jpegBits = bos.toByteArray();
		bos.close();
		return jpegBits;
	}
	
	private String prepareAjaxImage(List<TileInfo> tiles, boolean init) {
		byte[] imgBits;
		if(init)
			imgBits = getFrameBufferJpeg();
		else 
			imgBits = getTilesMergedJpeg(tiles, tracker.getTileWidth(), tracker.getTileHeight());
		
		if(imgBits == null) {
			s_logger.warn("Unable to generate jpeg image");
		} else {
			if(s_logger.isTraceEnabled())
				s_logger.trace("Generated jpeg image size: " + imgBits.length);
		}
		
		int key = ajaxImageCache.putImage(imgBits);
		StringBuffer sb = new StringBuffer("/ajaximg?host=");
		sb.append(host).append("&port=").append(port).append("&sid=").append(passwordParam);
		sb.append("&key=").append(key).append("&ts=").append(System.currentTimeMillis());
		return sb.toString(); 
	}
	
	private String prepareAjaxSession(boolean init) {
		StringBuffer sb = new StringBuffer();
		
		if(init)
			ajaxSessionId++;
		
		sb.append("/ajax?host=").append(host).append("&port=").append(port);
		sb.append("&sid=").append(passwordParam).append("&sess=").append(ajaxSessionId);
		return sb.toString();
	}

	public String onAjaxClientKickoff() {
		return "onKickoff();";
	}
	
	private boolean waitForViewerReady() {
		long startTick = System.currentTimeMillis();
		while(System.currentTimeMillis() - startTick < 5000) {
			if(this.status == ConsoleProxyViewer.STATUS_NORMAL_OPERATION)
				return true;
			
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
			}
		}
		return false;
	}
	
	private String onAjaxClientConnectFailed() {
		return "<html><head></head><body><div id=\"main_panel\" tabindex=\"1\"><p>" + 
			"Unable to start console session as connection is refused by the machine you are accessing" +
			"</p></div></body></html>";
	}
	
	public String onAjaxClientStart(String title) {
		if(!waitForViewerReady())
			return onAjaxClientConnectFailed();

		// make sure we switch to AJAX view on start
		setAjaxViewer(true);
			
		int tileWidth = tracker.getTileWidth();
		int tileHeight = tracker.getTileHeight();
		int width = tracker.getTrackWidth();
		int height = tracker.getTrackHeight();
		
		if(s_logger.isTraceEnabled())
			s_logger.trace("Ajax client start, frame buffer w: " + width + ", " + height);
		
		synchronized(this) {
			if(framebufferResized) {
				framebufferResized = false;
			}
		}
		
		int retry = 0;
		if(justCreated()) {
			tracker.initCoverageTest();
			
			try {
				rfb.writeFramebufferUpdateRequest(0, 0, tracker.getTrackWidth(), tracker.getTrackHeight(), false);
			
				while(!tracker.hasFullCoverage() && retry < 10) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
					}
					retry++;
				}
			} catch (IOException e1) {
				s_logger.warn("Connection was broken ");
			}
		}
		
		List<TileInfo> tiles = tracker.scan(true);
		String imgUrl = prepareAjaxImage(tiles, true);
		String updateUrl = prepareAjaxSession(true);
		
		StringBuffer sbTileSequence = new StringBuffer();
		int i = 0;
		for(TileInfo tile : tiles) {
			sbTileSequence.append("[").append(tile.getRow()).append(",").append(tile.getCol()).append("]");
			if(i < tiles.size() - 1)
				sbTileSequence.append(",");
			
			i++;
		}

/*		
		SimpleHash model = new SimpleHash();
		model.put("tileSequence", sbTileSequence.toString());
		model.put("imgUrl", imgUrl);
		model.put("updateUrl", updateUrl);
		model.put("width", String.valueOf(width));
		model.put("height", String.valueOf(height));
		model.put("tileWidth", String.valueOf(tileWidth));
		model.put("tileHeight", String.valueOf(tileHeight));
		model.put("title", title);
		model.put("rawKeyboard", ConsoleProxy.keyboardType == ConsoleProxy.KEYBOARD_RAW ? "true" : "false");
		
		StringWriter writer = new StringWriter();
		try {
			ConsoleProxy.processTemplate("viewer.ftl", model, writer);
		} catch (IOException e) {
			s_logger.warn("Unexpected exception in processing template.", e);
		} catch (TemplateException e) {
			s_logger.warn("Unexpected exception in processing template.", e);
		}
		StringBuffer sb = writer.getBuffer();
		if(s_logger.isTraceEnabled())
			s_logger.trace("onAjaxClientStart response: " + sb.toString());
		return sb.toString();
	*/
		return getAjaxViewerPageContent(sbTileSequence.toString(), imgUrl, 
				updateUrl, width, height, tileWidth, tileHeight, title, 
				ConsoleProxy.keyboardType == ConsoleProxy.KEYBOARD_RAW);
	}
	
	private String getAjaxViewerPageContent(String tileSequence, String imgUrl, String updateUrl, int width,
		int height, int tileWidth, int tileHeight, String title, boolean rawKeyboard) {
		
		String[] content = new String[] {
			"<html>",
			"<head>",
			"<script type=\"text/javascript\" language=\"javascript\" src=\"/resource/js/jquery.js\"></script>",
			"<script type=\"text/javascript\" language=\"javascript\" src=\"/resource/js/cloud.logger.js\"></script>",
			"<script type=\"text/javascript\" language=\"javascript\" src=\"/resource/js/ajaxviewer.js\"></script>",
			"<script type=\"text/javascript\" language=\"javascript\" src=\"/resource/js/handler.js\"></script>",
			"<link rel=\"stylesheet\" type=\"text/css\" href=\"/resource/css/ajaxviewer.css\"></link>",
			"<link rel=\"stylesheet\" type=\"text/css\" href=\"/resource/css/logger.css\"></link>",
			"<title>" + title + "</title>",
			"</head>",
			"<body>",
			"<div id=\"toolbar\">",
			"<ul>",
				"<li>", 
					"<a href=\"#\" onclick=\"javascript:sendCtrlAltDel();\">", 
						"<span><img align=\"left\" src=\"/resource/images/cad.gif\" alt=\"Ctrl-Alt-Del\" />Ctrl-Alt-Del</span>", 
					"</a>", 
				"</li>",
				"<li>", 
					"<a href=\"#\" onclick=\"javascript:sendCtrlEsc();\">", 
						"<span><img align=\"left\" src=\"/resource/images/winlog.png\" alt=\"Ctrl-Esc\" style=\"width:16px;height:16px\"/>Ctrl-Esc</span>",
					"</a>", 
				"</li>",
			"</ul>",
			"<span id=\"light\" class=\"dark\"></span>", 
			"</div>",
			"<div id=\"main_panel\" tabindex=\"1\"></div>",
			"<script language=\"javascript\">",
			
			"var tileMap = [ " + tileSequence + " ];",
			"var ajaxViewer = new AjaxViewer('main_panel', '" + imgUrl + "', '" + updateUrl + "', tileMap, ", 
				String.valueOf(width) + ", " + String.valueOf(height) + ", " + String.valueOf(tileWidth) + ", " + String.valueOf(tileHeight) + ", " + (rawKeyboard ? "true" : "false") + ");",

			"$(function() {",
				"ajaxViewer.start();",
			"});",

			"</script>",
			"</body>",
			"</html>"	
		};
		
		StringBuffer sb = new StringBuffer();
		for(int i = 0; i < content.length; i++)
			sb.append(content[i]);
		
		return sb.toString();
	}
	
	public String onAjaxClientDisconnected() {
		return "onDisconnect();";
	}
	
	public String onAjaxClientUpdate() {
		if(!waitForViewerReady())
			return onAjaxClientDisconnected();
		
		synchronized(tileDirtyEvent) {
			if(!dirtyFlag) {
				try {
					tileDirtyEvent.wait(3000);
				} catch(InterruptedException e) {
				}
			}
		}
		
		boolean doResize = false;
		synchronized(this) {
			if(framebufferResized) {
				framebufferResized = false;
				doResize = true;
			}
		}
		
		List<TileInfo> tiles;
		
		if(doResize)
			tiles = tracker.scan(true);
		else
			tiles = tracker.scan(false);
		dirtyFlag = false;
		
		String imgUrl = prepareAjaxImage(tiles, false);
		StringBuffer sbTileSequence = new StringBuffer();
		int i = 0;
		for(TileInfo tile : tiles) {
			sbTileSequence.append("[").append(tile.getRow()).append(",").append(tile.getCol()).append("]");
			if(i < tiles.size() - 1)
				sbTileSequence.append(",");
			
			i++;
		}

/*		
		SimpleHash model = new SimpleHash();
		model.put("tileSequence", sbTileSequence.toString());
		model.put("resized", doResize);
		model.put("imgUrl", imgUrl);
		model.put("width", String.valueOf(resizedFramebufferWidth));
		model.put("height", String.valueOf(resizedFramebufferHeight));
		model.put("tileWidth", String.valueOf(tracker.getTileWidth()));
		model.put("tileHeight", String.valueOf(tracker.getTileHeight()));
		
		StringWriter writer = new StringWriter();
		try {
			ConsoleProxy.processTemplate("viewer-update.ftl", model, writer);
		} catch (IOException e) {
			s_logger.warn("Unexpected exception in processing template.", e);
		} catch (TemplateException e) {
			s_logger.warn("Unexpected exception in processing template.", e);
		}
		StringBuffer sb = writer.getBuffer();
		
		if(s_logger.isTraceEnabled())
			s_logger.trace("onAjaxClientUpdate response: " + sb.toString());
		
		return sb.toString();
*/
		return getAjaxViewerUpdatePageContent(sbTileSequence.toString(), imgUrl, doResize, resizedFramebufferWidth,
			resizedFramebufferHeight, tracker.getTileWidth(), tracker.getTileHeight());
	}
	
	private String getAjaxViewerUpdatePageContent(String tileSequence, String imgUrl, boolean resized, int width,
		int height, int tileWidth, int tileHeight) {
		
		String[] content = new String[] {
			"tileMap = [ " + tileSequence + " ];",
			resized ? "ajaxViewer.resize('main_panel', " + width + ", " + height + " , " + tileWidth + ", " + tileHeight + ");" : "", 
			"ajaxViewer.refresh('" + imgUrl + "', tileMap, false);"
		};
		
		StringBuffer sb = new StringBuffer();
		for(int i = 0; i < content.length; i++)
			sb.append(content[i]);
		
		return sb.toString();
	}
	
	
	public long getAjaxSessionId() {
		return this.ajaxSessionId;
	}
	
	public AjaxFIFOImageCache getAjaxImageCache() {
		return ajaxImageCache;
	}
	
	public boolean isAjaxViewer() {
		return ajaxViewer;
	}

	public synchronized void setAjaxViewer(boolean ajaxViewer) {
		if(this.ajaxViewer != ajaxViewer) {
			if(this.ajaxViewer) {
				// previous session was AJAX session
				this.ajaxSessionId++;		// increase the session id so that it will disconnect existing AJAX viewer
			} else {
				// close java client session
				if(clientStream != null) {
					byte[] bs = new byte[2];
					bs[0] = (byte)250;
					bs[1] = 1;
					writeToClientStream(bs);
					
					try {
						clientStream.close();
					} catch (IOException e) {
					}
					clientStream = null;
				}
			}
			this.ajaxViewer = ajaxViewer;
		}
	}
	
	public void writeServer(byte[] b, int off, int len) {
		synchronized (this) {
			if (!rfb.closed()) {
				try {
					// We lock the viewer to avoid race condition when connecting one 
					// client forces the current client to disconnect.
					rfb.os.write(b, off, len);
					rfb.os.flush();
				} catch (IOException e) {
					// Swallow the exception because we want the client connection to sustain
					// even when server connection is severed and reestablished.
					s_logger.info("Ignore exception when writing to server: " + e);
					rfb.close();
				}
			} else {
				s_logger.info("Dropping client event because server connection is closed ");
			}
		}
	}
	
	public void sendClientMouseEvent(int event, int x, int y, int code, int modifiers) {
		if(code == 2)
			modifiers |= MouseEvent.BUTTON3_MASK;
		else
			modifiers |= MouseEvent.BUTTON1_MASK;

		int id = 0; 
		if(event == 1)
			id = MouseEvent.MOUSE_MOVED;
		else if(event == 2)
			id = MouseEvent.MOUSE_PRESSED;
		else if(event == 3)
			id = MouseEvent.MOUSE_RELEASED;
		else if(event == 8)
			id = MouseEvent.MOUSE_PRESSED;

		long curTicks = System.currentTimeMillis();
		MouseEvent mouseEvent = new MouseEvent(vc, id,
			curTicks, modifiers, x, y, 1, false);
		
		synchronized (this) {
			if (rfb != null && !rfb.closed()) {
				try {
					rfb.writePointerEvent(mouseEvent);
					if(event == 8) {
						if(s_logger.isTraceEnabled())
							s_logger.trace("Replay mouse double click event at " + x + "," + y);

						mouseEvent = new MouseEvent(vc, MouseEvent.MOUSE_RELEASED,
								curTicks, modifiers, x, y, 1, false);
						rfb.writePointerEvent(mouseEvent);
						
						mouseEvent = new MouseEvent(vc, MouseEvent.MOUSE_PRESSED,
								curTicks, modifiers, x, y, 1, false);
						rfb.writePointerEvent(mouseEvent);
						
						mouseEvent = new MouseEvent(vc, MouseEvent.MOUSE_RELEASED,
								curTicks, modifiers, x, y, 1, false);
						rfb.writePointerEvent(mouseEvent);
					}
				} catch (IOException e) {
					s_logger.warn("Exception while sending mouse event. ", e);
				}
			}
		}
	}

	public void sendClientRawKeyboardEvent(int event, int code, int modifiers) {
		code = ConsoleProxyAjaxKeyMapper.getInstance().getJvmKeyCode(code);
		switch(event) {
		case 4 : 	// Key press
			//
			// special handling for ' and " (keycode: 222, char code : 39 and 34
			//
			if(code == 39 || code == 34) {
				writeKeyboardEvent(KeyEvent.KEY_PRESSED, 222, (char)code, getAwtModifiers(modifiers));
			}
			break;

		case 5 :	// Key down
			if((modifiers & ConsoleProxyViewer.CTRL_KEY_MASK) != 0 && (modifiers & ConsoleProxyViewer.ALT_KEY_MASK) != 0 && code == KeyEvent.VK_INSERT) {
				code = KeyEvent.VK_DELETE;
			}
			
			if(code != 222) {
				writeKeyboardEvent(KeyEvent.KEY_PRESSED, code, 
					ConsoleProxyAjaxKeyMapper.getInstance().shiftedKeyCharFromKeyCode(code, (modifiers & ConsoleProxyViewer.SHIFT_KEY_MASK) != 0), 
					getAwtModifiers(modifiers));
			}
			break;
			
		case 6 :	// Key Up
			writeKeyboardEvent(KeyEvent.KEY_RELEASED, code, 
				ConsoleProxyAjaxKeyMapper.getInstance().shiftedKeyCharFromKeyCode(code, (modifiers & ConsoleProxyViewer.SHIFT_KEY_MASK) != 0), 
				getAwtModifiers(modifiers));
			break;
		}
	}

	public void sendClientKeyboardEvent(int event, int code, int modifiers) {
		int vkCode;
		switch(event) {
		case 4 : 	// Key press
			if(code == 0 || (modifiers & (ConsoleProxyViewer.CTRL_KEY_MASK | ConsoleProxyViewer.META_KEY_MASK | ConsoleProxyViewer.ALT_KEY_MASK)) != 0) {
				// if code is extend keys or has ctrl, alt, meta being pressed, ignore javascript key-press event
				return;
			}
			
			vkCode = ConsoleProxyAjaxKeyMapper.getInstance().getRegularCharVkCode(code);
			if(vkCode > 0) {
				writeKeyboardEvent(KeyEvent.KEY_PRESSED, vkCode, (char)code, 0); 
				writeKeyboardEvent(KeyEvent.KEY_RELEASED, vkCode, (char)code, 0);
			}
			break;

		case 5 :	// Key down
			vkCode = ConsoleProxyAjaxKeyMapper.getInstance().getActionCharVkCode(code);
			if(vkCode >= 0 || (modifiers & (ConsoleProxyViewer.CTRL_KEY_MASK | ConsoleProxyViewer.META_KEY_MASK | ConsoleProxyViewer.ALT_KEY_MASK)) != 0) {
				if(vkCode < 0) {
					vkCode = ConsoleProxyAjaxKeyMapper.getInstance().getRegularCharVkCode(code);
					
					if((modifiers & ConsoleProxyViewer.CTRL_KEY_MASK) != 0) {  	// if control-key is pressed, always use lower-case char-code
						if(vkCode >= (int)'A' && vkCode <= (int)'Z')
							vkCode = (int)'a' + (vkCode - (int)'A');
					}
				}
				
				if((modifiers & ConsoleProxyViewer.CTRL_KEY_MASK) != 0 && (modifiers & ConsoleProxyViewer.ALT_KEY_MASK) != 0 && vkCode == KeyEvent.VK_INSERT) {
					vkCode = KeyEvent.VK_DELETE;
				}
				
				writeKeyboardEvent(KeyEvent.KEY_PRESSED, vkCode, (char)vkCode,
					getAwtModifiers(modifiers));
			}
			break;
			
		case 6 :	// Key Up
			vkCode = ConsoleProxyAjaxKeyMapper.getInstance().getActionCharVkCode(code);
			if(vkCode >= 0 || (modifiers & (ConsoleProxyViewer.CTRL_KEY_MASK | ConsoleProxyViewer.META_KEY_MASK | ConsoleProxyViewer.ALT_KEY_MASK)) != 0) {
				if(vkCode < 0) {
					vkCode = ConsoleProxyAjaxKeyMapper.getInstance().getRegularCharVkCode(code);

					if((modifiers & ConsoleProxyViewer.CTRL_KEY_MASK) != 0) {	// if control-key is pressed, always use lower-case char-code
						if(vkCode >= (int)'A' && vkCode <= (int)'Z')
							vkCode = (int)'a' + (vkCode - (int)'A');
					}
					
					if((modifiers & ConsoleProxyViewer.CTRL_KEY_MASK) != 0 && (modifiers & ConsoleProxyViewer.ALT_KEY_MASK) != 0 && vkCode == KeyEvent.VK_INSERT) {
						vkCode = KeyEvent.VK_DELETE;
					}
				}

				writeKeyboardEvent(KeyEvent.KEY_RELEASED, vkCode, (char)vkCode,
					getAwtModifiers(modifiers));
			}
			break;
		}
	}
	
	private static int getAwtModifiers(int jsModifiers) {
		int awtModifiers = 0;
		
		if((jsModifiers & ConsoleProxyViewer.SHIFT_KEY_MASK) != 0) {
			awtModifiers |= InputEvent.SHIFT_DOWN_MASK;
		}
		
		if((jsModifiers & ConsoleProxyViewer.CTRL_KEY_MASK) != 0) {
			awtModifiers |= InputEvent.CTRL_DOWN_MASK;
		}
		
		if((jsModifiers & ConsoleProxyViewer.ALT_KEY_MASK) != 0) {
			awtModifiers |= InputEvent.ALT_DOWN_MASK;
		}
		
		return awtModifiers;
	}
	
	private void writeKeyboardEvent(int keyEventType, int code, char keyChar, int modifiers) {
		KeyEvent keyEvent;
		try {
			keyEvent = new KeyEvent(vc, keyEventType, 
				System.currentTimeMillis(), modifiers, code, keyChar);
		} catch(Exception e) {
			s_logger.warn("Unable to construct KeyEvent object, key code: " + code + ", keyChar: " + keyChar + " ", e);
			return;
		}
		
		synchronized (this) {
			if (rfb != null && !rfb.closed()) {
				try {
					rfb.writeKeyEvent(keyEvent);
				} catch (IOException e) {
					s_logger.warn("Exception while sending keyboard event. ", e);
				}
			}
		}
	}
}
