/*
 * AnzeigeTabelle.java	01.07.99
 *
 *
 * Beilage zum Buch "Software-Entwurf mit UML"
 * von J.Seemann & J. Wolff von Gudenberg,
 * Springer-Verlag, 1999
 * 
 */

 
import java.awt.*;

/** <i>Objekt zur Anzeige der Tabelle, beeinhaltet auch das Popup-Menu</i> */ 

public class AnzeigeTabelle extends Panel 
{
  // Objektreferenzen
  static protected Tabkalk tabkalk;
  protected PopupMenu popup;
  protected AnzeigeZelle[][] ZellenAnzeige;
  protected AnzeigeZelle activeZelleAnzeige;
  protected Point MouseClickPoint;
  protected TabellenCursor cursor;
  public LeerZelle leerzelle;

	// Attribute
	protected int rows;
  protected int cols;

	// Methoden
  /** Zugriffsfunktion - liefert Objektreferenz */
	static public Tabkalk Tabkalk() { return tabkalk; }
  
	/** Zugriffsfunktion - liefert Objektreferenz */
	public TabellenCursor getTabellenCursor()  { return cursor; }

	/** Zugriffsfunktion - liefert Objektreferenz */
  public AnzeigeZelle getActiveZelleAnzeige()  { return activeZelleAnzeige; }
	
	/** zeigt das Popup-Menu an der angegebenen Position */
  public void showPopup(int x, int y)  
  { 
  	 popup.show(this,x,y); 
  }
  
	/** liefert das einzelne AnzeigeZelle-Objekt */
	public AnzeigeZelle getZelleAnzeige(int X, int Y)  
  {  
     AnzeigeZelle c = null;     
     if ((X < rows) && (Y < cols) && (X >= 0) && (Y >= 0))  
     {
        c = ZellenAnzeige[Y][X]; 
     }
     return c; 
  }

	/** liefert Anzahl der Spalten */
  public int getSpalten()  { return cols-1; }
  
	/** liefert Anzahl der Zeilen */
	public int getZeilen()  { return rows-1; }


  /** liefert Zelle an der angegebenen Position */
  public Zelle getZelle (int Zeile, int Spalte)
  {
     return ZellenAnzeige[Zeile][Spalte].getZelle();
  }
	

  /** setzt Zelle an die angegebene Position */
  public void setZelle (int Zeile, int Spalte, Zelle z)
  {
     ZellenAnzeige[Zeile][Spalte].setZelle(z);
  	 z.setAnzeige(ZellenAnzeige[Zeile][Spalte]);
  }

	/** setzt Leerzelle an die angegebene Position */
  public void setLeerZelle (int Zeile, int Spalte)
  {
     ZellenAnzeige[Zeile][Spalte].setZelle(leerzelle);
  }

  /** liefere die Zelle an der angegebenen Adresse */
  public Zelle getZelle (String Adresse)
  {
     int x = (int)Character.toUpperCase(Adresse.charAt(0)) - 65;
     int y = Integer.parseInt(Adresse.substring(1)) - 1;

     return ZellenAnzeige[y][x].getZelle();
  } 

  /** liefere die Spaltennummer zu einem gegebenen AnzeigeZellen-Objekt */
  public int getXIndex(AnzeigeZelle c)  
  { 
    for (int i=0; i<rows; i++) 
    {
       for (int j=0; j<cols-1; j++) 
       {
          if (c == ZellenAnzeige[i][j]) return j;
       }
    }
    return -1;
  }
  
  /** liefere die Zeilennummer zu einem gegebenen AnzeigeZellen-Objekt */
	public int getYIndex(AnzeigeZelle c)  
  { 
    for (int i=0; i<rows; i++) 
    {
       for (int j=0; j<cols-1; j++) 
       {
          if (c == ZellenAnzeige[i][j]) return i;
       }
    }
    return -1;
  }

  /* setze Markierung im angegebenen Bereich zur&uuml;ck */
  public void resetMarkierung()
  {
    for (int i=0; i<rows; i++) 
       for (int j=0; j<cols-1; j++) 
       {
          if (ZellenAnzeige[i][j].isMarkiert())
             {
                ZellenAnzeige[i][j].setMarkierung(false);
                setColor(ZellenAnzeige[i][j],0);
             }
       }
  }
	
	/** setze Markierung im angegebenen Bereich */
  public void setMarkierung(Position ObenLinks, Position UntenRechts)
  {
     for (int x = ObenLinks.getX(); x <= UntenRechts.getX(); x++)
         for (int y = ObenLinks.getY(); y <= UntenRechts.getY(); y++)
         {
             if (ZellenAnzeige[y][x].isMarkiert() == false)
             {
                ZellenAnzeige[y][x].setMarkierung(true);
                setColor(ZellenAnzeige[y][x],0);
             }
         }
  }
  
	/** Neuzeichnen aller Zellen in der Tabelle */
	public void refresh()
  {
    for (int i=0; i<rows; i++) 
       for (int j=0; j<cols-1; j++) 
       {
           if (ZellenAnzeige[i][j].getZelle() != leerzelle)
           {
              ZellenAnzeige[i][j].repaint();
           }
       }
  }

