/* @(#) Zoom.java 1.1 99/11/18
 * Copyright (c) 1999 Lawrence Rodrigues
 */
package com.vistech.imageviewer;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
/** Zooms an image displayed on a canvas.
 * The canvas object must implement the ImageManipulator interface.
 * @version 1.0  18 Nov 1999
 * @author Lawrence Rodrigues
 **/
public class Zoom  implements ZoomController, Serializable {
   protected AffineTransform atx = new AffineTransform();
   protected boolean magOn = true;
   protected double magFactor = 1.0;
   protected double magFactorX = 1.0, magFactorY = 1.0;
   protected int magCenterX = 0;
   protected int magCenterY =0;
   protected Point zoomOffset = new Point(0,0);
   protected ImageManipulator imageCanvas;

   public Zoom(){}

   /** @param imagecanvas the component on which the image is drawn.
   */
   public Zoom(ImageManipulator imageCanvas){ this.imageCanvas = imageCanvas;}

   /** @param imagecanvas the component on which the image is drawn.
   */
   public void setImageManipulator(ImageManipulator imageCanvas){
      this.imageCanvas = imageCanvas;
   }

   public  void setMagOn(boolean onOff){ magOn = onOff;}
   public  boolean getMagOn(){ return magOn; }

   public void setMagFactor(double magFactor){
      this.magFactor = magFactor;
      imageCanvas.setMagFactor(magFactor);
   }

   public void setMagFactorX(double magFactorX){
      this.magFactorX = magFactorX;
      imageCanvas.setMagFactorX(magFactorX);
   }

   public void setMagFactorY(double magFactorY){
      this.magFactorY = magFactorY;
      imageCanvas.setMagFactorY(magFactorY);
   }

   public double getMagFactor(){ return magFactorX;}
   public double getMagFactorX(){ return magFactorX;}
   public double getMagFactorY(){ return magFactorY;}


   public void magnify(int magCenterX, int magCenterY){
       magnify(magCenterX, magCenterY, magFactorX, magFactorY);
   }

   public void magnify(int magCenterX, int magCenterY, double magFac ){
      magnify(magCenterX, magCenterY, magFac, magFac);
   }

   public void magnify(int magCenterX, int magCenterY, double magFacX, double magFacY ){
      setMagFactorX(magFacX);
      setMagFactorY(magFacY);
      this.magCenterX = magCenterX;
      this.magCenterY = magCenterY;
      Point panOffset = imageCanvas.getPanOffset();
      int x = (int)((magCenterX-panOffset.x)*magFactorX)-magCenterX;
      int y = (int)((magCenterY-panOffset.y)*magFactorY)-magCenterY;
      atx = imageCanvas.getTransform();
      atx.setToTranslation(-x, -y);
      atx.scale(magFactorX, magFactorY);
      applyTransform(atx);
   }

   public void paintImage(int magCenterX, int magCenterY, double mag){
      paintImage(magCenterX, magCenterY, mag, mag);
   }

   public void paintImage(int magCenterX, int magCenterY, double magX, double magY){
      setMagFactorX(this.magFactorX *magX);
      setMagFactorY(this.magFactorX *magY);
      int dx = this.magCenterX -magCenterX;
      int dy = this.magCenterY-magCenterY;
      this.magCenterX = magCenterX;
      this.magCenterY = magCenterY;
      try {
        Point2D mgp = null;
        atx = imageCanvas.getTransform();
        mgp = atx.inverseTransform((Point2D)(new Point(magCenterX, magCenterY)),(Point2D)mgp);
        double x = (mgp.getX()*magX)-mgp.getX();
        double y = (mgp.getY()*magY)-mgp.getY();
        scale(-x,-y, magX, magY);
      }catch (Exception e) {System.out.println(e); }
   }

   public void scale(double magOffsetX, double magOffsetY, double magX, double magY){
      atx.translate(magOffsetX,magOffsetY);
      atx.scale(magX,magY);
      applyTransform(atx);
   }

   public void resetAndScale(double magOffsetX, double magOffsetY, double magX, double magY){
      atx.setToTranslation(magOffsetX,magOffsetY);
      atx.scale(magX,magY);
      applyTransform(atx);
  }

   public void applyTransform(AffineTransform atx) {
      imageCanvas.applyTransform(atx);
   }

   public void reset() {
      magCenterX = 0;
      magCenterY =0;
      magFactor = 1.0;
      magFactorX = 1.0;
      magFactorY = 1.0;
  }
}
