#include <psychlops.h>
using namespace Psychlops;	// Initially developed with Psychlops Win32 1.0.2 / 20080414

/*
class Palette {
	Color elem[256];
	Image LUT;
	Palette() {
		LUT.set(523, 1);
		const int HEADER[12*3] = {
			36,106,133,63,136,163,8,19,138,211,25,46,3,115,164,112,68,9,56,41,49,34,159,208,
			0,0,0,0,0,0,0,0,0,0,0,0
		};
		for(int i=0; i<12; i++) {
			LUT.pix(i,0,Color(HEADER[i*3]/255.0, HEADER[i*3+1]/255.0, HEADER[i*3+2]/255.0));
		}
	}
};

*/

const double LOG2E = 1.44269504088896340736;
const double SIXSD = 1.15/2;
double bind(double x) {	return Math::normalDistibution(log(x)*LOG2E, 3, 1); }
double bind2(double x) {	return Math::cumulativeNormalDistibution(log(x)*LOG2E, 4, SIXSD); }
double bind3(double x) {	return 1-Math::cumulativeNormalDistibution(log(x)*LOG2E, 3, SIXSD); }

double hoge;
AnalogInput *analog;
void watcher() {
	while(true) {
		hoge = analog->get();
		Prototype::Thread::sleep(1000000);
	}
}

class RectLuminance : public ExperimentalMethods::Demo {
    Canvas display;
    double tf, tmp;
    int numstim;
    int orientation;

    Image base;
    Group gp;

    Letters let;
    Figures::FunctionalPlot c;
    Prototype::Thread thread;

    void initialize() {
        display.set(Canvas::window);
        c.set(500,500).shift(0,300).centering();
        c.append(&bind);
        c.append(&bind2);
        c.append(&bind3);
        c.x_max = 50;
        c.x_min = 0.01;
        c.y_max = 1;
        c.y_min = -0.5;

        Interval itv;
        Independent << tf          | "Temporal Frequency"   | -1.0<=itv<=3.0 |  1 | 0.5 , 1.0;
        Independent << orientation | "Stimulus Orientation" |  0.0<=itv<=3   |  1 | 1 , 0,1,2,3;
        Independent << numstim     | "Stimulus Alignment"   |  0.0<=itv<=2   |  1 | 1 , 0;

        Color col;

        base.set(100,100);
        for(int x=-50; x<50; x++) for(int y=-50; y<50; y++) base.pix(x+50,y+50,col.set(x*x+y*y>50*50? 0.5 : (y+50)/100.0));
        base.quicken();
        base.join(gp).centering(gp);
        gp.centering();


		AnalogOutput *analogout = new Devices::AnalogOutput_NIDAQmxBase();
		analogout->put(5);
		delete analogout;
		analog = new Devices::AnalogInput_NIDAQmxBase();
		thread.create(&watcher);
     }

    void trial() {

        Psychlops::Rectangle mask(102,102);
        double phase = 0;
        Color col;
        while(!Input::get(Keyboard::esc)) {
            phase = Math::mod(phase+2*PI*pow(2,tf)/display.getRefreshRate(), 2*PI);

            display.clear(Color::gray);

            if(numstim>0) {
                for(int x=-1; x<=1; x++ ) {
                    for(int y=-1; y<=1; y++ ) {
                        gp.rotation = orientation*90 +180*(cos(phase)<0 ? 1 : 0);
                        gp.centering().shift(x*102, y*102).draw();
                        mask.centering(gp);
                        mask.draw(col.set(.5,.5,.5,sin(phase)*(sin(phase)<0 ? -1 : 1)));
                    }
                }
            }

            gp.rotation = orientation*90 +180*(cos(phase)<0 ? 1 : 0) + 180*(numstim==2 ? 1 : 0);
            gp.centering().draw();

            mask.centering(gp);
            mask.draw(col.set(.5,.5,.5,sin(phase)*(sin(phase)<0 ? -1 : 1)));
            Display::var(Mouse::x, 300,300);
            Display::var(Mouse::y, 300,320);


			display.var(Mouse::getWheelDelta().y, 100, 100);
			display.var(Mouse::left.pressed(), 100, 120);
			display.var(hoge, 100, 140);
            c.draw();
            let.centering().draw(Color::red);
            display.flip();
        }
    }

};

void psychlops_main() {
    RectLuminance * exp = new RectLuminance;
    exp->run();
    delete exp;
}


