/*===========================================================================
 *
 * File:	MorrowMap.JAVA
 * Author:	Dave Humphrey (uesp@m0use.net)
 * Created On:	Monday, August 27, 2001
 *
 * Description
 *
 *=========================================================================*/

	/* Import Packages */
import java.awt.*;
import java.awt.Toolkit.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import java.net.URL;
import MorrowMapLocTypes;
import MorrowMapRecord;
import MorrowMapOptions;
import MorrowMapArray;


/*===========================================================================
 *
 * Begin Class MorrowMap
 *
 * Main class for handling the Tamriel map parsing and output.
 *
 *=========================================================================*/
public class MorrowMap extends java.applet.Applet implements Runnable {

  /*---------- Begin Class Data Constants --------------------------*/
  /*---------- End of Class Data Constants -------------------------*/

  
  /*---------- Begin Class Data Members --------------------------*/

  Thread	   m_MainThread;

  Image		   MapImage;		/* Stores the image of the map */
  Graphics         MapGraphics;		/* The graphics handle for image */

  Image		   m_MapBGImage;	/* Map background image, if any */
  Graphics         m_hMapBGImage;	/* The graphics handle for image */
  int		   m_BGImageWidth;
  int		   m_BGImageHeight;

  MorrowMapArray   m_ProvinceArray;	/* Array of province map records */
  MorrowMapArray   m_LocationArray;	/* Array of general location map records */

  MorrowMapOptions m_MapOptions;	/* Holds options related to map input/output */

  MediaTracker     m_MediaTracker;	/* Used to update display when loading images/files */
  String	   m_TrackerString;
  boolean	   m_IsLoading;	

