// ============================================================================
// File:               ClipTest.java
//
// Project:            Testing of clipping
//
// Purpose:            Test of workaround for Java 1.2/1.3 problem with line drawing
//
// Author:             Rammi
//
// Copyright Notice:   (c) 2000  Rammi (rammi@quincunx.escape.de)
//                     The usage of this source code is free. Use at your own
//		       risk.
//=============================================================================


// import de.caff.gimmicks.Clipping;

import java.awt.*;
import java.awt.event.*;
import java.util.*;

import javax.swing.*;


/**
 *  This is a simple class to test the clipping routines provided by
 *  the Clipping class.
 *  @see de.caff.gimmicks.Clipping;
 *
 *  @author Rammi <rammi@caff.de>
 */
public class ClipTest extends JComponent implements MouseListener, MouseMotionListener {
  private final static Rectangle clip      = new Rectangle(100, 100, 200, 100);
  private Vector    polylines = new Vector();
  private Polyline  active    = null;
  private Point     last      = null;
  private Point     pos       = null;

  private static class Polyline {
    int[] x = new int[2];
    int[] y = new int[2];
    int   nPoints = 0;

    public Polyline(int px, int py) {
      add(px, py);
    }

    public void add(int px, int py) {
      if (nPoints == x.length) {
	int[] tmp = new int[2*x.length];
	System.arraycopy(x, 0, tmp, 0, x.length);
	x = tmp;
      }
      if (nPoints == y.length) {
	int[] tmp = new int[2*y.length];
	System.arraycopy(y, 0, tmp, 0, y.length);
	y = tmp;
      }
      
      x[nPoints] = px;
      y[nPoints] = py;
      ++nPoints;
    }

    public void draw(Graphics g) {
      g.setColor(Color.blue);
      g.drawPolyline(x, y, nPoints);
    }

    public void draw(Graphics g, Rectangle rect) {
      g.setColor(Color.red);
      Clipping.drawPolyline(g, x, y, nPoints, rect);
    }
  }

  public ClipTest() {
    setDoubleBuffered(true);
    addMouseListener(this);
    addMouseMotionListener(this);
  }

  /**
   *  This does the real testing.
   *  1st all lines are drawn in blue, then a yellow rectangle is drawn over the
   *  lines, then all lines are drawn clipped in red. So inside the rectangle
   *  everything should appear in red, outside in blue.
   */
  public void paintComponent(Graphics g) {
    // paint the complete polylines
    for (Enumeration l = polylines.elements();  l.hasMoreElements();  ) {
      Polyline p = (Polyline)l.nextElement();
      p.draw(g);
    }

    // draw rectangle
    g.setColor(Color.yellow);
    g.fillRect(clip.x, clip.y, clip.width, clip.height);
 
    // paint the clipped polylines
    for (Enumeration l = polylines.elements();  l.hasMoreElements();  ) {
      Polyline p = (Polyline)l.nextElement();
      p.draw(g, clip);
    }

    if (last != null  &&  pos != null) {
      g.setColor(Color.black);
      g.drawLine(last.x, last.y, pos.x, pos.y);
    }

  }

  public void mouseClicked(MouseEvent e) {
    int mod = e.getModifiers();

    if ((mod & MouseEvent.BUTTON2_MASK) != 0) {
      polylines.clear();
      active = null;
      last = pos = null;
    }
    else if ((mod & MouseEvent.BUTTON3_MASK) != 0) {
      active = null;
      last = pos = null;
    }
    else {
      if (active != null) {
	last = e.getPoint();
	active.add(last.x, last.y);
      }
      else {
	last = e.getPoint();
	active = new Polyline(last.x, last.y);
	polylines.addElement(active);
      }
    }

    repaint();
  }

  public void mouseEntered(MouseEvent e) {    
  }

  public void mouseExited(MouseEvent e) {    
  }

  public void mousePressed(MouseEvent e) {    
  }

  public void mouseReleased(MouseEvent e) {    
  }

  public void mouseDragged(MouseEvent e) {
  }

  public void mouseMoved(MouseEvent e) {
    if (last != null) {
      pos = e.getPoint();
      repaint();
    }
  }

  public static void main(String[] args) {
    JFrame frame = new JFrame("Clipping test");

    frame.getContentPane().add(new ClipTest());
    frame.setSize(2*(clip.x+clip.width), 2*(clip.y+clip.height));
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
	System.exit(0);
      }
    });
    frame.show();
  }

}

