#include <psychlops.h>
using namespace Psychlops;
///- Prefix


///+ Main Routine
//// Psychlops runs at the first line of this function psychlops_main().
void psychlops_main() {
    Canvas window(Canvas::window); //Create a window. Here, window variables are preset mode.
	
	Image img[100];
	Clock before, after;
	before.update();
	for(int i=0; i<100; i++) {
		img[i].set(300,300,Image::RGBA);
		img[i].shift(100,100);
		img[i].clear(Color(1.0,0.7,0.5, 1.0));
		img[i].cache();
	}
	img[0].line(0,0,0,79,Color::cyan);
	img[0].line(0,79,79,79,Color::cyan);
	img[0].line(79,79,79,0,Color::cyan);
	img[0].line(79,0,0,0,Color::cyan);
	img[0].cache();
	after.update();
	
	std::cout << (after - before).at_msec() << " ms " << std::endl;
	
	///+ 2
	////  Set a figure size, position and color.
    Psychlops::Rectangle
	/*ID:FIGURE selector Rectangle Ellipse*/ figure; //Create a figure (Rectangle or Ellipse) variable.
    figure.set( 100, 100 ); // Set the size of figure.
    figure.fill = Psychlops::Color( 1, 1, 1 ); // Set the drawing color of figure in (R, G ,B) format.
    figure.centering().shift( 0, 0 ); // Move the figure to the starting point.
    ///- 2
	
    int frame=0;
    int looming_direction=1, motion_dir=1; // Create variables for looming motion.
	//looming_direction is a variable for size change.
	//motion_dir is a variable for motion direction.
	///+ 3 Drawing loop
    //// Draw each frames in a "while loop".
    while(!Keyboard::esc.pushed()) { //exit a program when the escape key is pressed down.
        window.clear(0); // Clear the window with a designated gray-scale level.
		img[0].draw();
		
		
		///+ 3.1
        //// Calculate object's position and size for each frame.
		
        if(frame% 30==0){ // a direction of size change will reverse at designated frames.
            looming_direction=looming_direction*-1;
        }
		
        if(frame% 90==0){ // motion direction will reverse at designated frames.
			motion_dir*=-1;
        }
		
        ///- 3.1
		
		///+ 3.2
        //// Settting figure's properties
        figure.resize(figure.getWidth()+looming_direction*1, // Scaling the figure in a direction given by "looming_direction".
					  figure.getHeight()+looming_direction*1);// Scaling the figure in a direction given by "looming_direction".
        figure.shift(motion_dir*1, motion_dir*0);// Move the figure for 1 pixel in direction given by "motion_dir".
        ///- 3.2
		
		///+ 3.3
        ////Drawing
        figure.draw(); // Drawing the figure with a designated color at designated position.
        window.flip(); // Reflect the drawing for the display by flipping frame buffers.
        ///- 3.3
		
		///+ 3.4
        ////make a step for next frames
        frame++;
        ///- 3.4
    }
    ///- 3 Drawing loop
	
}
///- Main Routine


/*
void func() {
	Canvas cnvs(700, 700, Canvas::window);

	int wid=200, hei=200, left=0, right=0;
	bool typ=0;

	Independent << typ   | "typ";
	Independent << wid   | "wid"   | 10 | 1;
	Independent << hei   | "hei"   | 10 | 1;
	Independent << left  | "left"  | 10 | 1;
	Independent << right | "right" | 10 | 1;
	
	//Image source("TocoToucan.png");
	Image source("test.png"), ref("test.png");
	source.cache();
	Rectangle rect(100,100);
	rect.shift(500,200);
	
	source.centering();
	
	while(!Input::get(Keyboard::esc)) {
		cnvs.clear(Color::gray);
		if(typ)
			source(rect.set(source.getWidth()-left, source.getHeight()-right)).centering(Drawable::prime->getCenter()).draw();
			//ref.centering(Drawable::prime->getCenter()).draw();
		else
			source.centering(Drawable::prime->getCenter()).draw();
		cnvs.flip(10);
	}
}

void psychlops_main() {
	Procedure proc;
	proc.setDesign(Procedure::DEMO);
	proc.setProcedure(func);
	proc.run();
}			   
*/

/*
double bellcurve(const double x, const double sigma) {
	return exp( -(x*x) / (2.0*sigma*sigma) );
}
double bellcurve_(const double x) {
	return bellcurve(x,5);
}

AnalogInput *analog;
static double hoge = 0;
void addToS() {
	AppState::setThreadPriority(AppState::LOW);
	while(true) {
		hoge = analog->get();
	}
}

class RectLuminance : public ExperimentalMethods::Demo {
	Canvas display;
	double tf;
	int numstim;
	int orientation;
	
	Image base;
	Group gp;
	Prototype::Thread recorder;
	
	void initialize() {
		display.set(Canvas::window);
		//AnalogOutput *analogout = new Devices::AnalogOutput_NIDAQmxBase();
		//analogout->put(5);
		//delete analogout;
		//analog = new Devices::AnalogInput_NIDAQmxBase(1,1,0);
		//recorder.create(&addToS);
		
		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();
	}

	void trial() {
		Rectangle mask(102,102);
		Font font(L"Meirio", 10);
		Letters let(L"");
		double phase = 0;
		Color col;

		Figures::FunctionalPlot plot(300,300);
		plot.append(&sin);
		plot.append(&bellcurve_);
		plot.x_min = -10;
		plot.x_max =  10;
		plot.y_min = -10;
		plot.y_max =  10;

		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)));
			if(Mouse::right.pressed()) display.var(Mouse::getWheelDelta().x, 300,300);
			display.var(Mouse::getWheelDelta().y, 300,320);
			let.centering();
			let.draw(Color::white);
			display.msg(L"fd", 500,500);

			plot.draw();
			
			display.var(hoge, 400, 400);
			display.flip();
		}
	}
	
};

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

*/