/*
void YamaGraph(const Psychlops::Rectangle &area, const Interval &itvl, double (*func)(double) ) {
	double xbegin = itvl.begin.value, xend = itvl.end.value, xdiff = xend-xbegin;
	double x, y, lasty = 0;
	for(int i=0; i<area.getWidth(); i++) {
		x = xbegin + xdiff*i/area.getWidth();
		y = 10*func(x);
		Display::line(area.getLeft()+i, area.getTop(), area.getLeft()+i, area.getTop()+y, Color::red);
	}
}

void psychlops_main() {
	Canvas c(Canvas::window);

	Psychlops::Rectangle area(100,100);
	area.centering();

	Interval itvl = Interval(0,2*PI);
	while(!Keyboard::esc.pushed()) {
		c.clear();
		YamaGraph(area, itvl, &sin);
		c.flip();
	}
}
*/


/*
class MotionOfHybridImage : public ExperimentalMethods::Demo {
	Canvas canvas;
	double x, y;
	double a;

	void initialize() {
		canvas.set(800,600, Canvas::window, Display::secondary);

		Interval rng;
		Independent << x    | "x"     |  -500<=rng<= 600.0 |  10    |  .0625   , 0;
		Independent << y    | "y"     |  -500<=rng<= 600.0 |  10    |  .0625   , 0;
		Independent << a    | "a"     |     0<=rng<=   1.0 |  .125  |  .0625  , 0.5;

		canvas.showFPS();
		canvas.watchFPS();
		Mouse::show();
	}

	void trial() {
		Psychlops::Rectangle rect(100,100), dot(1,1);
		Image img(102,102), full(300,200);
		for(int x=0;x<102;x++) { img.pix(x,0,Color::yellow); img.pix(x,101,Color::yellow); }
		for(int y=0;y<102;y++) { img.pix(0,y,Color::yellow); img.pix(101,y,Color::yellow); }
		//img.quicken();
		full.clear();//.shift(2,1).quicken();
		dot.shift(0,0);

		Color gridc(0,.2,0);

		while(!Keyboard::esc.pushed()) {
			canvas.clear(Color::black);
			for(int xx=0; xx<canvas.getWidth()/2; xx++)  canvas.line(xx*2, 0,xx*2, canvas.getHeight()-1, gridc);
			for(int yy=0; yy<canvas.getHeight()/2; yy++) canvas.line(0, yy*2, canvas.getWidth()-1, yy*2, gridc);
			full.draw();
			dot.draw(Color::red);
			canvas.pix(canvas.getWidth()-1,canvas.getHeight()-1,Color::red);

//			rect.centering().shift(x-100,y).draw(Color::red);
			img.centering().shift(x-100,y).draw(a);

			img.centering().shift(x+100,y).draw();
			rect.centering().shift(x+100,y).draw(Color::red);
			canvas.flip();
			//y+=0.001;
		}
	}

};


void psychlops_main() {

	MotionOfHybridImage *exp = new MotionOfHybridImage;
	exp->run();
	delete exp;

}
*/

/*

#include <psychlops.h>
using namespace Psychlops;



class GaussianEnvelope : public Image {
public:
	GaussianEnvelope(double sigma) {
		Color col;

		int size = Math::round(sigma*6), halfsize = size/2;
		int particle = (halfsize*2 == size) ? 0 : 1;
		Image::set(size, size, Image::RGBA);

		for(int y=-halfsize; y<halfsize+particle; y++) {
			for(int x=-halfsize; x<halfsize+particle; x++) {
				alpha(x+halfsize, y+halfsize, gaussian(sigma,x) * gaussian(sigma,y));
			}
		}
		quicken();
	}
	double gaussian(double sigma, double x) const {
		double factor = ( sigma * sqrt(2*PI) ) / 1.0;
		return factor * ( ( 1.0 / ( sigma * ::sqrt(2.0*PI) ) ) * exp( -(x*x) / (2.0*sigma*sigma) ) );
	}
};


void psychlops_main() {
	Canvas canvas(800,600, Display::list()[1]);

	Image grating(100,100);
	for(int y=0; y<100; y++) for(int x=0; x<100; x++) grating.pix(x,y,Color(.5+.5*sin(x/10.0)));
	grating.centering(0,0);

	GaussianEnvelope filter(20);
	filter.centering();
	Group group;
	group.clip(&filter).add(grating).centering();

	while(!Keyboard::esc.pushed()) {
		canvas.clear(Color::gray);
		group.draw();
		canvas.flip();
	}
}

*/
