//Psychlops Code Template
//    Please visit following web site to get sample codes.
//    http://psychlops.sourceforge.jp/ja/?StartCode
//    CodeDresser at following address is also available to view the code.
//    http://visitope.org/Tools/codedresser.html

///+ 0 Setup Psychlops Circumstances
//// 0 Setup Psychlops Circumstances
#include <psychlops.h>
using namespace Psychlops;
// Psychlops Win32 1.5.5 / 20110927
///- 0 Setup Psychlops Circumstances

void psychlops_main() {
	
	
	///+ 1 Declaration /////////////////////////////////////////////////////////////
	//// 1 Declaration
	// declare default window and variables for its parameters
	//Psychlops::Rectangle cnvsrect(800,600);
	//cnvsrect.centering(((Display)Display::secondary).getCenter());
	//Canvas cnvs(cnvsrect);
	Canvas cnvs(Canvas::window);
	
	double CANVAS_FRAMENUM;
	int CANVAS_REFRESHRATE;
	int defaultdotnum = 1500;
	int dotnum = defaultdotnum;
	
	double fieldW=400, fieldH=200;
	double orientation = PI;
	double d[128];
	double maxlifetime = 100;
	double dotsize = 2;
	
	Psychlops::Widgets::Slider wavelength;
	Psychlops::Widgets::Slider speed;
	Psychlops::Widgets::Slider angle;
	Psychlops::Widgets::Slider tf;
	
	
	Psychlops::Interval rng;
	Psychlops::Matrix position(defaultdotnum,3);
	
	Psychlops::Color DEFAULT_BG_COLOR, dotcol;
	Psychlops::Rectangle dot(dotsize, dotsize);
	
	
	//declare local variables around here
	
	///- 1 Declaration /////////////////////////////////////////////////////////////
	
	///+ 2 Initialization //////////////////////////////////////////////////////////
	//// 2 Initialization
	// Set initial values for local variables
	CANVAS_REFRESHRATE = cnvs.getRefreshRate();
	CANVAS_FRAMENUM = 0;
	DEFAULT_BG_COLOR.set(127.0/255.0,127.0/255.0,127.0/255.0,1.0); // default background color is 127/255 mid-gray
	
	wavelength.set("Lambda", 100<=rng<=300, 10,50);
//	wavelength.shift(50,20);
	wavelength = 150;
	
	speed.set("speed", 0<=rng<=2, 0.25,1);
//	speed.shift(50,40);
	speed = 0.25;
	
	angle.set("direction", 0<=rng<=360, 30,15);
//	angle.shift(50,60);
	angle = 90;
	
	tf.set("TF", 0<=rng<=5, 0.25,1.0);
//	tf.shift(50,80);
	tf = 0.25;
	// Draw Offline images around here
	for(int i=0; i<dotnum; i++){
		position(i,1)=random(fieldW);
		position(i,2)=random(fieldH);
		position(i,3)= random(maxlifetime);
		position(i,4)= random(1.0);
	}
	// Offline Movie calculation using Image array around here
	
	///- 2 Initialization //////////////////////////////////////////////////////////
	
	///+ 3 Drawing /////////////////////////////////////////////////////////////////
	//// 3 Drawing
	while(!Input::get(Keyboard::esc)) {
		cnvs.clear(DEFAULT_BG_COLOR);
		
		for(int dn=0; dn<dotnum; dn++){
			d[1] = position(dn,1);
			d[2] = position(dn,2);
			d[3] = d[1]*cos(orientation)-d[2]*sin(orientation);
			
			if(cos(2.0*PI*d[3]/wavelength+2.0*PI*tf*2.0*CANVAS_FRAMENUM/CANVAS_REFRESHRATE)>0){
				d[5] = speed;
			}
			else{
				d[5] = -speed;
			}
			
			position(dn,1) = position(dn,1) + cos(angle*180.0/PI) * d[5];
			position(dn,2) = position(dn,2) + sin(angle*180.0/PI) * d[5];
			
			if(position(dn,3)--<0){
				position(dn,1)=random(fieldW);
				position(dn,2)=random(fieldH);
				position(dn,3)= random(maxlifetime);
				
			}
			
			position(dn,1)=Math::mod(position(dn,1), fieldW);
			position(dn,2)=Math::mod(position(dn,2), fieldH);
			
			dot.centering().shift(-fieldW*0.5+position(dn,1), -fieldH*0.5 + position(dn,2));
			if(Keyboard::up.pressed()){if(d[5]>0)dotcol.set(0.5,0.0,0.0); else dotcol.set(0.0,0.5,0.0);}
			else {d[6]= 1.0; dotcol.set(d[6],d[6],d[6]);}
			dot.draw(dotcol);
		}
		//Write draw commands for realtime figure calculation and drawing around here
		
		
		//Write copy (Draw) commands for rendered movies in section 2 around here
		speed.draw();
		wavelength.draw();
		angle.draw();
		tf.draw();

		cnvs.flip(2);
		CANVAS_FRAMENUM++;
	}
	
	///- 3 Drawing /////////////////////////////////////////////////////////////////
	
}