/*
* viewwin.h
* DIN Is Noise is copyright (c) 2006-2024 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/

#ifndef __viewwin
#define __viewwin

#include "box.h"

struct viewport { // opengl viewport

  // for constant size handle of vertex/tangent in curve editors
  //
  static int handle_radius;
  static float handle_factor;

  int width, height;
  int xmax, ymax;
	int midx, midy;

  float xmax_1, ymax_1; // 1.0 / xmax , 1.0 / ymax

  viewport ();
	~viewport ();
  void operator() (int width, int height);
  void calc (int w, int h);
  bool inside (int x, int y);

};

struct window : box<float> { // curve editor

  float mousex, mousey; 
  float mousex_prev, mousey_prev; 
  int prev_mousex, prev_mousey; // prev mouse in mouse co-ords

  void locate_mouse (); 
  void update_mouse (); 
	int diff_mouse (float& dx, float& dy); 

  float vwx, vwy; // for view-win transform; to locate mouse in window
  void calc_viewwin ();

  static int PAN_RATE, ZOOM_RATE;
  static float PAN_AMOUNT, ZOOM_AMOUNT;
  static double PAN_REPEAT, ZOOM_REPEAT;
  static void calc_repeats ();

  float pan_x, pan_y;
  void calc_panxy ();
  void panx (int dir);
  void pany (int dir);

  float aspect_ratio;

  window ();
  window (float l, float b, float r, float t);
  void set (float l, float b, float r, float t);
  void get (float& l, float& b, float& r, float& t);

  void zoom (int dir);

  void project ();

  float handle_radius, handle_radius2;
  float sus_handle_radius;
  void calc_handle_radius ();

  void calc ();

};

void view2win (int vx, int vy, float& wx, float& wy, viewport& view, window& win);
void win2view (float wx, float wy, int& vx, int& vy, window& win, viewport& view);

template <typename T> void win2view (float wx, float wy, int& vx, int& vy, box<T>& win, viewport& view) {
  float xr = (wx - win.left) * win.width_1;
  float yr = (wy - win.bottom) * win.height_1;
  vx = (int) (xr * view.xmax + 0.5);
  vy = (int) (yr * view.ymax + 0.5);
}

template <typename T> void view2win (int vx, int vy, float& wx, float& wy, viewport& view, box<T>& win) {
  float xr = vx * view.xmax_1;
  float yr = vy * view.ymax_1;
  wx = win.left + xr * win.width;
  wy = win.bottom + yr * win.height;
}

extern viewport view;

#endif