  /** tausche die Zelle an der angegebenen Position aus */
	public void aktualisiere(Position P, Zelle z)
  {
  	 int ausrichtung = 0;
  	 int nachkomma = 0;
  	 Zelle v = ZellenAnzeige[P.getY()][P.getX()].getZelle();
  	 
  	 if (v != leerzelle)
  	 {
  	    ausrichtung = v.getAusrichtung();
  	 	  nachkomma = v.getNachkomma();
  	 }
     ZellenAnzeige[P.getY()][P.getX()].setZelle(z);
  	 if (v != leerzelle)
  	 {
  	    z.setNachkomma(nachkomma);
  	 	  z.setAusrichtung(ausrichtung);
  	 }
     ZellenAnzeige[P.getY()][P.getX()].repaint();
  }

  
	// Konstruktor
	public AnzeigeTabelle(Tabkalk tabkalk, int rows, int cols)
  {
    this.tabkalk = tabkalk;
    this.rows = rows;
    this.cols = cols;

    ZellenAnzeige = new AnzeigeZelle[rows][cols];

    GridBagLayout gridBag = new GridBagLayout();
    GridBagConstraints c = new GridBagConstraints();
    setLayout(gridBag);

    // Tabelle mit Leerzellen initialisieren
  	//
  	char rowChar = 'A';
    int colNum = 1;

    int dummy = 1;
    c.fill = GridBagConstraints.BOTH;

    leerzelle = new LeerZelle();

    for (int i=0; i<rows; i++) 
    {
       for (int j=0; j<cols-1; j++) 
       {
          ZellenAnzeige[i][j] = new AnzeigeZelle(leerzelle);
          StringBuffer buf = new StringBuffer();
          buf.append(rowChar);
          buf.append(colNum);
          ZellenAnzeige[i][j].setSymName(buf.toString());
          colNum++;
          gridBag.setConstraints(ZellenAnzeige[i][j], c);
          add(ZellenAnzeige[i][j]);
       }

       c.gridwidth = GridBagConstraints.REMAINDER;
       ZellenAnzeige[i][cols-1] = new AnzeigeZelle(leerzelle);
       gridBag.setConstraints(ZellenAnzeige[i][cols-1], c);
       StringBuffer buf = new StringBuffer();
       buf.append(rowChar);
       buf.append(colNum);
       ZellenAnzeige[i][cols-1].setSymName(buf.toString());
       add(ZellenAnzeige[i][cols-1]);
       c.gridwidth = 1;
       rowChar++;
       colNum = 1;
    }

    // Erzeugung des Popup-Menues
    // 
    String[] labels = new String[] {"Gehe zu", "Bearbeiten", "Undo", "Ausrichtung", "Neu" };
    popup = new PopupMenu();

    MenuItem item;
    Menu submenu;

    item = new MenuItem("Gehe zu");
    item.addActionListener(new KOMMANDO_GeheZu());
    popup.add(item);

    submenu = new Menu("Bearbeiten");
    item = new MenuItem("Ausschneiden");
    item.addActionListener(new KOMMANDO_Ausschneiden());
    submenu.add(item);
    item = new MenuItem("Kopieren");
    item.addActionListener(new KOMMANDO_Kopieren());
    submenu.add(item);
    item = new MenuItem("Einfügen");
    item.addActionListener(new KOMMANDO_Einfuegen());
    submenu.add(item);
    popup.add(submenu);

    item = new MenuItem("Undo");
    item.addActionListener(new KOMMANDO_Undo());
    popup.add(item);

    submenu = new Menu("Ausrichtung");
    item = new MenuItem("Links");
    item.addActionListener(new KOMMANDO_Ausrichtung(Zelle.LINKS));
    submenu.add(item);
    item = new MenuItem("Zentriert");
    item.addActionListener(new KOMMANDO_Ausrichtung(Zelle.MITTE));
    submenu.add(item);
    item = new MenuItem("Rechts");
    item.addActionListener(new KOMMANDO_Ausrichtung(Zelle.RECHTS));
    submenu.add(item);
    popup.add(submenu);

    submenu = new Menu("Nachkommastellen");
    item = new MenuItem("keine");
    item.addActionListener(new KOMMANDO_Nachkomma(0));
    submenu.add(item);
    item = new MenuItem("1");
    item.addActionListener(new KOMMANDO_Nachkomma(1));
    submenu.add(item);
    item = new MenuItem("2");
    item.addActionListener(new KOMMANDO_Nachkomma(2));
    submenu.add(item);
    item = new MenuItem("3");
    item.addActionListener(new KOMMANDO_Nachkomma(3));
    submenu.add(item);
    item = new MenuItem("5");
    item.addActionListener(new KOMMANDO_Nachkomma(5));
    submenu.add(item);

    popup.add(submenu);
    this.add(popup);


    TabelleEventHandler th = new TabelleEventHandler(this);
    addMouseListener(th);
    addKeyListener(th);

    cursor = new TabellenCursor(this);

    this.requestFocus();
  }


	/** setze Farbe der entsprechenden Zelle */
  public void setColor(AnzeigeZelle C, int Flag)
  {
     if (C.isMarkiert())
     {
        if (Flag == 0)
        {
           C.setBackground(Tabkalk.markBackground);
           C.setForeground(Tabkalk.markForeground);
        }
        else
        {
           C.setBackground(Tabkalk.highmarkBackground);
           C.setForeground(Tabkalk.highmarkForeground);
        }
     }
     else
     {
        if (Flag == 0)
        {
           C.setBackground(Tabkalk.normBackground);
           C.setForeground(Tabkalk.normForeground);
        }
        else
        {
           C.setBackground(Tabkalk.highBackground);
           C.setForeground(Tabkalk.highForeground);
        }
     }
     
     C.repaint();
  }
}