package canvas;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.function.Function;

import javax.swing.Renderer;

public class Canvas {
	
	
	/**
	 * 
	 * @param dt time in milliseconds
	 * @param revalidate
	 *            true if something which may affect widget state may have
	 *            changed (ex. global variables, theme)
	 */
	public void update(double dt, boolean revalidate) {
		
	}
	
	public void paint(Renderer g) {
		
	}
	

	/**
	 * destroys Context associated with context;
	 * @param gl
	 */
	
	public void dispose(Renderer g) {
		

	}
	
	/**
	 * returns  current rendering context for the canvas
	 * @return
	 */
	public Context getContext(){
		return null;
	}
	
	/**
	 * returns  current rendering context for the canvas
	 * @return
	 */
	public Context getContext(String s){
		return null;
	}
	/**
	 * resets canvas and associated context, called when simulation reloads or script is resaved
	 */
	public void reset(){
		
	}
	
	/**
	 * Returns current Scene associated with context if any
	 * @return
	 */
	public Scene getScene() {
		return null;
	}
	
	/**
	 * set current Scene associated with context
	 * @param Scene
	 */
	public void setScene(Scene scene) {
		
	}
	
	/**
	 * Creates Offscreen Canvas associated with this canvas
	 * <p> An OffscreenCanvas is a canvas object that isn�t part of the screen display. 
	 * It is simply an area of memory that you can draw into using all of the familiar methods of canvas/context.
	 * <p>
	 * To render its content it can be used in place of Image object in context method, for example
	 * <pre>
	 * 	var ctx=world.getCanvas().getContext();
	 * 	var oCanvas=canvas.createOffscreenCanvas("id",120,120); //create offscreen canvas
	 * 	var octx=oCanvas.getContext();
	 * 	octx.fillRect(10,10,50,50); //draw some stuff on offscreen canvas
	 *	ctx.drawImage(oCanvas,0,0); //copy the content of offscreen canvas on actual context;
       </pre>                           
	 * which is exactly how you would do it with a standard canvas object.
	 * @param id
	 * @param width
	 * @param height
	 * @return {Canvas} canvas created
	 */
	public Canvas createOffscreenCanvas(String id, int width, int height) {
		return null;
	}
	
	/**
	 * Returns Offscreen Canvas created for this canvas with specified id else returns null
	 * @param id {String} Id of offscreen canvas used in its creation using {@link #createOffScreenCanvas(String, int, int)}
	 * @return {Canvas}
	 * @see #createOffscreenCanvas(String, int, int)
	 */
	public Canvas getOffscreenCanvas(String id) {
		return null;

	}
	
	/**
	 * Sets background color of canvas 
	 * 
	 * @param {Number}r
	 *            red component between 0 and 1 inclusive
	 * @param {Number}g
	 *            green component between 0 and 1 inclusive
	 * @param {Number}b
	 *            blue component between 0 and 1 inclusive
	 * @param {Number}a
	 *            alpha component between 0 and 1 inclusive
	 */
	public void setBackGroundColor(double r, double g, double b, double a) {
	
	}

	/**
	 * Sets background color of canvas {pass null to use default gui Color}
	 * @param color {Color|String} Color Object or css color string  ex.<br>
	 * 	<ol> 
	 * 	<li> Common color name "red", "green" </li>
	 *	<li> Hexadecimal representation of color such as #FF0096 or 0xFF0096 </li>
	 * 	<li> Color functions "rgb(255,0,0)","hsl(180, 50%, 50%)","rgba(255,255,120,1)" </li>
	 */
	public void setBackGroundColor(Object color) {
		
	}
	
	public String getBeanClassName() {
		return null;

	}
	

	/**Runs when the widget receives mouse scroll event although the event is automatically generated by SimPhy, 
	 * but this function can also be used to fire artificial mouse wheel events
	 * @param x{Number} : x coordinate of mouse in widget space (top left as origin) \n" +
	 * @param y{Number} : y coordinate of mouse in widget space (top left as origin) \n" +
	 * @param worldPt{Vector2} :point corresponding to mouse location in world space \n" +
	 * @param scroll{Number} :  the number of 'clicks' the mouse wheel was rotated, as an integer. \n" +
	 * @return if true is returned event is consumed and not further handled by simphy world"+
	 */
	public boolean handleMouseWheel(int x,int y, int scroll){
		return true;
	}
	
