// TODO: Math.sin() Math.cos()

package iengine;
import com.nttdocomo.ui.*;

public class Screen extends Canvas {
    private Engine engine;
    static int width;
    static int height;
    static int angle;
    boolean sw = true;
    int colorPiston, colorShaft, colorCylinder, colorRoter;
    int colorBack, colorDep, colorPre, colorEngine;
    int costable[] = {
      1024, 1023,1023,1022,1021,1020,1018,1016,1014,1011,1008,1005,1001,997,993,989,984,979,973,968,962,955,949,942,935,928,920,912,904,895,886,877,868,858,848,838,828,817,806,795,784,772,760,748,736,724,711,698,685,671,658,644,630,616,601,587,572,557,542,527,512,496,480,464,448,
432,416, 400,383, 366,350, 333,316, 299,282, 265,247, 230,212, 195,177, 160,142, 124,107, 89,71, 53,35, 17,0, -17, -35, -53, -71, -89, -107, -124, -142, -160, -177, -195, -212, -230, -247, -265, -282, -299, -316, -333, -350, -366, -383, -400, -416, -432, -448, -464, -480, -496, -512, -527, -542, -557, -572, -587, -601, -616, -630, -644, -658, -671, -685, -698, -711, -724, -736, -748,
-760, -772, -784, -795, -806, -817, -828, -838, -848, -858, -868, -877, -886, -895, -904, -912, -920, -928, -935, -942, -949, -955, -962, -968, -973, -979, -984, -989, -993, -997, -1001, -1005, -1008, -1011, -1014, -1016, -1018, -1020, -1021, -1022, -1023, -1023, -1024, -1023,
-1023, -1022, -1021, -1020, -1018, -1016, -1014, -1011, -1008, -1005, -1001, -997, -993, -989, -984, -979, -973, -968, -962, -955, -949, -942, -935, -928, -920, -912, -904, -895, -886, -877, -868, -858, -848, -838, -828, -817, -806, -795, -784, -772, -760, -748, -736, -724, -711, -698, -685, -671, -658, -644, -630, -616, -601, -587,
-572, -557, -542, -527, -512, -496, -480, -464, -448, -432, -416, -400, -383, -366, -350, -333, -316, -299, -282, -265, -247, -230, -212, -195, -177, -160, -142, -124, -107, -89, -71, -53, -35, -17, 0, 17, 35, 53, 71, 89, 107, 124, 142, 160, 177, 195, 212, 230, 247, 265, 282, 299, 316, 333, 350, 366, 383, 400, 416, 432, 448, 464, 480, 496, 512, 527, 542, 557,
572, 587, 601, 616, 630, 644, 658, 671, 685, 698, 711, 724, 736, 748, 760, 772, 784, 795, 806, 817, 828, 838, 848, 858, 868, 877, 886, 895, 904, 912, 920, 928, 935, 942, 949, 955, 962, 968, 973, 979, 984, 989, 993, 997, 1001, 1005, 1008, 1011, 1014, 1016, 1018, 1020, 1021, 1022, 1023, 1023
};

int sintable[] = {
  0, 17, 35, 53, 71, 89, 107, 124, 142, 160, 177, 195, 212, 230, 247, 265, 282, 299, 316, 333, 350, 366, 383, 400, 416, 432, 448, 464, 480, 496, 512, 527, 542, 557, 572, 587, 601, 616, 630, 644, 658, 671, 685, 698, 711, 724, 736, 748, 760, 772, 784, 795, 806, 817, 828, 838, 848, 858, 868, 877, 886, 895, 904, 912, 920, 928, 935, 942, 949, 955, 962, 968, 973, 979, 984, 989, 993,
  997, 1001, 1005, 1008, 1011, 1014, 1016, 1018, 1020, 1021, 1022, 1023, 1023, 1024, 1023, 1023, 1022, 1021, 1020, 1018, 1016, 1014, 1011, 1008, 1005, 1001, 997, 993, 989, 984, 979, 973, 968, 962, 955, 949, 942, 935, 928, 920, 912, 904, 895, 886, 877, 868, 858, 848, 838, 828, 817, 806, 795, 784, 772, 760, 748, 736, 724, 711, 698, 685, 671, 658, 644,  630, 616,  601, 587,  572, 557,  542, 527,  512, 496,  480, 464,  448, 432,  416, 400,  383, 366,  350, 333,  316, 299,  282, 265,  247, 230,  212, 195,  177, 160,  142, 124,  107,
  89,  71, 53,  35, 17,  0,  -17,  -35,  -53,  -71,  -89,  -107,  -124,  -142,  -160,  -177,  -195,  -212,  -230,  -247,  -265,  -282,  -299,  -316,  -333,  -350,  -366,  -383,  -400,  -416,  -432,  -448,  -464,  -480,  -496,  -512,  -527,  -542,  -557,  -572,  -587,  -601,  -616,  -630,  -644,  -658,  -671,  -685,  -698,  -711,  -724,  -736,  -748,  -760,  -772,  -784,  -795,  -806,  -817,  -828,  -838,  -848,  -858,  -868,  -877,  -886,  -895,  -904,  -912,  -920,  -928,  -935,  -942,  -949,  -955,  -962,  -968,  -973,  -979,  -984,  -989,  -993,  -997,  -1001,  -1005,  -1008,  -1011,
  -1014,  -1016,  -1018,  -1020,  -1021,  -1022,  -1023,  -1023,  -1024,  -1023,  -1023,  -1022,  -1021,  -1020,  -1018,  -1016,  -1014,  -1011,  -1008,  -1005,  -1001,  -997,  -993,  -989,  -984,  -979,  -973,  -968,  -962,  -955,  -949,  -942,  -935,  -928,  -920,  -912,  -904,  -895,  -886,  -877,  -868,  -858,  -848,  -838,  -828,  -817,  -806,  -795,  -784,  -772,  -760,  -748,  -736,  -724,  -711,  -698,  -685,  -671,  -658,  -644,  -630,  -616,  -601,  -587,  -572,  -557,  -542,  -527,  -512,  -496,  -480,  -464,  -448,  -432,  -416,  -400,  -383,  -366,  -350,  -333,  -316,  -299,  -282,  -265,  -247,  -230,  -212,  -195,  -177,  -160,  -142,  -124,  -107,
  -89,  -71,  -53,  -35, -17
};

