// Copyright (c) 1995, 1996 Regents of the University of California.
// All rights reserved.
//
// This software was developed by the Arcadia project
// at the University of California, Irvine.
//
// Redistribution and use in source and binary forms are permitted
// provided that the above copyright notice and this paragraph are
// duplicated in all such forms and that any documentation,
// advertising materials, and other materials related to such
// distribution and use acknowledge that the software was developed
// by the University of California, Irvine.  The name of the
// University may not be used to endorse or promote products derived
// from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

// File: Layer.java
// Classes: Layer
// Original Author: Jason Robbins
// $Id: Layer.java,v 1.2 2000/09/19 21:08:32 dougo Exp $

// Modified by : Kedar Patankar

package edu.neu.ccs.demeter.tools.apstudio.graphedit;

import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
import java.util.Enumeration;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Point;

/** A Layer is like a drawing layer in high-end drawing applications
 * (e.g., MacDraw Pro). A Layer is like a sheet of clear plastic that
 * can contain part of the picture being drawn and multiple layers are
 * put on top of each other to make the overall picture. Different
 * layers can be hidden, locked, or grayed out independently. In The
 * UCI Graph Editing Framework the Layer class is more abstract than
 * described above. LayerDiagram is a Subclass of Layer that does what
 * is described above. Other subclasses of Layer can provide
 * functionality. For example the background drawing grid is a
 * subclass of Layer that computes its display rather than displaying
 * what is stored in a data structure. Generalizing the concept of a
 * layer to handle grids and other computed display features gives
 * more power and allows the framework to be extended in building
 * various applications. For example an application that needs polar
 * coordinates might use LayerPolar, and an application that used a
 * world map might implement LayerMap. But since layers can be
 * composed, the user could put a grid in front of or behind the map. <p>
 *
 * This approach to implementing drawing editors is described in one
 * or more published papers.. UIST?
 *
 * @see LayerDiagram
 * @see LayerGrid
 * @see LayerPolar */

public abstract class Layer extends Observable implements Observer {

  /** The name of the layer as it should appear in a menu */
  private String _name = "aLayer";

  /** Does the user not want to see this layer right now? */
  private boolean _hidden = false;

  /** Is this layer demphasized by making everything in it gray? */
  private boolean _grayed = false;

  /** Is this layer locked so that the user can not modify it? */
  private boolean _locked = false;

  /** Should the user be able to hide, lock, or gray this layer? */
  protected boolean _onMenu = false;


  /** Construct a new layer. This abstract class really does nothing
   * in its constructor, but subclasses may have meaningful constructors. */
  public Layer() { }

  /** Set the name of the layer */
  public Layer(String name) {
    _name = name;
  }

  /** Reply a string useful for debugging */
  public String toString() {
    return super.toString() + "[" + _name + "]";
  }

  /** If this layer has the given name then return 'this', else null */
  public Layer findLayerNamed(String aName) {
    if (aName.equals(_name)) return this;
    else return null;
  }

  /** Draw this Layer on the given Graphics. Sublasses should define
   * methods for drawContents, which is called from here if the layer
   * is not hidden. */
  public void draw(Graphics g) {
    if (_hidden) return;
    if (! _grayed) drawContents(g); else drawGrayContents(g);
  }

  /** Draw the contents of this layer, subclasses must define
   * this. For example, LayerDiagram draws itself by drawing a list of
   * DiagramElement's and LayerGrid draws itself by drawing a lot
   * lines. */
  public abstract void drawContents(Graphics g);

  /** Draw the contents in a dimmed, demphasized way. Calls
   * drawContents. Needs-More-Work:
   * really needs a new kind of Graphics to work right. */
  public void drawGrayContents(Graphics g) {
    g.setColor(Color.lightGray);
    // g.lockColor();
    drawContents(g);
    // g.unlockColor();
  }

  /** get and set methods */
  public void hidden(boolean b) { _hidden = b; }
  public boolean hidden() { return _hidden; }

  public void grayed(boolean b) { _grayed = b; }
  public boolean grayed() { return _grayed; }

  public void locked(boolean b) { _locked = b; }
  public boolean locked() { return _locked; }

  public void onMenu(boolean b) { _onMenu = b; }
  public boolean onMenu() { return _onMenu; }

  public Vector contents() { return null; }

  /** Most layers contain things, so I have empty implementations of
   * add, remove, removeAll, elements, and pick.
   *
   * @see LayerDiagram */
  public void add(DiagramElement de) { }
  public void remove(DiagramElement de) { }
  public void removeAll() { }
  public Enumeration elements() { return (new Vector()).elements(); }
  public final DiagramElement pick(Point p) { return pick(p.x, p.y); }
  public DiagramElement pick(int x, int y) { return null; }
  public DiagramElement pick(UID id) {return null;}


  /** Given an object from the net-level model (e.g., NetNode or
   * NetPort), reply the graphical depiction of that object in this
   * layer, if there is one. Otherwise reply null. */
  public DiagramElement perspectiveFor(Object obj) { return null; }


  /** When an object contained in a Layer changes state it notifies
   * the Layer. The Layer in turn notifies its parent Layer or some
   * Editor's */
  public void update(Observable o, Object arg) {
    setChanged();
    notifyObservers(arg);
  }

  /** Allow the user to edit the properties of this layer (not the
   * properties of the contents of this layer). For example, in
   * LayerGrid this could set the grid size.  @see LayerGrid */
  public void adjust() {
    // subclasses implement this to being up dialog boxes with
    // prefernces related to that particular layer
    // needs-more-work: generic layer dialog box
  }


} /* end class Layer */


