#ifndef WINDOWSCALED2_H
#define WINDOWSCALED2_H

#include <typedefs.h>

// TODO static global windows quad1, quad2, quad3, quad4
//   (-1,-1)(1,1) window, (-0.5,-0.5)(0.5,0.5) window

// TODO - axes eg x=0 line
//             y=5
// Notches in axes.
// Label axes, spec this and document.

/*!
\brief Support 

Let S be the coordinate space.
Let S' be the same space scaled:
 (xmin,ymin) to (0,0).
 (xmax,ymax) to (1,1).
*/
class windowscaleD2
{
public:

  /** Unit window at 1st quadrant. */
  static windowscaleD2 unit;

  /** Unit window with center at origin. */
  static windowscaleD2 unitcentered;

  /** x left */
  double xmin;
  /** y bottom */
  double ymin;
  /** x right */
  double xmax;
  /** y top */
  double ymax;

  /** Construct in a bad state. */
  windowscaleD2();

  /** Create the window. */
  windowscaleD2
  (
    doublec xmin_, 
    doublec xmax_, 
    doublec ymin_, 
    doublec ymax_ 
  );

  /** Create the window. */
  void construct
  (
    doublec xmin_, 
    doublec xmax_, 
    doublec ymin_, 
    doublec ymax_ 
  );

  /** 1/(xmax-xmin) */
  double oneoverxlength;
  /** 1/(ymax-ymin) */
  double oneoverylength;

  /** Get the width divided by height ratio. */
  doublec widthoverheight() const;
  /** Get the height divided by width ratio. */
  doublec heightoverwidth() const;

  /** Is the point inside the box? */
  boolc isinside(doublec x, doublec y) const;


  /** Recalculate after changes to window dimensions. */
  void update();

  /** Convert (x,y) from other window to this one. */
  boolc convertfrom
  (
    double & x, 
    double & y, 
    windowscaleD2 const & w2
  ) const;

  /** Converts to ratio point in S to S'. */
  boolc unitscale(double & x, double & y) const;
  /** Converts the ratio point in S' to S. */
  void unitscaleInverse(double & x, double & y) const;
  /** Convert from ratio in x-axis only. */
  void unitscaleInverse_x(double & x) const;
  /** Convert from ratio in y-axis only. */
  void unitscaleInverse_y(double & y) const;

  /** Translate the window in the X-axis. */
  void shiftx(doublec x);
  /** Translate the window in the Y-axis. */
  void shifty(doublec y);
  /** Translate the window in the X and Y axes. */
  void shiftxy(doublec x, doublec y);

  /** Move the window so bottom left of the window 
      is at the origin. */
  void shiftquadrant1();
  /** Move the window so bottom right of the window 
      is at the origin. */
  void shiftquadrant2();
  /** Move the window so top right of the window 
      is at the origin. */
  void shiftquadrant3();
  /** Move the window so top left of the window 
      is at the origin. */
  void shiftquadrant4();
  /** Center the window in the X-axis. */
  void shiftcenterx();
  /** Center the window in the Y-axis. */
  void shiftcentery();
  /** Center the window in the X and Y axes. */
  void shiftcenterxy();

  /** Multiply xmin, xmax by scale. */
  void scalex(doublec scale);
  /** Multiply ymin, ymax by scale. */
  void scaley(doublec scale);
  /** Multiply xmin, xmax, ymin, ymax by scale. */
  void scalexy(doublec scale);

  /** Serialize this object by writing it out as a string. */
  operator stringc() const;
  /** Construct object from a string. */
  void serializeInverse(stringc & s);

  /** (0,0) (1,1) */
  void unitwindow();
};

#endif