    public Screen(){
	Graphics g;
	width = getWidth();
	height = getHeight();
	g = getGraphics();
	colorPiston = g.getColorOfRGB(47, 79, 79); // gray
	colorShaft = g.getColorOfRGB(32, 178, 170); // lightseagreen
	colorCylinder = g.getColorOfRGB(105, 105, 105); // dimgrey
	colorRoter = g.getColorOfRGB(34, 139, 34); // forestgreen
	colorBack = g.getColorOfRGB(0, 0, 0); // black
	colorDep = g.getColorOfRGB(255, 0, 0); // red
	colorPre = g.getColorOfRGB(0, 255, 255); // cyan
	colorEngine = g.getColorOfRGB(178, 34, 34); // firebrick
	angle = -180;
    }

    public void reset(){
	engine = new Engine(this);
	Thread runner = new Thread(engine);
	runner.start();
    }

    public void paint(Graphics g){
	// double cycle;
	int piston_x1, piston_y1, piston_x2, piston_y2;
	int width03;

        g.lock();

	width03 = width * 3 / 10;

	piston_x1 = sintable[180+angle%360] * (width / 10) / 1024
	    + width/2;
	piston_y1 = costable[180+angle%360] * (height / 10) / 1024
	    + height*3/4;
	piston_x2 = width / 2;
	piston_y2 = piston_y1 - height * 3 / 10;

	g.setColor(colorBack);
	g.fillRect(0, 0, width, height);

	/* Draw heat sink */
	g.setColor(colorEngine);
	g.fillRect(width * 35/100, height * 3 / 10,
		   width03, height * 2 / 100);
	g.fillRect(width * 35/100, height * 35 / 100,
		   width03, height * 2 / 100);
	g.fillRect(width * 35/100, height * 4 / 10,
		   width03, height * 2 / 100);

	/* Draw Cylinder */
	g.drawRect(width * 42 / 100, height * 24 / 100,
		   width * 16 / 100, height / 2);
	fillArc(g, piston_x2, height*3/4, width03, 0, 360);

	g.setColor(colorBack);
	fillArc(g, piston_x2, height*3/4,
		//	fillArc(g, piston_x2 - width * 14 / 100,
		//		height * 7 / 10 - height * 14 / 100,
		width*28/100, 0, 360);
	g.fillRect(width * 43 / 100, height / 4,
		   width * 14 / 100, height / 2);

	/* Draw Gas */
	if(sw){
	    g.setColor(colorPre);
	} else {
	    g.setColor(colorDep);
	}
	g.fillRect(width*435/1000, height/4,
		   width*13/100,
		   piston_y2 - height/20 - height/4 + height/10);

	/* Draw Piston arm */
	g.setColor(colorShaft);
	g.drawLine(piston_x1, piston_y1, piston_x2, piston_y2);
	g.drawLine(piston_x1, piston_y1, piston_x2, height*3/4);

	/* Draw Piston & ring */
	g.setColor(colorPiston);
	g.fillRect(width*435/1000, piston_y2 - height/20,
		   width*13/100, height/10);

	g.setColor(colorShaft);
	g.fillRect(width*435/1000, piston_y2 - height*45/1000,
		   width*13/100, height/100);
	fillArc(g, piston_x2 - width*15/1000,
		piston_y2 - height*15/1000,
		width*3/100, 0, 360);

	/* Draw Roter */
	g.setColor(colorRoter);
	fillPie(g, piston_x2, height*3/4, width/5, angle+30, angle+120);

	g.setColor(colorPiston);
	fillArc(g, piston_x2, height*3/4, width/10, 0, 360);

	g.unlock(true);

	// gettimeofday(&end, &dummy);
	// cycle = 60 / ((double) ((end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec)) / 1000000);

	if(angle < 180-18){
	    angle += 18;
	}else{
	    angle = -180;
	    sw = ! sw;
	}
    }


