/*
 * Copyright (c) 2006-2008 MiniMe. Code released under The MIT/X Window System
 * License. Full license text can be found in license.txt
 */
package minime.core;

import javax.microedition.lcdui.game.*;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Canvas;

import minime.Logger;
import minime.Portability;

/**
 * The CanvasDisplayable class is for writing applications that need to handle
 * low-level events and to issue graphics calls for drawing to the display.
 * 
 * @author yishu
 * 
 */
//public class CanvasDisplayable extends GameCanvas implements Displayable
public class CanvasDisplayable extends GameCanvas implements Runnable, Displayable
{
    private final long REFRESH_TIME = 40 ;
    private EventDispatcher eventDispatcher = EventDispatcher.getInstance();
    private Runtime runtime = Runtime.getInstance();
    private boolean isDoubleBuffered ;
    private Thread t ;
    
    static final Logger LOG = Logger.getLogger("minime.CanvasDisplayable");

    /**
     * Constructs a new CanvasDisplayable object with the canvas is in
     * full-screen mode.
     * 
     */
    public CanvasDisplayable()
    {
        super(false);
        this.setFullScreenMode(true);
        t = new Thread(this) ;
        isDoubleBuffered = isDoubleBuffered() ;
    }

    //
    // from Canvas
    //

    /**
     * Called when a key is pressed. Fire a key event and some
     * object(implemented EventListener interface)receive this key event and
     * handle it.
     * 
     * @param keyCode
     *            the key code of the key that was pressed
     */
    protected void keyPressed(int keyCode)
    {
    	LOG.debug("keyPressed:"+keyCode+":"+Portability.translateKeyCode(keyCode)) ;
        eventDispatcher.fire(Event.createEvent(Event.KEY_DOWN_EVENT, keyCode, Portability.translateKeyCode(keyCode), null));
    }

    protected void keyReleased(int keyCode)
    {
    	LOG.debug("keyReleased:"+keyCode+":"+Portability.translateKeyCode(keyCode)) ;
        eventDispatcher.fire(Event.createEvent(Event.KEY_UP_EVENT, keyCode, Portability.translateKeyCode(keyCode), null));
    }

    protected void keyRepeated(int keyCode)
    {
    	LOG.debug("keyRepeated:"+keyCode+":"+Portability.translateKeyCode(keyCode)) ;
    }

	public void run()
	{
		Graphics g = getGraphics() ;
		long flushingTime = 0;
		while(true) 
		{			
			runtime.paint(g) ;
			try {
//				long curent = System.currentTimeMillis() ;
				runtime.gameTick() ;
				long delay = (long)(REFRESH_TIME - (System.currentTimeMillis() - flushingTime)) ;
				
//				int color = g.getColor() ;
//				if (delay<0)
//					g.setColor(255, 0, 0) ;
//				else
//					g.setColor(0, 255, 0) ;
//				
//				if (!isDoubleBuffered)
//					g.fillRect(20, 0, 10, 10) ;
//				
//				g.fillRect(0, 0, 10, 10) ;
//				g.setColor(color) ;
//				
				Thread.sleep((long)Math.max((long)1,delay)) ;
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			flushGraphics();
			flushingTime = System.currentTimeMillis() ;
		}
	}
    
//    /**
//     * Renders the Canvas.
//     * 
//     * @param g
//     *            the Graphics object to be used for rendering the Canvas
//     */
//    public void paint(Graphics g)
//    {
//        runtime.paint(g);
//    }

    /**
     * Return the native displable instance.
     * 
     * @return native displable instance.
     */
    public javax.microedition.lcdui.Displayable getNativeDisplayable()
    {
        return this;
    }

    /**
     * Return the canvas instance.
     * 
     * @return canvas instance.
     */
    public Canvas getCanvas()
    {
        return this;
    }

	public void startGameThread()
	{
		t.start();
	}
}
