#include <io.h>
#include <system.h>
#include <stdio.h>
//write data
#define IOWR_DATA(base, offset, data) \
        IOWR_16DIRECT(base, (offset) * 2, data)
//read data
#define IORD_DATA(base, offset) \
        IORD_16DIRECT(base, (offset) * 2)

#define RD_SYNC 0
#define RD_start 1
#define WR_start 2
#define WR_readselects 3
#define RD_readselects 4
#define WR_aggr 5
#define WR_box 6
#define WR_reset 7
#define RD_leftclick 0
#define RD_rightclick 1
#define RD_dx 2
#define RD_dy 3
#define RD_snum 4

/*void delay(int input){

    int i, j;
    for (i=0;i<input;i++){
        j=0;
    }

}*/

int main()
{
    //alt_u8 blank = 0;
    int i = 0;
    //bottom right corner of pixel dump
    alt_u16 xcoordinate = 0;
    alt_u16 ycoordinate = 0;

    int outOfBoundsX = 0;
    int outOfBoundsY= 0;
    alt_8 deltaX;
    alt_8 deltaY;

    int isOutOfBounds=0;
    //alt_8 lastDeltaX = IORD_DATA(GPIO_BASE, RD_dx);
    //alt_8 lastDeltaY = IORD_DATA(GPIO_BASE, RD_dy);
    //alt_u16 last_sample = IORD(GPIO_BASE, RD_snum);
    //alt_u16 this_sample;
    //alt_u16 writeable = 1;
    alt_u16 leftclick = 1;

    int xcoordinate_temp = 0;
    int ycoordinate_temp = 0;

    //alt_u16 start_RAM = 0;

    IOWR_DATA(VGA_BASE, WR_readselects, 1);
    IOWR_DATA(VGA_BASE,WR_start,0);
    IOWR_DATA(VGA_BASE, WR_reset, 0);

    alt_u16 lastcurrentAllRAMS=0x0;

    for(;;){


        //reset
        if(IORD_DATA(GPIO_BASE, RD_rightclick)==0){
            IOWR_DATA(VGA_BASE, WR_aggr, 0);
            IOWR_DATA(VGA_BASE, WR_start, 0);
            xcoordinate = 0;
            ycoordinate = 0;
            outOfBoundsX = 0;
            outOfBoundsY = 0;
            IOWR_DATA(VGA_BASE, WR_aggr, 1);
            for(i=0; i<15; i++){
                IOWR_DATA(VGA_BASE, WR_reset, 1);
            }
            IOWR_DATA(VGA_BASE, WR_aggr, 0);

            continue;
        }
        else {
            IOWR_DATA(VGA_BASE, WR_reset, 0);
            //read from address 1 for x position of sample
            deltaX = IORD_DATA(GPIO_BASE, RD_dx);

            //read from address 2 for y position of sample
            deltaY = IORD_DATA(GPIO_BASE, RD_dy);

            leftclick = IORD_DATA(GPIO_BASE, RD_leftclick);
            //IOWR_DATA(VGA_BASE, WR_reset, 0);



            alt_u16  currentAllRAMS = IORD_DATA(GPIO_BASE,RD_snum);
            //printf("%x\n",currentAllRAMS);

            if (currentAllRAMS == lastcurrentAllRAMS){
                continue;
            }
            alt_u16 currentRAM1 = currentAllRAMS & 0xF;
            alt_u16 currentRAM2 = (currentAllRAMS>>4) & 0xF;
            alt_u16 currentRAM3 = (currentAllRAMS>>8) & 0xF;
            alt_u16  currentRAM4 = (currentAllRAMS>>12) & 0xF;
            alt_u16  lastRAM1 = lastcurrentAllRAMS & 0xF;
            alt_u16  lastRAM2 = (lastcurrentAllRAMS>>4) & 0xF;
            alt_u16  lastRAM3 = (lastcurrentAllRAMS>>8) & 0xF;
            alt_u16  lastRAM4 = (lastcurrentAllRAMS>>12) & 0xF;
            alt_u16  ramWhichIsDifferent;
            if(currentRAM1!=lastRAM1){
                //printf("%x\n",currentAllRAMS);
                ramWhichIsDifferent = 0x1;
            }
            else if(currentRAM2!=lastRAM2){
                //printf("%x\n",currentAllRAMS);
                ramWhichIsDifferent=0x2;
            }
            else if(currentRAM3!=lastRAM3){
                //printf("%x\n",currentAllRAMS);
                ramWhichIsDifferent=0x4;
            }
            else{
                //printf("%x\n",currentAllRAMS);
                ramWhichIsDifferent=0x8;
            }
            IOWR(VGA_BASE, WR_readselects, ramWhichIsDifferent);

            lastcurrentAllRAMS = currentAllRAMS;

            //alt_u16 temp = IORD_DATA(VGA_BASE, RD_start);
            //printf("%x\n",temp);
            //if(last_sample != this_sample){
            xcoordinate_temp=xcoordinate-deltaX;
            printf("dx: %d\n", xcoordinate);
            ycoordinate_temp=ycoordinate+deltaY;
            printf("dy: %d\n", ycoordinate);
            //printf("x: %d\n",xcoordinate);
            //printf("y: %d\n",ycoordinate);
            //printf("\n");
            //Boundary conditions
            if(xcoordinate_temp>=0 && ycoordinate_temp>=0 && xcoordinate_temp<=112 && ycoordinate_temp<=112
                && outOfBoundsX>=0 && outOfBoundsY>=0 && outOfBoundsX<=112 && outOfBoundsY<=112){

                xcoordinate-=deltaX;
                ycoordinate+=deltaY;

                outOfBoundsX = xcoordinate;
                outOfBoundsY = ycoordinate;

                if ((deltaX == 0) && (deltaY == 0)){
                    printf("er\n");
                }


                //                    start_RAM = ycoordinate+xcoordinate*128;
                //write back new position
                IOWR_DATA(VGA_BASE, WR_start, ycoordinate+xcoordinate*128);

                if((!leftclick)){
                    //green if writing
                    IOWR_DATA(VGA_BASE, WR_box, 1);
                    for(i=0; i<15; i++){
                        IOWR_DATA(VGA_BASE, WR_aggr, 1);
                    }

                    //printf("ag\n");
                    IOWR_DATA(VGA_BASE, WR_aggr, 0);
                }else{
                    //yellow if not writing
                    IOWR_DATA(VGA_BASE, WR_box, 0);
                    IOWR_DATA(VGA_BASE, WR_aggr, 0);
                }
                isOutOfBounds=0;
                //printf("%d\n",ycoordinate-1*xcoordinate*256);
            }else{
                //red if out of bounds
			//IOWR_DATA(VGA_BASE, WR_start, ycoordinate+xcoordinate*128);
                IOWR_DATA(VGA_BASE, WR_box, 2);
                if(!isOutOfBounds){
                	//printf("d2: %d\n", xcoordinate_temp);
                	isOutOfBounds=1;
                    if(xcoordinate_temp<0){
						//bottom right corner
						if(ycoordinate_temp<0)
							IOWR_DATA(VGA_BASE, WR_start, 0);
						//top right corner
						else if(ycoordinate_temp>112)
							IOWR_DATA(VGA_BASE, WR_start, 112);
						else
							IOWR_DATA(VGA_BASE, WR_start, ycoordinate_temp);
					}
                    else if(ycoordinate_temp<0){
						//bottom right corner
						if(xcoordinate_temp<0)
							IOWR_DATA(VGA_BASE, WR_start, 0);
						//bottom left corner
						else if(xcoordinate_temp>112)
							IOWR_DATA(VGA_BASE, WR_start, 112*128);
						else
							IOWR_DATA(VGA_BASE, WR_start, xcoordinate_temp*128);
					}
                    else if(xcoordinate_temp>112){
						//bottom left corner
						if(ycoordinate_temp<0)
							IOWR_DATA(VGA_BASE, WR_start, 112*128);
						//top left corner
						else if(ycoordinate_temp>112)
							IOWR_DATA(VGA_BASE, WR_start, 112+112*128);
						else
							IOWR_DATA(VGA_BASE, WR_start, 112*128 + ycoordinate_temp);
					}
                    else if(ycoordinate_temp>112){
						//top right corner
						if(xcoordinate_temp<0)
							IOWR_DATA(VGA_BASE, WR_start, 112);
						//top left corner
						else if(xcoordinate_temp>112)
							IOWR_DATA(VGA_BASE, WR_start, 112+112*128);
						else
							IOWR_DATA(VGA_BASE, WR_start, xcoordinate_temp*128 + 112);
					}

                }

				else{

			        if(xcoordinate_temp<0){
						//bottom right corner
						if(ycoordinate_temp<0)
							IOWR_DATA(VGA_BASE, WR_start, 0);
						//top right corner
						else if(ycoordinate_temp>112)
							IOWR_DATA(VGA_BASE, WR_start, 112);
						else

							IOWR_DATA(VGA_BASE, WR_start, ycoordinate_temp);
					}
                    else if(ycoordinate_temp<0){
						//bottom right corner
						if(xcoordinate_temp<0)
							IOWR_DATA(VGA_BASE, WR_start, 0);
						//bottom left corner
						else if(xcoordinate_temp>112)
							IOWR_DATA(VGA_BASE, WR_start, 112*128);
						else
							IOWR_DATA(VGA_BASE, WR_start, xcoordinate_temp*128);
					}
                    else if(xcoordinate_temp>112){
						//bottom left corner
						if(ycoordinate_temp<0)
							IOWR_DATA(VGA_BASE, WR_start, 112*128);
						//top left corner
						else if(ycoordinate_temp>112)
							IOWR_DATA(VGA_BASE, WR_start, 112+112*128);
						else
							IOWR_DATA(VGA_BASE, WR_start, 112*128 + ycoordinate_temp);
					}
                    else if(ycoordinate_temp>112){
						//top right corner
						if(xcoordinate_temp<0)
							IOWR_DATA(VGA_BASE, WR_start, 112);
						//top left corner
						else if(xcoordinate_temp>112)
							IOWR_DATA(VGA_BASE, WR_start, 112+112*128);
						else
							IOWR_DATA(VGA_BASE, WR_start, xcoordinate_temp*128 + 112);
					}
                }

                outOfBoundsX-=deltaX;
                printf("ox: %d\n", outOfBoundsX);
                outOfBoundsY+=deltaY;
                printf("oy: %d\n", outOfBoundsY);
                xcoordinate=outOfBoundsX;
                ycoordinate=outOfBoundsY;

               // printf("outOfBoundsX = %d", outOfBoundsX);
				//printf("outOfBoundsX = %d", outOfBoundsY);
            }
        }
    }
}
