module util.ascii;

private import opengl;

public float asciiR = 1.0,asciiG = 1.0 ,asciiB = 1.0 ,asciiAlpha = 1.0;
public void drawColon(float x,float y ,float scale){
	glColor3f(asciiR * asciiAlpha ,asciiG * asciiAlpha ,asciiB * asciiAlpha);
	for(int i=0;i<4;i++){
		glPushMatrix();
		glTranslatef(x ,y+((i/2)*2-1)*10*scale ,-800);
		glScalef(0.7 * scale ,0.7 * scale ,0.7 * scale);
		glBegin(GL_LINE_LOOP);
		
		
		glVertex2f(3 ,-4);
		glVertex2f(4 ,-3);
		glVertex2f(4 ,3);
		glVertex2f(3 ,4);
		glVertex2f(-3 ,4);
		glVertex2f(-4 ,3);
		glVertex2f(-4 ,-3);
		glVertex2f(-3 ,-4);
		
		glEnd();
		
		glPopMatrix();
	}
	
}
private:
const int[] bar_a = [0    ,2 ,3 ,4 ,5 ,6];
const int[] bar_b = [  ,1    ,3 ,4 ,5 ,6];
const int[] bar_c = [0 ,1       ,4    ,6];
const int[] bar_d = [      2 ,3 ,4 ,5 ,6];
const int[] bar_e = [0 ,1 ,2 ,3 ,4    ,6];
const int[] bar_f = [0 ,1    ,3 ,4      ];
const int[] bar_g = [0 ,1 ,2 ,3    ,5 ,6];
const int[] bar_h = [   1    ,3 ,4 ,5   ];
const int[] bar_i = [     ,2       ,5   ];
const int[] bar_j = [     ,2       ,5 ,6];
const int[] bar_k = [   1    ,3 ,4    ,6];
const int[] bar_l = [   1       ,4    ,6];
const int[] bar_m = [0 ,1    ,3 ,4    ,6];
const int[] bar_n = [0 ,1 ,2    ,4 ,5   ];
const int[] bar_o = [0 ,1 ,2    ,4 ,5 ,6];
const int[] bar_p = [0 ,1 ,2 ,3 ,4      ];
const int[] bar_q = [0 ,1 ,2 ,3    ,5   ];
const int[] bar_r = [        ,3 ,4      ];
const int[] bar_s = [0 ,1    ,3    ,5 ,6];
const int[] bar_t = [0 ,1       ,4      ];
const int[] bar_u = [   1 ,2    ,4 ,5 ,6];
const int[] bar_v = [           ,4 ,5 ,6];
const int[] bar_w = [0    ,2 ,3    ,5 ,6];
const int[] bar_x = [   1 ,2 ,3 ,4 ,5   ];
const int[] bar_y = [   1 ,2 ,3    ,5 ,6];
const int[] bar_z = [0    ,2 ,3 ,4    ,6];
const int[] bar__ = [                  6];
const int[] bar_0 = [0 ,1 ,2    ,4  ,5 ,6];
const int[] bar_1 = [      2       ,5    ];
const int[] bar_2 = [0    ,2 ,3 ,4    ,6];
const int[] bar_3 = [0    ,2 ,3    ,5 ,6];
const int[] bar_4 = [   1 ,2 ,3    ,5   ];
const int[] bar_5 = [0 ,1    ,3    ,5 ,6];
const int[] bar_6 = [0 ,1    ,3 ,4 ,5 ,6];
const int[] bar_7 = [0    ,2       ,5   ];
const int[] bar_8 = [0 ,1 ,2 ,3 ,4 ,5 ,6];
const int[] bar_9 = [0 ,1 ,2 ,3    ,5 ,6];