/*
Letters let;

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

	Rectangle a(100,100), b(100,100);
	a.stroke = Stroke(Color::blue, 5, Stroke::DASHED);
	b.shift(100,109).fill = Color::black;
	Rectangle cr(10,10);
	cr.fill = Color::red;
	Figures::Arrow arrow(0,0,100,50);
	arrow.stroke = Stroke(Color::green, 5, Stroke::SOLID);
	//arrow.fill = Color::green;


	Group g;
	g.append(a);
	b.join(g);
	cr.join(g);
	arrow.join(g);
	g.centering();

	Rectangle clipper(200,200);
	clipper.centering();

	let = L"日本語";
	let.cache();
	let.centering();

	//g.clip(clipper);

	while(!Keyboard::esc.pushed()) {
		c.clear(Color::gray);

		g.rotation+=1;
		g.draw();
		let.draw(Color::red);

		c.flip();
	}
}
*/


/*

class RectLuminance : public ExperimentalMethods::Demo {
	Canvas display;
	double bg_lum, x;
//	Widgets::SequentialScreenshot sc;
	Gabor *gabor;
	Rectangle rect;
	FigureGroup g;
	Figures::Cross xr;
	Figures::Arrow arr;

	void initialize() {
		display.set(640,400, Canvas::window);
		gabor = new QuickGabor(10.0, 10.0, 1.0);
		g.add(gabor);
		g.add(rect);
		g.add(xr);
		rect.set(100, 100);
		xr.set(100,100).shift(200,200);
		xr.brush = Stroke(Color::red, 2, Stroke::SOLID);
		g.shift(100,0);
		g.rotation = -5;
		g.axis = Psychlops::Point(1,1,1);
		arr.centering();
		arr.vec = Psychlops::Point(100,50);

		Interval itv;
		Independent << bg_lum    | "BG Luminance"   | 0.0<=itv<=4095 |  128 | 1 , 1;
		Independent << x         | "X"              | 0.0<=itv<=4095 |  128 | 1 , 1;

		display.watchFPS();
		display.showFPS();
	}

	void trial() {
		Letters let(L"日本語");
		let.color = Color::green;
		while(!Input::get(Keyboard::esc)) {
			display.clear(Color(bg_lum/4095));
			(*gabor).centering().draw();
			let.centering();
			let.draw();
			g.draw();
			arr.vec.x -= 1;
			arr.draw(Color::white);
			display.flip();
		}
	}
	
};

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

*/

/*
 void psychlops_main() {
	Color col, col2;

	Image pic;
	Image pic2(pic.getWidth(), pic.getHeight());
	pic.load("pic1.png");

	display.clear(Color::white);
	display.flip();


	for(int x=0; x<pic.getWidth(); x++) {
		display.progressbar(x, pic.getWidth());
		for(int y=0; y<pic.getHeight(); y++) {
//			col = pic.getPix(x,y);
//			col2.set(1-col.getR(), 1-col.getG(), 1-col.getB());
//			pic2.pix(x,y,col2);
		}
	}
*/
/*
	pic.centering();
	pic2.centering();
	Display::clear(Color::white);

	while(!Input::get(Keyboard::esc)) {
		pic.draw();
		Display::flip();
		pic2.draw();
		Display::flip();
	}
}
*/




/*
class Test : public ExperimentalMethods::Demo {
	
public:
	Canvas d;
	double l,r,g;

	void initialize() {
		d.set(Canvas::window);
		l=r=g=0;
		Range rng;
		Independent << r | 0<=rng<=1 | 1.0/255 | 16.0/255;
		Independent << g | 0<=rng<=1 | 1.0/255 | 16.0/255;
		Independent << l | 0<=rng<=1023 | 1 | 64;
		Color::setGammaValue(6.75,1.0,1.0,Color::BITS_MONO);
	}
	void terminate() {
	}
	void trial() {
		Rectangle rect(100,100), rect1(100,100), rect2(100,100);
		rect.centering();
		rect1.centering().shift(-100,0);
		rect2.centering().shift(-50,-100);
		Color col, ref1, ref2, bg;
		while(!Input::get(Keyboard::esc)) {
			bg.set(l/1023);
			d.clear(bg);
			col.set(r,g,0);
			rect.draw(col);
			ref1.set(127/255.0,0,0);
			rect1.draw(ref1);
			ref2.set(127/255.0,127/255.0,0);
			rect2.draw(ref2);
			d.flip();
		}
	}
	
};

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