///+ Prefix linkto BasicCode1
//// Lines for set up Psychlops environment
#include <psychlops.h>;
using namespace Psychlops;
///- Prefix linkto BasicCode1


///+ Main Routine
//// Psychlops runs at the first line of this function psychlops_main().
void psychlops_main() {

    ///+ 0 Declaration linkto BasicCode4_1a
    ////Prepare global parameters
    Canvas window(Canvas::window);
    const int imagenumber = 128; // To prepare the image array, the array number should be "const".
    Psychlops::Image img[128]; //Prepare "Image" class variable to make offscreen movie.
    Psychlops::Rectangle centerrect(10,10);
    int imageHsize = 100;  //Width for offscreeen.
    int imageVsize = 100;  //Height for offscreeen.

    double R,G,B;
    ///- 0 Declaration linkto BasicCode4_1a
    double env;
    Psychlops::Rectangle figurerect(imageHsize, imageVsize);

    ///+ 1 Initialize
    ////Initialize
    centerrect.centering();

    double _i, _j, sd;//variables to axis conversion and Gaussian SD.

    ///+ 1.0 setimage
    //// To reduce the time for gaussian calcuration, set Image here.
    for (int k=0; k<imagenumber; k++){
        img[k].set(imageHsize, imageVsize); //Allocate offscreen in main memory.
    }
    ///- 1.0 setimage

    ///+ 1.1 drawimage
    ////After the offscreen is set, set color to each pixel.
    for(int i=0; i < imageHsize; i++){
        for(int j=0; j < imageVsize; j++){
            ///+ 1.1.1 gaussian linkto BasciCode4_1b
            //// Gaussian envelope
            _i = i-imageHsize*0.5; //get position in image center coordinates
            _j = j-imageVsize*0.5; //get position in image center coordinates
            sd = imageVsize/6.0/*ID:sigma 3.0 8.0 1.0*/; //calculate SD for gaussian
            env=exp(-(_i*_i+_j*_j)/(2.0*(sd*sd)) ); //calculate 2D gaussian
            ///- 1.1.1 gaussian linkto BasciCode4_1b

            for (int k=0; k<imagenumber; k++){
                ///+ makeRGBnoise linkto BasicCode4_1a
                //// set colors of each pixels
                R=random(1.0) * 0.5/*ID:RGain 0.0 1.0 0.5*/; //Set R values.
                G=random(1.0) * 0.5/*ID:GGain 0.0 1.0 0.5*/; //Set G values.
                B=random(1.0) * 0.5/*ID:BGain 0.0 1.0 0.5*/; //Set B values.
                ///- makeRGBnoise linkto BasicCode4_1a

                img[k].pix(i,j, Color(env*R,env*G,env*B));
            }
        }
    }
    ///- 1.1 drawimage

    ///+ 1.2 locateimage
    //// after whole drawing is finished, image is send to VGA and set position.
    for (int k=0; k<imagenumber; k++){
        img[k].cache(); //Move offscreen from main memory to video RAM. (Optional)
        img[k].centering().shift(100,100);//set the position to copy offscreen
    }
    ///- 1.2 locateimage

    ///- 1 Initialize

    ///+ 2 drawing link to BasicCode4_1a
    ////drawing offscreen
    int frame=0;
    while(!Keyboard::esc.pushed()){
        frame++;
        frame = frame % imagenumber; //A frame count should not exceed the frame number of offscreen movies
        window.clear(Color::black); //Clear screen with black
        img[frame].draw(); // copy offscreen onto the reverse side of window buffer.
        centerrect.draw(Color::red);// draw reference rectangle at the center.
        figurerect.centering().shift(100,100);
        if(Keyboard::spc.pressed())figurerect.draw(Color(1.0,0.25,0.25, 0.2/*ID:figurerectalpha 0.0 1.0 0.2*/)); //Draw a rectangle with alpha color.

        window.flip();
    }
    ///- 2 drawing link to BasicCode4_1a

}
///- Main Routine

./4_2b.xap