public void drawAlphabet(char c ,float x,float y ,float scale = 1.0){
	bool[7] bar;
	foreach(inout b;bar){
		b = false;
	}
	int[] bars;
	switch(c){
		case 'a':case 'A':bars = bar_a;break;
		case 'b':case 'B':bars = bar_b;break;
		case 'c':case 'C':bars = bar_c;break;
		case 'd':case 'D':bars = bar_d;break;
		case 'e':case 'E':bars = bar_e;break;
		case 'f':case 'F':bars = bar_f;break;
		case 'g':case 'G':bars = bar_g;break;
		case 'h':case 'H':bars = bar_h;break;
		case 'i':case 'I':bars = bar_i;break;
		case 'j':case 'J':bars = bar_j;break;
		case 'k':case 'K':bars = bar_k;break;
		case 'l':case 'L':bars = bar_l;break;
		case 'm':case 'M':bars = bar_m;break;
		case 'n':case 'N':bars = bar_n;break;
		case 'o':case 'O':bars = bar_o;break;
		case 'p':case 'P':bars = bar_p;break;
		case 'q':case 'Q':bars = bar_q;break;
		case 'r':case 'R':bars = bar_r;break;
		case 's':case 'S':bars = bar_s;break;
		case 't':case 'T':bars = bar_t;break;
		case 'u':case 'U':bars = bar_u;break;
		case 'v':case 'V':bars = bar_v;break;
		case 'w':case 'W':bars = bar_w;break;
		case 'x':case 'X':bars = bar_x;break;
		case 'y':case 'Y':bars = bar_y;break;
		case 'z':case 'Z':bars = bar_z;break;
		case '.':case '_':bars = bar__;break;
		case '0':		  bars = bar_0;break;
		case '1':		  bars = bar_1;break;
		case '2':		  bars = bar_2;break;
		case '3':		  bars = bar_3;break;
		case '4':		  bars = bar_4;break;
		case '5':		  bars = bar_5;break;
		case '6':		  bars = bar_6;break;
		case '7':		  bars = bar_7;break;
		case '8':		  bars = bar_8;break;
		case '9':		  bars = bar_9;break;
		
		default:break;
	}
	foreach(int b;bars){
		bar[b] = true;
	}
	drawCrossBar(x ,y+20*scale ,scale ,bar[0]);
	drawVerticalBar(x-10*scale ,y+10*scale ,scale ,bar[1]);
	drawVerticalBar(x+10*scale ,y+10*scale ,scale ,bar[2]);
	drawCrossBar(x ,y ,scale ,bar[3]);
	drawVerticalBar(x-10*scale ,y-10*scale ,scale ,bar[4]);
	drawVerticalBar(x+10*scale ,y-10*scale ,scale ,bar[5]);
	drawCrossBar(x ,y-20*scale ,scale ,bar[6]);
	/*
	drawCrossBar(x-10*scale ,y+20*scale ,scale ,bar[0]);
	drawCrossBar(x+10*scale ,y+20*scale ,scale ,bar[1]);
	drawVerticalBar(x-20*scale ,y+10*scale ,scale ,bar[2]);
	drawRightDownBar(x-10*scale ,y+10*scale ,scale ,bar[3]);
	drawVerticalBar(x ,y+10*scale ,scale ,bar[4]);
	drawRightUpBar(x+10*scale ,y+10*scale ,scale ,bar[5]);
	drawVerticalBar(x+20*scale ,y+10*scale ,scale ,bar[6]);
	drawCrossBar(x-10*scale ,y ,scale ,bar[7]);
	drawCrossBar(x+10*scale ,y ,scale ,bar[8]);
	drawVerticalBar(x-20*scale ,y-10*scale ,scale ,bar[9]);
	drawRightUpBar(x-10*scale ,y-10*scale ,scale ,bar[10]);
	drawVerticalBar(x ,y-10*scale ,scale ,bar[11]);
	drawRightDownBar(x+10*scale ,y-10*scale ,scale ,bar[12]);
	drawVerticalBar(x+20*scale ,y-10*scale ,scale ,bar[13]);
	drawCrossBar(x-10*scale ,y-20*scale ,scale ,bar[14]);
	drawCrossBar(x+10*scale ,y-20*scale ,scale ,bar[15]);
	*/
}

public void drawString(char[] s ,float x ,float y ,float scale = 1.0){
	int dx = 0;
	foreach(char c;s){
		drawAlphabet(c ,x + dx ,y ,scale);
		dx += scale * 30.0;
	}
}

public void drawStringCenter(char[] s ,float y ,float scale = 1.0){
	int dx = 0;
	int x =  (s.length - 1) * 30 / 2 * -1;
	foreach(char c;s){
		drawAlphabet(c ,x + dx ,y ,scale);
		dx += scale * 30.0;
	}
}

public void drawString(char[] s ,float x ,float y ,int start ,int end ,float scale = 1.0){
//	if(end < start || start >= s.length || end < 0)return;
	int dx = 0;
	for(int i=0;i<s.length;i++){
		if(start <= i && i <= end){
			drawAlphabet(s[i] ,x + dx ,y ,scale);
		}else drawAlphabet(' ' ,x+dx ,y ,scale);
		dx += scale * 30.0;
	}
}

