/**
 * Title:        Teach and Presentation Tool<p>
 * Description:  A tool which enables you to create~npresentations and teach application like~nToolbook, Powerpoint or Director.<p>
 * Copyright:    Copyright (c) 2002<p>
 * Company:      University of Applied Sciences Wedel<p>
 * @author Christian Kohls, Tobias Windbrake
 * @version
 */

package TAPplugins;

import javax.swing.JComponent;
import javax.swing.ImageIcon;
import javax.swing.*;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.util.Enumeration;
import java.util.Vector;
import java.util.NoSuchElementException;
import java.io.*;
import TAP.*;



 public class TAPMinimalElement extends TAPElement implements
                MouseListener,MouseMotionListener {


  protected JMinimalComponent myComponent = new JMinimalComponent();

  protected static int nameCounter = 1;

  protected PGMinimal minimal;

  protected StandardEditTimeListener editListener;


  // Internal Properties:
  private int internalClickCounter = 0;        // to demonstrate internal data
  private int internalClickCounterStart = 0;
  private String lastMouseEvent = "no Event" ; // to demonstrate internal data

  // for dragging an element we need to remember it's orign,
  // these properties are use by the MouseMotionListene-implementation
  protected float xorign,yorign;


  // empty constructor:
  public TAPMinimalElement() {
  }

  // the constructor to make a copy needs all values of
  // the original element
  // it is not public because only an element itself is allowed to make
  // a copy of it.

  protected TAPMinimalElement(  PGLocation location,
                        PGSize size, PGMinimal minimal, String name, String subName,
                        int internalClickCounter, String lastMouseEvent) {

      // create listeners:
      this.editListener = new StandardEditTimeListener(this);

      // add the edit-mode-listeners to the component:
      myComponent.addMouseListener((MouseListener)this.editListener);
      myComponent.addMouseMotionListener((MouseMotionListener)this.editListener);


      // never shared property:
      this.name = name;
      this.subName = subName + "1";

      // copy internal properties:
      this.internalClickCounter = internalClickCounter;
      this.lastMouseEvent = lastMouseEvent;

      // using the same properties if shared or use an copy
      // if not shared:

      this.location = (PGLocation) assignGroup(location);
      this.size = (PGSize) assignGroup(size);
      this.minimal = (PGMinimal) assignGroup(minimal);

      // the default for split is that components are splitted at edit-time
      // if a component is allowed to be splitted at runtime the
      // java-implentation of the TCL-splitTAPElement-Command has to call
      // startTAP()
      isRuntime = false;

  }

  public void init() {

      // insert here a name-finder method
      name = "minimalElement" + String.valueOf(nameCounter++);
      subName = "sub_0";


      // create all Listeners for this element:
      // the listeners will be shared by all TAPElements which
      // use the same Jcomponent as well.
      // for this reason we have to notify the Listeners which
      // TAPElement shall be the owner to the current time,
      // we do this in the startElement()-method.
      editListener = new StandardEditTimeListener(this);

      // add the edit-mode-listeners to the component:
      myComponent.addMouseListener((MouseListener)editListener);
      myComponent.addMouseMotionListener((MouseMotionListener)editListener);

      // if the user is able to create components, it is edit-time (by default)
      // with exception of creating dynamic elements by TCL, for this
      // case the java-method which implements the TCL-createTAP-command
      // has to call startTAP() after creating the element
      isRuntime = false;

      // creatin properties with defalt values:
      location = new PGLocation();
      size = new PGSize();
      minimal = new PGMinimal();

  } // end method init


  // returns a copy of this element, references will point
  // to the same or a new crate object depending on if they
  // are shared or not
  public TAPElement getACopy(){
      return
         new TAPMinimalElement(location,size, minimal, name, subName,
                               internalClickCounter,lastMouseEvent);

  }

  public JComponent getComponent() {
     return myComponent;
  }

  public void startTAP() {
     // only if we change from edittime to runtime
     // (and not from runtime to runtime) we have to restart the properties
     // to store the current start values

     if (!isRuntime) {
       location.restartRuntime();
       size.restartRuntime();
       minimal.restartRuntime();
       myComponent.removeMouseListener(editListener);
       myComponent.removeMouseMotionListener(editListener);
       myComponent.addMouseListener(this);
       myComponent.addMouseMotionListener(this);
       requestUpdate();
       update();

     } // end if (!isRuntime)
     isRuntime = true;

  }

  public void stopTAP() {
     // only if we change from runtime to edittime
     // (and not from edittime to edittime) we have to reset the properties
     // to the values of the start of the runtime:

     if (isRuntime) {

       internalClickCounter = internalClickCounterStart;
       location.resetEdittime();
       size.resetEdittime();
       minimal.resetEdittime();

       myComponent.removeMouseListener(this);
       myComponent.removeMouseMotionListener(this);
       myComponent.addMouseListener(editListener);
       myComponent.addMouseMotionListener(editListener);
       update();

    } // end if (isRuntime)


    isRuntime = false;
  }

  public void startElement() {


  }

  public void stopElement() {

  }




   public String tell (String message, String layerName) {
        lastMouseEvent = "tell: " + message ;
        requestUpdate();
        update();
        return "wrote message to screen";
  }




   public TAPPropertyGroup propertyGroupAt(int index) throws NoSuchElementException {
      switch (index) {
        case 0: return PGName.getSingletonPGName();
        case 1: return location;
        case 2: return size;
        case 3: return minimal;
        default:  throw new NoSuchElementException("PGLocation contains only" +
                                                   "three property groups!");

      } // end switch

  } // end nextElement



  public void setPropertyGroup(TAPPropertyGroup newGroup){

     if (newGroup.getPropertyGroupName().equals("Location"))
         location = (PGLocation) newGroup;

     if (newGroup.getPropertyGroupName().equals("Size"))
         size = (PGSize) newGroup;

     if (newGroup.getPropertyGroupName().equals("Minimal"))
         minimal = (PGMinimal) newGroup;

  }



  public void update() {


    if (location.getVisibleCurr() || !this.isRuntime) {
      myComponent.setVisible(true);
      updateBounds(myComponent);

      myComponent.setInfoString( minimal.getStatement() + lastMouseEvent);
      myComponent.setOffset(minimal.getOffset());
      myComponent.setBold(minimal.getIsBold());
      myComponent.setClickCounter(String.valueOf(internalClickCounter));
      myComponent.repaint();

    } else myComponent.setVisible(false);

  }

  public String getElementType() {
      return
        "Minimal";
  }

  public ImageIcon getIconRepresentation() {
    Class c = TAPMinimalElement.class;
    return new ImageIcon(c.getResource("icons/mini.gif"));
  }

  public String getVersion() { return "v1_8.3.02" ; }



  public int getPropertyGroupCount() {
     return 4 ;  // PGName, PGLocation , PGSize , PGMinimal

  }

  public void saveInternalData(Writer outputFile) {
    this.writeInternalData(outputFile,"internalClickCounter",String.valueOf(internalClickCounter));
  }

  public void initInternalData(String dataName, String dataContent) {
      if (dataName.equals("internalClickCounter")) {
         internalClickCounterStart = Integer.valueOf(dataContent).intValue();
         internalClickCounter = internalClickCounterStart;
      }
  }

  // implentation of MouseListener:
  public void mouseClicked(MouseEvent e) {
      lastMouseEvent = "mouse was clicked.";
      internalClickCounter++;
      update();
  }

  public void mouseEntered(MouseEvent e) {
      lastMouseEvent = "mouse entered component.";
      update();

  }

  public void mouseExited(MouseEvent e) {
      lastMouseEvent = "mouse exited component.";
      update();

  }

  public void mousePressed(MouseEvent e) {
      lastMouseEvent = "mouse was pressed.";

      // to drag the element:
      if (location.getDragableCurr()) {
         xorign = e.getX();
         yorign = e.getY();
      }

      update();
  }

  public void mouseReleased(MouseEvent e) {
      lastMouseEvent = "mouse was released.";
      update();

  }

  public void mouseDragged(MouseEvent e) {

      // to drag the element:

      if (location.getDragableCurr()) {
           setPropertyRemote("x",String.valueOf( (e.getX() + xorign)/TAPBoard.currentBoard.getWidth() * 100)  );
           setPropertyRemote("y",String.valueOf( (e.getY() + yorign)/TAPBoard.currentBoard.getHeight() * 100)  );
           xorign = e.getX() + xorign;
           yorign = e.getY() + yorign;
       } // end if dragable


  }

  public void mouseMoved(MouseEvent e) {
  }


  public String toString() {
     return
       name + "." + subName;
  }





}