  /*---------- End of Class Data Members -------------------------*/


/*===========================================================================
 *
 * Method - int CheckParameters ();
 *
 * Checks and parses any input parameters for the applet.  Returns -1 on any
 * error.
 *
 *=========================================================================*/
int CheckParameters () {
  String ParamString;
  int    Value;
  
	/* Check for the pixel width of image */
  ParamString = getParameter("PixelWidth");

  if (ParamString != null) {
    Value = Integer.valueOf(ParamString).intValue();
    if (Value < 10 || Value > 1024) return (-1);
    m_MapOptions.m_PixelWidth = Value;
   }

	/* Check for the pixel height of image */
  ParamString = getParameter("PixelHeight");

  if (ParamString != null) {
    Value = Integer.valueOf(ParamString).intValue();
    if (Value < 10 || Value > 1024) return (-1);
    m_MapOptions.m_PixelHeight = Value;
   }

	/* Check for the search string */
  ParamString = getParameter("SearchString");

  if (ParamString != null) {
    m_MapOptions.SetSearchString(ParamString);
   }

	/* Check for display options */
  ParamString = getParameter("DrawText");
  if (ParamString != null) m_MapOptions.SetDrawText(ParamString);

  ParamString = getParameter("ShowPosition");
  if (ParamString != null) m_MapOptions.SetShowPosition(ParamString);
  
  return (0);
 }
/*===========================================================================
 *		End of Function CheckParameters()
 *=========================================================================*/


/*===========================================================================
 *
 * Method - void ClearMapImage ();
 *
 * Clears the entire map image buffer.
 *
 *=========================================================================*/
public void ClearMapImage () {
  int X, Y;
  int X2, Y2;
  int W, H;

  MapGraphics.setColor(MorrowMapLocTypes.GetWaterColor());
  MapGraphics.fillRect(0, 0, m_MapOptions.m_PixelWidth, m_MapOptions.m_PixelHeight);

  //X = m_MapOptions.MapToPixelX(m_MapOptions.MIN_MAP_X);
  //W = m_MapOptions.MapToPixelX(m_MapOptions.MAX_MAP_X) - m_MapOptions.MapToPixelX(m_MapOptions.MIN_MAP_X);
  //Y = m_MapOptions.MapToPixelY(m_MapOptions.MAX_MAP_Y);
  //H = m_MapOptions.MapToPixelY(m_MapOptions.MIN_MAP_Y) - m_MapOptions.MapToPixelY(m_MapOptions.MAX_MAP_Y);
  //MapGraphics.drawImage(m_MapBGImage, X, Y, W, H, this);

  X  = (m_MapOptions.m_MapBox.x - m_MapOptions.MIN_MAP_X) * m_BGImageWidth / m_MapOptions.MAX_MAP_WIDTH;
  X2 = (m_MapOptions.m_MapBox.x + m_MapOptions.m_MapBox.width - m_MapOptions.MIN_MAP_X) * m_BGImageWidth / m_MapOptions.MAX_MAP_WIDTH;
  Y  = (m_MapOptions.MAX_MAP_Y - m_MapOptions.m_MapBox.y) * m_BGImageHeight / m_MapOptions.MAX_MAP_HEIGHT;
  Y2 = (m_MapOptions.MAX_MAP_Y - m_MapOptions.m_MapBox.y - m_MapOptions.m_MapBox.height) * m_BGImageHeight / m_MapOptions.MAX_MAP_HEIGHT;

	/* Scale and paste the background image */
  System.out.println("Map = " + X + ", " + Y2 + ", " + X2 + ", " + Y);
  MapGraphics.drawImage (m_MapBGImage, 
			 0, 0, m_MapOptions.m_PixelWidth, m_MapOptions.m_PixelHeight,
			 X, Y2, X2, Y, this);
 }
/*===========================================================================
 *		End of Function ClearMapImage()
 *=========================================================================*/


/*===========================================================================
 *
 * Method - public int CreateMapImage ();
 *
 * Attempts to create a new map image based on the current option and
 * map database information.
 *
 *=========================================================================*/
public int CreateMapImage () {
  
	/* Update the conversion factors */
  m_MapOptions.ComputeConversion();

	/* Delete the old map image, if any */
  ClearMapImage();

	/* Output province/main locations */
  m_ProvinceArray.CreateImage(MapGraphics, m_MapOptions);
  m_LocationArray.CreateImage(MapGraphics, m_MapOptions);
  
  return (0);
 }
/*===========================================================================
 *		End of Method int CreateMapImage()
 *=========================================================================*/


/*===========================================================================
 *
 * Class MorrowMap Method - public void init ();
 *
 *=========================================================================*/
public void init() {
  int Result;

	/* Create the map database arrays */
  m_ProvinceArray = new MorrowMapArray();
  m_LocationArray = new MorrowMapArray();

	/* Create the map options */
  m_MapOptions = new MorrowMapOptions();

	/* Check and parse any input parameters */
  Result = CheckParameters();

	/* Create the buffered map image */
  MapImage = createImage(m_MapOptions.m_PixelWidth, m_MapOptions.m_PixelHeight);
  MapGraphics = MapImage.getGraphics();
 }
/*===========================================================================
 *		End of Class MorrowMap Method init()
 *=========================================================================*/


/*===========================================================================
 *
 * Method - public int LoadMapBG ();
 *
 * Attempts to load the map background image.
 *
 *=========================================================================*/
public int LoadMapBG () {
  URL theURL;

  System.out.println("Starting LoadMapBG ' " + m_MapOptions.MAP_IMAGE_URL + "'...");

  	/* Attempt to initialize the URL and data IO streams */
  m_MediaTracker = new MediaTracker(this); 
  m_IsLoading = true;
  m_TrackerString = "Loading background image " + m_MapOptions.MAP_IMAGE_URL + "...";
  repaint();
  m_MapBGImage = getImage(getCodeBase(), m_MapOptions.MAP_IMAGE_URL); 

	/* Tell the MediaTracker to kep an eye on this image, and give an ID */
  m_MediaTracker.addImage(m_MapBGImage, 1); 
 
	/* Tell the mediaTracker to stop the applet execution 
	   (in this example don't paint) until the images are fully loaded. 
	   must be in a try catch block. */
  try { 
    m_MediaTracker.waitForID(1);
   } 
  catch (InterruptedException e) {
    System.out.println("Media track error...");
    m_IsLoading = false;
    return (-1);
   } 

  m_IsLoading = false;
  System.out.println("Finished loading BG image...");
  System.out.println("    Size = " + m_MapBGImage.getWidth(this) + " x " + m_MapBGImage.getHeight(this));
  m_BGImageWidth  = m_MapBGImage.getWidth(this);
  m_BGImageHeight = m_MapBGImage.getHeight(this);
  return (0);
 }
/*===========================================================================
 *		End of Method int LoadMapBG()
 *=========================================================================*/


/*===========================================================================
 *
 * Class MorrowMap Method - void OutputError (Message);
 *
 * Displays the given error message to the Java window and stops the
 * applet.
 *
 *=========================================================================*/
public void OutputError (String Message) {

	/* Clear the current map image */
  ClearMapImage();

	/* Output the error message */
  MapGraphics.setColor(Color.red);
  MapGraphics.drawString("An error occurred in the Java applet!", 10, 10);
  MapGraphics.drawString(Message, 10, 30);

  repaint();
  System.exit(1);
 }
/*===========================================================================
 *		End of Class MorrowMap Method OutputError()
 *=========================================================================*/


/*===========================================================================
 *
 * Class MorrowMap Method - paint (graph);
 *
 *=========================================================================*/
public void paint (Graphics graph) {

  if (m_IsLoading) {
    //graph.drawImage(m_MapBGImage, 0, 0, m_MapOptions.m_PixelWidth, m_MapOptions.m_PixelHeight, this);

    graph.clearRect(0, 0, m_MapOptions.m_PixelWidth, m_MapOptions.m_PixelHeight);
    graph.setColor(MorrowMapLocTypes.GetWaterColor());
    graph.drawImage(MapImage, 0, 0, this);
    graph.drawString(m_TrackerString, 100, 100);
    
   }
  else {
    graph.drawImage(MapImage, 0, 0, this);
   }

 }

public void update (Graphics graph) {
  paint(graph);
 }
/*===========================================================================
 *		End of Method paint()
 *=========================================================================*/


/*===========================================================================
 *
 * Method - void Pan (DX, DY);
 *
 * Attempts to pan the current view point of the map.  
 *
 *=========================================================================*/
public void Pan (float DX, float DY) {
  int Result;
  
	/* Attempt to zoom in/out */
  Result = m_MapOptions.Pan(DX, DY);
  if (Result < 0) return;

	/* Update the display */
  CreateMapImage();
  repaint();
 }
/*===========================================================================
 *		End of Method Pan()
 *=========================================================================*/


/*===========================================================================
 *
 * Method - void run ();
 *
 *=========================================================================*/
public void run () {
  int Result;

	/* Read and parse the map databases */
  m_IsLoading = true;

  m_TrackerString = "Loading location database " + m_MapOptions.MAP_PROV_URL + "...";
  repaint();
  Result = m_ProvinceArray.LoadDatabase(getCodeBase() + m_MapOptions.MAP_PROV_URL, true);

  m_TrackerString = "Loading location database " + m_MapOptions.MAP_MAIN_URL + "...";
  repaint();
  if (Result >= 0) Result = m_LocationArray.LoadDatabase(getCodeBase() + m_MapOptions.MAP_MAIN_URL, false);
  if (Result <  0) OutputError("Failed to load map database file!");
  m_IsLoading = false;

	/* Attempt to create the background image */
  LoadMapBG();
  
	/* Attempt to output database to image buffer */
  CreateMapImage();

  //m_ProvinceArray.DebugOutput();
  //m_LocationArray.DebugOutput();
  repaint();  
 }
/*===========================================================================
 *		End of Method Pan()
 *=========================================================================*/


/*===========================================================================
 * 
 * Method - void Search (SearchString);
 *
 * Searches the map database for matching locations, outputting the results
 * to a new map image.
 *
 *=========================================================================*/
public void Search (String SearchString) {

	/* Update the map options */
  m_MapOptions.SetSearchString(SearchString);

	/* Update the map image */
  m_MapOptions.ZoomFullMap();
  CreateMapImage();
  repaint();
 }
/*===========================================================================
 *		End of Method Search()
 *=========================================================================*/


/*===========================================================================
 *
 * Class MorrowMap Method - public void start ();
 *
 *=========================================================================*/
public void start() {
  m_MainThread = new Thread(this);
  m_MainThread.start();
 }

public void stop() {
  m_MainThread.stop();
  m_MainThread = null;
 }
/*===========================================================================
 *		End of Class MorrowMap Method start()
 *=========================================================================*/


/*===========================================================================
 *
 * Class MorrowMap Method - public void SetForceDisplayLevel ();
 *
 *=========================================================================*/
public void SetForceDisplayLevel (String Value) {
  m_MapOptions.SetForceDisplayLevel(Value);
  //System.out.println("Finished loading BG image...");
  CreateMapImage();
  repaint();
 }
/*===========================================================================
 *		End of Class MorrowMap Method SetForceDisplayLevel()
 *=========================================================================*/


/*===========================================================================
 *
 * Class MorrowMap Method - public void SetShowPosition ();
 *
 *=========================================================================*/
public void SetShowPosition (boolean Flag) {
  m_MapOptions.m_ShowPosition = Flag;
  CreateMapImage();
  repaint();
 }
/*===========================================================================
 *		End of Class MorrowMap Method SetShowPosition()
 *=========================================================================*/


/*===========================================================================
 *
 * Class MorrowMap Method - public void SetShowAll ();
 *
 *=========================================================================*/
public void SetShowAll (boolean Flag) {
  m_MapOptions.m_ShowAll = Flag;
  CreateMapImage();
  repaint();
 }
/*===========================================================================
 *		End of Class MorrowMap Method SetShowAll()
 *=========================================================================*/


/*===========================================================================
 *
 * Method - void Zoom (Amount);
 *
 * Attempts to zoom into/out of the current view point of the map.  Amount
 * is a number representing the amount of zoom.  
 *	0.5 = Zoom in to half size
 *	1.0 = No change
 *	2.0 = Zoom out to double size
 *
 *=========================================================================*/
public void Zoom (float Amount) {
  int Result;
  	
	/* Attempt to zoom in/out */
  Result = m_MapOptions.Zoom(Amount);
  if (Result < 0) return;

	/* Update the display */
  CreateMapImage();
  repaint();
 }
/*===========================================================================
 *		End of Method Zoom()
 *=========================================================================*/


/*===========================================================================
 *
 * Method - void ZoomFullMap ();
 *
 * Resets the zoom level to show the entire map area.  
 *
 *=========================================================================*/
public void ZoomFullMap () {
  int Result;
  	
	/* Attempt to zoom in/out */
  Result = m_MapOptions.ZoomFullMap();
  if (Result < 0) return;

	/* Update the display */
  CreateMapImage();
  repaint();
 }
/*===========================================================================
 *		End of Method ZoomFullMap()
 *=========================================================================*/

 }
/*===========================================================================
 *		End of Class MorrowMap
 *=========================================================================*/


/*===========================================================================
 *		End of File MorrowMap.JAVA
 *=========================================================================*/