public void drawNumber(int num,float x ,float y ,float scale = 1.0){
	bool[7] bar;
	foreach(inout b;bar){
		b = false;
	}
	switch(num){
		case 0:
		bar[0]=true;bar[1]=true;bar[2]=true;bar[3]=true;bar[4]=true;bar[6]=true;
		break;
		case 1:
		bar[1]=true;bar[3]=true;
		break;
		case 2:
		bar[0]=true;bar[3]=true;bar[4]=true;bar[5]=true;bar[6]=true;
		break;
		case 3:
		bar[1]=true;bar[3]=true;bar[4]=true;bar[5]=true;bar[6]=true;
		break;
		case 4:
		bar[1]=true;bar[2]=true;bar[3]=true;bar[5]=true;
		break;
		case 5:
		bar[1]=true;bar[2]=true;bar[4]=true;bar[5]=true;bar[6]=true;
		break;
		case 6:
		bar[0]=true;bar[1]=true;bar[2]=true;bar[4]=true;bar[5]=true;bar[6]=true;
		break;
		case 7:
		bar[1]=true;bar[3]=true;bar[6]=true;
		break;
		case 8:
		bar[0]=true;bar[1]=true;bar[2]=true;bar[3]=true;bar[4]=true;bar[5]=true;bar[6]=true;
		break;
		case 9:
		bar[1]=true;bar[2]=true;bar[3]=true;bar[4]=true;bar[5]=true;bar[6]=true;
		break;
		default:break;
	}

	
	for(int i=0;i<4;i++){
		
			
			drawVerticalBar(x+((i%2)*2-1)*10*scale ,y+((i/2)*2-1)*10*scale ,scale ,bar[i]);
			
			
			
		
	}
	for(int i=0;i<3;i++){
		
			
			drawCrossBar(x ,y+(i-1)*20*scale ,scale ,bar[i+4]);
			
			
		
	}
	
	
}

public void drawVerticalBar(float x,float y ,float scale ,bool bar){
	glPushMatrix();
			
	if(bar)glColor3f(asciiR * asciiAlpha ,asciiG * asciiAlpha ,asciiB * asciiAlpha);
	else glColor3f(asciiR * asciiAlpha * 0.3 ,asciiG * asciiAlpha * 0.3 ,asciiB * asciiAlpha * 0.3);
	glTranslatef(x ,y ,-800);
	glScalef(scale ,scale ,scale);
	glBegin(GL_LINE_LOOP);
	glVertex2f(0 ,-9);
	glVertex2f(2 ,-7);
	glVertex2f(2 ,7);
	glVertex2f(0 ,9);
	glVertex2f(-2 ,7);
	glVertex2f(-2 ,-7);
	glEnd();
	
	glPopMatrix();
}

public void drawCrossBar(float x,float y ,float scale ,bool bar){
	glPushMatrix();
	
	if(bar)glColor3f(asciiR * asciiAlpha ,asciiG * asciiAlpha ,asciiB * asciiAlpha);
	else glColor3f(asciiR * asciiAlpha * 0.3 ,asciiG * asciiAlpha * 0.3 ,asciiB * asciiAlpha * 0.3);
	glTranslatef(x ,y ,-800);
	glScalef(scale ,scale ,scale);
	glBegin(GL_LINE_LOOP);
	glVertex2f(-9 ,0);
	glVertex2f(-7 ,2);
	glVertex2f(7 ,2);
	glVertex2f(9 ,0);
	glVertex2f(7 ,-2);
	glVertex2f(-7 ,-2);
	glEnd();
	
	glPopMatrix();
}
public void drawRightUpBar(float x,float y ,float scale ,bool bar){
	glPushMatrix();
	
	if(bar)glColor3f(asciiR * asciiAlpha ,asciiG * asciiAlpha ,asciiB * asciiAlpha);
	else glColor3f(asciiR * asciiAlpha * 0.3 ,asciiG * asciiAlpha * 0.3 ,asciiB * asciiAlpha * 0.3);
	glTranslatef(x ,y ,-800);
	glScalef(scale ,scale ,scale);
	glBegin(GL_LINE_LOOP);
	glVertex2f(-7 ,-7);
	glVertex2f(-5 ,-7);
	glVertex2f(7 ,5);
	glVertex2f(7 ,7);
	glVertex2f(5 ,7);
	glVertex2f(-7 ,-5);
	glEnd();
	
	glPopMatrix();
}
public void drawRightDownBar(float x,float y ,float scale ,bool bar){
	glPushMatrix();
	
	if(bar)glColor3f(asciiR * asciiAlpha ,asciiG * asciiAlpha ,asciiB * asciiAlpha);
	else glColor3f(asciiR * asciiAlpha * 0.3 ,asciiG * asciiAlpha * 0.3 ,asciiB * asciiAlpha * 0.3);
	glTranslatef(x ,y ,-800);
	glScalef(scale ,scale ,scale);
	glBegin(GL_LINE_LOOP);
	glVertex2f(-7 ,7);
	glVertex2f(-5 ,7);
	glVertex2f(7 ,-5);
	glVertex2f(7 ,-7);
	glVertex2f(5 ,-7);
	glVertex2f(-7 ,5);
	glEnd();
	
	glPopMatrix();
}