	/**
	 * Handles Mouse motion Event, although the event is automatically generated by SimPhy, 
	 * but this function can also be used to fire artificial mouse wheel events
	 * @param
	 * @param id {Number}: EventType: 500(clicked),501(pressed),502(released),503(moved),504(entered),505(exited) \n" +
	 * @param x {Number} : x coordinate of mouse in widget space (top left as origin) \n" +
	 * @param y {Number} : y coordinate of mouse in widget space (top left as origin) \n" +
	 * @param button {Number} : Button involved in event {1=Left, 2=Middle and 3=Right mouse button" +
	 * @param clickCount {Number} Number of clicks
	 * @param ctrlKey {boolean} if ctrl key is pressed
	 * @param altkey {boolean} if alt key is pressed
	 * @param shiftkey {boolean} if shift key is pressed
	 */
	public boolean handleMouseEvent(int x, int y, int clickcount,int id,int button,
				boolean shiftdown, boolean controldown, boolean popuptrigger) {
		return true;
	}
	

	/**
	 * Handles Mouse motion Event, although the event is automatically generated by SimPhy, but this function can also
	 * be used to fire artificial mouse wheel events
	 * 
	 * @param keyChar
	 *            {char} : the character(if any) associated with keyevent  +
	 * @param keyCode
	 *            {Number} : key code {@see https://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyEvent.html} for keycodes
	 * @param key
	 *            {String} : the identifier of the key (like 'ArrowLeft','a','Enter','F11) that was pressed when a key event occured
	 * @param id
	 *            {Number} : EventType 401(keyPressed), 402(KeyReleased)
	 * @param shiftdown
	 *            {boolean} if ctrl key is pressed
	 * @param controldown
	 *            {boolean} if shift key is pressed
	 * @param modifiers
	 * @return if true is returned event is consumed and not further handled by simphy world"+
	 */
	public boolean handleKeyEvent(int keychar, int keycode,int id,boolean shiftdown,
				boolean controldown, int modifiers) {
		return true;
 	}
	 
	/**
	 * 
	 * @return if true then popupshould not be handled by gui
	 */
	public boolean handlePopUp(int x, int y){
		return false;
	}
	
	public void setBounds(Rectangle r){
		
	}

	/**
	 * Sets Height of canvas, keeping width unchanged	
	 * @param height
	 * @throws Exception 
	 */
	public void setHeight(int height ) throws Exception{
		
	}
	
	/**
	 * Sets Width of canvas, keeping width unchanged	
	 * @param width
	 * @throws Exception 
	 */
	public void setWidth(int width ) throws Exception{
		
	}
	
	
	public Dimension getPreferredSize() {
		return null;
	}

	/**
	 * Set size of canvas (Note that setting size may have different effect based on layout of its parent)
	 * @param width{Number} width in pixels
	 * @param height{Number} height in pixels
	 */
	public void setSize(int width,int height) throws Exception {
		
	}

	/**
	 * 
	 * @return callbackFunction if any
	 */
	public Function<Object,Object> getOnmousedown() {
		return null;
	}

	/**
	 * Sets Callback function for mouse down event
	 * @param  callbackFunction {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 */
	public void setOnmousedown(Function<Object,Object> callbackFunction)  {
		
	}
		
	/**
	 * 
	 * @return callbackFunction if any
	 */
	public Function<Object,Object> getOnmouseup() {
		return null;
	}

	/**
	 * Sets Callback function for mouse up event
	 * @param  callbackFunction {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 */
	public void setOnmouseup(Function<Object,Object> callbackFunction)  {
		
	}
		
	/**
	 * 
	 * @return callbackFunction if any
	 */
	public Function<Object,Object> getOnmousemove() {
		return null;
	}

	/**
	 * Sets Callback function for mouse move event
	 * @param  callbackFunction {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 */
	public void setOnmousemove(Function<Object,Object> callbackFunction)  {
		
	}
		
	/**
	 * 
	 * @return callbackFunction if any
	 */
	public Function<Object,Object> getOnclick() {
		return null;
	}

