import javax.swing.*;

import java.awt.*;
import java.awt.event.*;
import java.lang.InterruptedException;


//****************************************************
//****************************************************
/**
@brief Contains the main cyle and process the input  

@author Esteban Gallardo
*/ 
public class ScrollWorld extends JPanel implements MouseListener, MouseMotionListener, Runnable 
{
    JViewport _viewGolfAdvent;	 /**< @brief Viewport of golf adventure */
        
    public World _World=null;			 /**< @brief Instance of world */

	public Thread threadWorld;	 		 /**< @brief Thread of execution */
	public boolean exit_ScrollWorld=false;	/**< @brief Informs of the exit of the thread */
	public int editionMode=0;			/**< @brief Informs if we are working with colision,rendering,mission,matrix */
	public int editedLayer=0;			/**< @brief Informs Render layer where we are working */
	
	public static final int EDITION_COLISION	 = 0;
	public static final int EDITION_RENDER 		 = 1;	
	
	// ---------------------------------------------------
	/**
	 @brief Create a world , gets the dimension of the screen and create a buffer for double buffering
	 */
	public ScrollWorld() 
	{
	    super(new BorderLayout());	    
	    
	    try 
	    {
		    // Set up the drawing area.
		    _World = new World();
		    _World.init( 16 , 28 , TileMapEditor.gBlockSize_X, TileMapEditor.gBlockSize_Y);
		    _World.setBackground(Color.white);
		    _World.addMouseListener(this);
		    _World.addMouseMotionListener(this);
		    _World.iBlockLength_X=(TileMapEditor.gBlockSize_X/TileMapEditor.gZoomApplied);
		    _World.iBlockLength_Y=(TileMapEditor.gBlockSize_Y/TileMapEditor.gZoomApplied);
	    } 
	    catch (Exception ed) 
	    {
	        ed.printStackTrace();
	        System.exit(0);
	    }

	    // Put the drawing area in a scroll pane.
	    JScrollPane scroller = new JScrollPane(_World);
	    scroller.setPreferredSize(new Dimension(560,560));
	    _viewGolfAdvent=scroller.getViewport();
	               	    
	    // Lay out this demo.
	    add(scroller, BorderLayout.CENTER);
	    
	    // Start the thread
	    threadWorld=new Thread(this);
	    threadWorld.start();
	}


	// ---------------------------------------------------
	/**
	 @brief Loads a world , gets the dimension of the screen and create a buffer for double buffering
	 */
	public ScrollWorld(String filename) 
	{
	    super(new BorderLayout());	    
	    
	    try 
	    {
		    // Set up the drawing area.
		    _World = new World();
		    _World.init( filename );		    
		    _World.setBackground(Color.white);
		    _World.addMouseListener(this);
		    _World.addMouseMotionListener(this);
		    _World.iBlockLength_X=(TileMapEditor.gBlockSize_X/TileMapEditor.gZoomApplied);
		    _World.iBlockLength_Y=(TileMapEditor.gBlockSize_Y/TileMapEditor.gZoomApplied);
	    } catch (Exception ed)
	    {
	        ed.printStackTrace();
	        System.exit(0);
	    }

	    // Put the drawing area in a scroll pane.
	    JScrollPane scroller = new JScrollPane(_World);
	    scroller.setPreferredSize(new Dimension(560,560));
	    _viewGolfAdvent=scroller.getViewport();
	               	    
	    // Lay out this demo.
	    add(scroller, BorderLayout.CENTER);
	    
	    // Start the thread
	    threadWorld=new Thread(this);
	    threadWorld.start();
	}
	
	
	// ---------------------------------------------------
	/**
	 @brief paintComponent
	 */
	protected void paintComponent(Graphics g) 
	{
		super.paintComponent(g);
	}
	
	// ---------------------------------------------------
	/**
	 @brief paint
	 */
	public void paint(Graphics g) 
	{
		g.drawImage(_World.buffer,0,0,this);
		_World.buffer.flush();
	}
	
	
	// ---------------------------------------------------
	// ---------------------------------------------------
	// ---------------------------------------------------
	// ---------------------------------------------------
	// MOUSE LISTENER FUNCTIONS
	// ---------------------------------------------------
	// ---------------------------------------------------
	// ---------------------------------------------------
	// ---------------------------------------------------
	public void mouseClicked(MouseEvent e){}
	public void mouseEntered(MouseEvent e){}
	public void mouseExited(MouseEvent e){}
	
	Point2D posIni=new Point2D();
	// ---------------------------------------------------
	/**
	 @brief Gets the dimension of the screen and create a buffer for double buffering
	 */
	public void mousePressed(MouseEvent e)
	{
	   _World.setPositionCell(e.getX(), e.getY(), -1, -1, editionMode, editedLayer);
	}

	
	// ---------------------------------------------------
	/**
	 @brief Process mouse move events
	 */
	public void mouseMoved( MouseEvent e ) 
	{
	}	
	
	// ---------------------------------------------------
	/**
	 @brief Process mouse dragged events
	 */
	public void mouseDragged( MouseEvent e ) 
	{
	   _World.setPositionCell(e.getX(), e.getY(), -1, -1, editionMode, editedLayer);
	}

	// ---------------------------------------------------
	/**
	 @brief Process mouse released event
	 */
	public void mouseReleased(MouseEvent e)
	{
	}	
	
	

	// ---------------------------------------------------
	// ---------------------------------------------------
	// ---------------------------------------------------
	// ---------------------------------------------------
	// RUNNABLE FUNCTIONS
	// ---------------------------------------------------
	// ---------------------------------------------------
	// ---------------------------------------------------
	// ---------------------------------------------------

	// ---------------------------------------------------
	/**
	 @brief starts the process
	 */
	public void start()
	{
	    run();
	}

	// ---------------------------------------------------
	/**
	 @brief stop the process
	 */
	public void stop()
	{
	}

	// ---------------------------------------------------
	/**
	 @brief Mainly paints the world
	 */
	public void run()
	{
		while (!exit_ScrollWorld) 
		{
			try 
			{
				try { Thread.sleep(100); } 
				catch (InterruptedException e) {};

				// Get the dimmension 
				_World.getDimension(getSize());
				
				// Camera update position
				Dimension areaTmp = getSize();
				Point posTmp=_viewGolfAdvent.getViewPosition();
				_World._Camera.x=posTmp.x+(areaTmp.width>>1);
				_World._Camera.y=posTmp.y+(areaTmp.height>>1);
				
				// System.out.println("Camera ("+_Camera.x+","+_Camera.y+")");
				
				// ++++++ Logic World ++++++					
				_World.logic();
				
				// ++++++ Draw World ++++++ 
				_World._g.setColor( Color.white );
				_World._g.fillRect( 0 , 0 , _World._iScreenWidth , _World._iScreenHeight );
				_World.render( editionMode, editedLayer );
				
				repaint();
			} 
			catch (Exception ed) 
			{
			    ed.printStackTrace();
			};
		}
	}

}