    void fillArc(Graphics g, int cx, int cy, int r, int s, int e){
        int i, n, r2, step;
	int x[] = new int[16];
	int y[] = new int[16];

        r2 = r/2;
        while(e < s){e += 360;}
        while(e < 0){e += 360;}
        while(s < 0){s += 360;}
        while(e > 360){e -= 360;}
        while(s > 360){s -= 360;}
	step = (e-s)/16;

	n=0;
        for(i=s; i<=e; i+=step){
	    if(i != s){
		try{
		    x[n] = costable[i % 360] * r2 / 1024 + cx;
		    y[n] = sintable[i % 360] * r2 / 1024 + cy;
		}catch(Exception ee){
		}
		n++;
	    }
	}

	g.fillPolygon(x, y, 16);
    }

    void fillPie(Graphics g, int cx, int cy, int r, int s, int e){
        int i, n, r2, step;
	int x[] = new int[16];
	int y[] = new int[16];

        r2 = r/2;
        while(e < s){e += 360;}
        while(e < 0){e += 360;}
        while(s < 0){s += 360;}
        while(e > 360){e -= 360;}
        while(s > 360){s -= 360;}
	step = (e-s)/14;

	n=0; x[n] = cx; y[n] = cy;

        for(i=s; i<=e; i+=step){
	    if(i != s){
		try{
		    x[n] = costable[i % 360] * r2 / 1024 + cx;
		    y[n] = sintable[i % 360] * r2 / 1024 + cy;
		    n++;
		}catch(Exception ee){
		}
	    }
	}

	x[n] = cx; y[n] = cy;

	g.fillPolygon(x, y, 16);
    }
}

// eof
