// 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: LayerDiagram.java
// Classes: LayerDiagram
// Original Author: Jason Robbins
// $Id: LayerDiagram.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.Vector;
import java.util.Enumeration;
import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.PrintGraphics;

/** A Layer like found in many drawing applications. It contains a
 * collection of DiagramElement's, ordered from back to front. Each
 * LayerDiagram contains part of the overall picture that the user is
 * drawing.  */

public class LayerDiagram extends Layer 
{

  /** The DiagramElement's that are contained in this layer */
  private Vector _contents = new Vector();

  /** A counter so that layers have default names like 'One', 'Two', ... */
  private static int _nextLayerNumbered = 1;

  /** Construct a new LayerDiagram with a default name and do not put
   * it on the Layer's menu. */
  public LayerDiagram() {
    this("Layer" + numberWordFor(_nextLayerNumbered++));
  }

  /** Construct a new LayerDiagram with the given name, and add it to
   * the menu of layers. Needs-More-Work: I have not implemented a
   * menu of layers yet. I don't know if that is really the right user
   * interface */
  public LayerDiagram(String name) {
    super(name);
    _onMenu = true;
  }

  /** A utility function to give the spelled-out word for numbers. */
  protected static String numberWordFor(int n) {
    switch(n) {
    case 1: return "One";
    case 2: return "Two";
    case 3: return "Three";
    case 4: return "Four";
    case 5: return "Five";
    case 6: return "Six";
    case 7: return "Seven";
    case 8: return "Eight";
    case 9: return "Nine";
    default: return "Layer " + n;
    }
  }

  /** Add a DiagramElement to the contents of this layer. Items are
   * added on top of all other items */
  public void add(DiagramElement de) {
    _contents.removeElement(de); // act like a set
    _contents.addElement(de);
    de.addObserver(this);
    de.endTrans();
  }

  /** remove the given DiagramElement from this layer */
  public void remove(DiagramElement de) {
    _contents.removeElement(de);
    de.endTrans();
    de.deleteObserver(this);
  }

  /** Enumerate over all DiagramElement's in this layer */
  public Enumeration elements() { return _contents.elements(); }

  /** Reply the contents of this layer. Do I really want to do this? */
  public Vector contents() { return _contents; }

  /** Reply the 'top' DiagramElement under the given (mouse)
   * coordinates. Needs-More-Work: For now, just do a linear search.
   * Later, optimize this routine using Quad Trees (or other)
   * techniques.  */
  public DiagramElement pick(int x, int y) {
    /* search backward so that highest item is found first */
    for (int i = _contents.size() - 1; i >= 0; i--) {
      DiagramElement de = (DiagramElement) _contents.elementAt(i);
      if (de.inside(x, y)) return de;
    }
    return null;
  }

  public DiagramElement pick(UID id)
  {
	  for (int i = 0;i<_contents.size();i++)
	  {
		  DiagramElement de = (DiagramElement) _contents.elementAt(i);
		  if (de.hasId(id)) return de;
	  }
	  return null;
  }
  /** Delete all DiagramElement's from this layer */
  public void removeAll() { _contents.removeAllElements(); }

  /** Find the DiagramElement that visualized the given NetNode in
  * this layer, or null if there is none. */
  public DiagramElement perspectiveFor(Object obj) {
    Enumeration prims = elements();
    while (prims.hasMoreElements()) {
      DiagramElement de = (DiagramElement) prims.nextElement();
      if (de.owner() == obj) return de;
    }
    return null;
  }

  /** Draw all the DiagramElement's that belong to this layer. */
  public void drawContents(Graphics g) 
  {
    Rectangle clip;
	if(g instanceof PrintGraphics) // This is for multiple page printing
		clip=Globals.getPrintClip();
	else
		clip= g.getClipBounds();
	Enumeration prims = elements();
	while (prims.hasMoreElements()) 
	{
		DiagramElement de = (DiagramElement) prims.nextElement();
		if (clip == null || de.getBoundingBox().intersects(clip))
		{
			de.draw(g);
		}
	}
  }

} /* end class LayerDiagram */

