// ShowImage.java
//
// Copyright Henrik Björkman (www.stacken.kth.se/~bjorkman) 1999
//
// History:
//
// Created by Henrik Björkman 1999-08-13 using code from 
// DrawCircleDemo.java    
//

package chartplotter_package;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import se.beod.henrik.nav.*;

/**
 *
 */
public class ShowImage extends Frame 
{
  ShowImageComponent plot_area;
  static int nwindows=0; // Do system exit if is down to zero.
  ScrollPane pane;
  ChartData chartData;
  ReferencePoint ref;
  String name;
  Integer state=new Integer(0);
  String data_file_name;
  boolean needSave=false;
  String dir="";

  static void error(String s)
  {
    System.err.println("ChartThread: " + s);
    System.exit(0);
  }

  // Just for debugging.
  static public void debug(String s)
  {
    System.err.println("ShowImage: "+s);
  }

  public static void println(String s)
  {
    System.out.println(s);
  }

  void help()
  {
    println("Usage: java ShowImage [switches] <image file name>");
    println("");
    System.exit(0);
  }



  void createMenu()
  {
    MenuBar menubar=new MenuBar();

    Menu file_menu;
    file_menu=new Menu("File");
    menubar.add(file_menu);

    MenuItem s;
    s = new MenuItem("Save data", new MenuShortcut(KeyEvent.VK_S));
    file_menu.add(s);
    s.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) { save(); }
    });


    MenuItem l;
    l = new MenuItem("Load image",new MenuShortcut(KeyEvent.VK_L));
    file_menu.add(l);
    this.setMenuBar(menubar);
    l.addActionListener(new ActionListener() {     
      public void actionPerformed(ActionEvent e) { load(); }
    });

    MenuItem r;
    r = new MenuItem("Add ref",new MenuShortcut(KeyEvent.VK_R));
    file_menu.add(r);
    this.setMenuBar(menubar);
    r.addActionListener(new ActionListener() {     
      public void actionPerformed(ActionEvent e) {ref();}
    });

    MenuItem d;
    d = new MenuItem("Set datum",new MenuShortcut(KeyEvent.VK_D));
    file_menu.add(d);
    this.setMenuBar(menubar);
    d.addActionListener(new ActionListener() {     
      public void actionPerformed(ActionEvent e) {datum();}
    });

    MenuItem i;
    i = new MenuItem("Set info",new MenuShortcut(KeyEvent.VK_I));
    file_menu.add(i);
    this.setMenuBar(menubar);
    i.addActionListener(new ActionListener() {     
      public void actionPerformed(ActionEvent e) {remark();}
    });

    MenuItem c;
    c = new MenuItem("Exit",new MenuShortcut(KeyEvent.VK_C));
    file_menu.add(c);
    this.setMenuBar(menubar);
    c.addActionListener(new ActionListener() {     
      public void actionPerformed(ActionEvent e) { close(); }
    });


  }

  synchronized void ref()
  {

    Point p=plot_area.getPoint();

    checkIfReady();

    if (p==null)
    {
      debug("not possible now");
      //OkDialog d=new OkDialog(this,"Not possible now","Mark a point on the map first.");
      OkDialog.popUp(this,"Not possible now","Mark a point on the map first.");
    }
    else if (ref!=null)
    {
      debug("not possible now");
      //OkDialog d=new OkDialog(this,"Not possible now","Finish current ref point first.");
      OkDialog.popUp(this,"Not possible now","Finish current ref point first.");
    }
    else
    {
      debug("ref");

      ref=new ReferencePoint("-10000 -10000 0N0 0E0");
      RefDialog d=new RefDialog(this,"Enter new reference point",p,ref,state);
    }

    debug("klar");
  }

  void checkIfReady()
  {
    if (ref!=null)
    {
      if ((ref.x==-10001) && (ref.y==-10001))
      {
        ref=null;
      }
      else if ((ref.x!=-10000) && (ref.y!=-10000))
      {
        chartData.addRefPoint(ref);
        needSave=true;
        ref=null;
      }
    }
  }

  void findLimits()
  {
    chartData.south=ReferencePoint.MAX_NORTH;
    chartData.north=ReferencePoint.MAX_SOUTH;
    chartData.west=ReferencePoint.MAX_EAST;
    chartData.east=ReferencePoint.MAX_WEST;
    for (int i=0;i<chartData.nref;i++)
    {
      if (chartData.ref[i].lat<chartData.south) 
      {
        chartData.south=chartData.ref[i].lat;
      }
      if (chartData.ref[i].lat>chartData.north) 
      {
        chartData.north=chartData.ref[i].lat;
      }
      if (chartData.ref[i].lng<chartData.west) 
      {
        chartData.west=chartData.ref[i].lng;
      }
      if (chartData.ref[i].lng>chartData.east) 
      {
        chartData.east=chartData.ref[i].lng;
      }
    }
  }


  public static int findLastDot(String str)
  {
    int dot=-1;

    for(int i=0;i<str.length();i++)
    {
      if (str.charAt(i)=='.') {dot=i;}
    }
    return(dot);
  }

  public static String changeName(String str)
  {
    String name;

    int dot=findLastDot(str);

    if (dot>0)
    {
      name=str.substring(0,dot)+".dat";
    }
    else
    {
      name=str+".dat";
    }
    return(name);
  }

  void datum()
  {
    String datum=chartData.datum;
    if (datum==null) {datum="WGS-84";}
    StringInputDialog d=new StringInputDialog(this,"Chart datum","Give chart datum",datum);
    d.show();
    if (d.getState()==StringInputDialog.OK)
    {
      chartData.datum=d.getText();
    }
    d.dispose();
  }

  void remark()
  {
    String info=chartData.title;
    if (info==null) {info="";}
    StringInputDialog d=new StringInputDialog(this,"Chart information","Chart title?",info);
    d.show();
    if (d.getState()==StringInputDialog.OK)
    {
      chartData.title=d.getText();
    }
    d.dispose();
  }

  void save()
  {
    String str;

    debug("save");

    checkIfReady();
    findLimits();

    debug(data_file_name);

    str=chartData.toString();

    debug(str);

    chartData.findCalibrationParams();
    if (chartData.diff>=0)
    {
      println("Precision estimated to: "+chartData.diff+" pixels");
    }
    else
    {
      println("To few reference points to estimate precision.");
    }

    try
    {
      File file=new File(dir+data_file_name);
      FileWriter out=new FileWriter(file);
      out.write("// "+new java.util.Date()+"\n");
      out.write(str);
      out.close();
      needSave=false;
    }
    catch (IOException e) {error(""+e); }

  }

  void load()
  {
    debug("load");

    int r=ExitDialog.UNKNOWN;

    checkIfReady();

    debug("load "+needSave);

    if (needSave)
    {
      r=ExitDialog.visa(this,"There is unsaved data","Proceed without saving?");
    }

    if (r!=ExitDialog.CANCEL)
    {
      needSave=false;

      FileDialog d=new FileDialog(this,"Which image file?",FileDialog.LOAD);
      d.setDirectory(dir);
      d.show();
      name=d.getFile(); /*File.Separator*/

      if (name!=null)
      {
        dir=d.getDirectory();
        d.dispose();

        chartData=new ChartData();
        chartData.imgFileName=name;
        data_file_name=changeName(name);

        setTitle(name+" - ShowImage");

        plot_area.loadChart(dir+name);

        this.show();

        fileExistWarning();
      }
    }

  }

  public void fileExistWarning()
  {
    File file=new File(dir+data_file_name);
    if (file.exists())
    {
      OkDialog d=new OkDialog(this,"Warning","A data file allready exist for this map.");
      /*d.show();
      d.dispose();*/
    }
  }


  public void processKeyEvent(KeyEvent e)
  {
    debug("key event: "+e.getID());
    if (e.getID()==KeyEvent.KEY_PRESSED)
    {
      debug("key code: "+e.getKeyCode());

      if (e.getKeyCode()==KeyEvent.VK_L) 
      {
        debug("left");
        plot_area.movePoint(-1,0);
        return;
      }
      if (e.getKeyCode()==KeyEvent.VK_R) 
      {
        debug("right");
        plot_area.movePoint(1,0);
        return;
      }
      if (e.getKeyCode()==KeyEvent.VK_U) 
      {
        debug("up");
        plot_area.movePoint(0,-1);
        return;
      }
      if (e.getKeyCode()==KeyEvent.VK_D) 
      {
        debug("down");
        plot_area.movePoint(0,1);
        return;
      }


    }
    super.processKeyEvent(e);
  }




  // The main constructor of this class.
  public ShowImage(String[] args)
  {
    super("ShowImage");

    debug("args.length "+args.length);

    int i=0;
    while (i<args.length)
    {
      if (args[i].charAt(0)!='-') break;
      if (args[i].length()<2) {help();}
      switch(args[i].charAt(1))
      {
        case 'h' : help();break;
        default  : help();break;
      }
      i++;
    }

    debug("i "+i);




    nwindows++;

    createMenu();

    // Another event listener, this one to handle window close requests.
    this.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) { close(); }
    });

    this.enableEvents(AWTEvent.KEY_EVENT_MASK);

    plot_area = new ShowImageComponent(this ,false, 1);
    debug("plot_area Created");



    load();

    pane=new ScrollPane();
    pane.setSize(400,300);

    this.add("Center", pane);
    debug("add pane done");


    pane.add("Center", plot_area);
    debug("plot_area");
        
    this.pack();
    debug("pack done");

    this.show();
    debug("show done");

    /*fileExistWarning();*/


    //debug("r "+ExitDialog.visa(this,"Warning","Are you ready?"));

  }

  /** Close a window.  If this is the last open window, just quit. */
  void close()
  {
    int r=ExitDialog.UNKNOWN;

    checkIfReady();

    debug("close "+needSave);

    if (needSave)
    {
      r=ExitDialog.visa(this,"There is unsaved data","Proceed without saving?");
    }

    if (r!=ExitDialog.CANCEL)
    {
      nwindows--;
      if (nwindows==0) System.exit(0);
      else this.dispose();
    }
  }

  // ShowImage can be used by other classes, or it can be
  // used standalone with this main() method.
  static public void main(String[] args) /*throws IOException */
  {
    debug("ShowImage");

    new ShowImage(args);
  }

}