	/**
	 * Sets Callback function for mouse click event
	 * @param  callbackFunction {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 */
	public void setOnclick(Function<Object,Object> callbackFunction)   {
		
	}
	
	/**
	 * 
	 * @return callbackFunction if any
	 */
	public Function<Object,Object> getOndoubleclick() {
		return null;
	}

	/**
	 * Sets Callback function for mouse double click event
	 * @param  callbackFunction {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 */
	public void setOndoubleclick(Function<Object,Object> callbackFunction) {
		
	}
	
	/**
	 * 
	 * @return callbackFunction if any
	 */
	public Function<Object,Object> getOnmousewheel() {
		return null;
	}

	/**
	 * Sets Callback function for mouse wheel or scroll event
	 * @param  callbackFunction {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 */
	public void setOnmousewheel(Function<Object,Object> callbackFunction) {
		
	}
	
	/**
	 * 
	 * @return callbackFunction if any
	 */
	public Function<Object,Object> getOnkeypress() {
		return null;
	}

	/**
	 * Sets Callback function for key press event
	 * @param  callbackFunction {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 */
	public void setOnkeypress(Function<Object,Object> callbackFunction)  {
		

	}
	/**
	 * Sets Callback function for canvas resize event
	 * @param  callbackFunction {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 */
	public void setOnresize(Function<Object,Object> callbackFunction)   {
		
	}
	
	/**
	 * Sets Callback function to call just before context menu is fired for the canvas
	 * @param  callbackFunction {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 */
	public void setOncontextmenu(Function<Object,Object> callbackFunction)  {
		
	}
	
	/**
	 * 
	 * @return callbackFunction if any
	 */
	public Function<Object,Object> getOnkeydown() {
		return null;
	}

	/**
	 * Sets Callback function for key down event
	 * @param  callbackFunction {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 */
	public void setOnkeydown(Function<Object,Object> callbackFunction) {
		
	}
	
	/**
	 * 
	 * @return callbackFunction if any
	 */
	public Function<Object,Object> getOnkeyup() {
		return null;
	}

	/**
	 * Sets Callback function for key up event
	 * @param  callbackFunction {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 */
	public void setOnkeyup(Function<Object,Object> callbackFunction) {
		
	}
	
	/**
	 * Sets Mouse of keyboard eventListener for canvas
	 * @param event {String} mouseup|mousedown|mousemove|click|keyup|keydown|keypress|mousewheel
	 * @param callback {Function} function(must be defined in script) to be called
	 * @throws SimphyScriptException
	 * Note: You may use the "on" prefix. For example, use "click" or "onclick" to listen click events.
	 */
	public void addEventListener(String event, Function<Object,Object> callback){
		
	}
	
	/**
	 * Sets Mouse of keyboard eventListener for canvas
	 * @param event
	 * @param callback
	 * @throws SimphyScriptException
	 */
	public void addEventListener(String event, Function<Object,Object> callback,boolean propagate) {

	}
	
	/**
	 * Remove an event handler that has been attached with the {@link #addEventListener(String, Function)}method.
	 * @param event {String} mouseup|mousedown|mousemove|click|keyup|keydown|keypress|mousewheel
	 */
	public void removeEventListener(String event){
		
	}
	
	/**
	 * Requests focus on this canvas, Having the focus means that key events are handed by it.
	 */
	public void focus(){

	}
	
	/**
	 * The method allows to execute function on the next available repaint (called irrespective of simulation running or spot)
	 * <p>
	 * This is different from {@link org.shikhar.simphy.scripting.App#setInterval(Function, double)} and {@link org.shikhar.simphy.scripting.App#setTimeout(Function, double)} 
	 * which are executed only when simulation is running.
	 * @param callback {Function} The function to call when it's time to update your animation for the next repaint.
	 */
	public int requestAnimationFrame(Function<Object,Object> callback ) {
		
		return 1;
	}
	
	/**
	 * This method cancels an animation frame request previously scheduled through a call to {@link #requestAnimationFrame(Function)}.	 
	 * @param callback {Function} The function to call when it's time to update your animation for the next repaint.
	 */
	public void cancelAnimationFrame(int requestId) {
		
	}
}
