#include <iostream>
#include <cmath>
#include "../xwin_tools/xwin_tools.h"

using namespace std;
using namespace xwin_tools;

double sin0(double x);
#define screen_width 640
#define screen_height 480
#define pi M_PI

double freq = 50;
int amp = 100;

class MyWindow : public Frame {
public:
   MyWindow() 
   : Frame("Sin wave...", 640, 480) { 
   }

   ~MyWindow() { 

   }

   void on_paint(Graphics & g) {
      g.set_color(Color(0,0,0));
      int y;
      int last_x = 0; 
      int last_y = 0;
      for(int x = 1; x < 640; x++) {
         y = (sin0(x/freq)*amp) + 200;
         g.draw_line(last_x,last_y,x,y);
         last_x = x;
         last_y = y;
      }
   }

   void on_mouse_move(const size_t x, const size_t y) {
   }

   void on_click(const size_t x, const size_t y) {
   }

   void on_key_press(const char ch) {
   }
  
   void on_resize(const size_t w, 
                  const size_t h) {
      g.set_color(Color(32000,65000,32000));
      Frame::on_resize(w,h);
   }

   void on_close_window() {
      exit(0);
   }
};

double 
mod(double x)
{
   double rem = remainder(x, 2.0 * pi);
   return rem;
}

double _pow(double a, double b) {
   double c = 1;
   for(int i = 0; i < b; i++) {
      c *= a;
   }
   return c;
}

double _fact(double x) {
   double ret = 1;
   for(int i = 1; i <= x; i++)
      ret *= i;
   return ret;
}

/*
1 = ((x-h)^2 / a^2) + ((y-k)^2 / b^2) 
1 - ((x-h)^2 / a^2) = ((y-k)^2 / b^2)
1 - ((x-h)^2 / a^2) = (y-k)^2 * (1 / b^2)
(1 - ((x-h)^2 / a^2)) / (1 / b^2) = (y-k)^2
sqrt((1 - ((x-h)^2 / a^2)) / (1 / b^2)) = y-k
sqrt((1 - ((x-h)^2 / a^2)) / (1 / b^2)) + k = y
sqrt((1 - (pow((x-h),2.0) / pow(a,2.0))) / (1 / pow(b,2.0))) + k = y
*/
double
sin0(double x)
{
/*
   double h = 1.0;
   double k = 1.0;
   double a = 1.0;
   double b = 1.0;
   double y = sqrt((1.0 - (pow((mod(x)-h),2.0) / pow(a,2.0))) / (1 / pow(b,2.0))) + k;
*/
   double y = x;
   double s = -1;
   for(int i = 3; i <= 100; i += 2) {
      y += s*(_pow(x,i)/_fact(i));
      s *= -1;
   }
/*
   double res= 0, pow =x,fact= 1;
   for(int i = 0; i < 5; i++) {
      res += pow / fact;
      pow *= x * x;
      fact *= (2*(i+1)) * (2*(i+1)+1);
   }
*/
   return y;
}

int
main()
{
   MyWindow my_win;
   return my_win.run();
   return 0;
}

#include "../xwin_tools/xwin_tools.cpp"
