
/*
CLASS {NATIVE_Console|_GCC}, NATIVE :

IMPORT, ANYWAY: {Console} .

NATIVE: "///COPY NATIVE_Console.*" .
*/

//#ifdef SEPARATE_UNITS
//    #include "NATIVE_Console.h"
//#endif

	byte AL4_console::Last_foreground_color = 7;
	byte AL4_console::Last_background_color;
	bool AL4_console::End_input_detected;
	
	void AL4_console::Extended_write(std::string S)
	{
	//? {Console}
		C_Console::M__Extended_write(S);
	//.
	}
	
	void AL4_console::Console_ANSI_colors(bool Add)
	{
		if (Add)
		{
			AL4_system::WriteRedirected = Extended_write;
		}
		else AL4_system::WriteRedirected = AL4_system::Write_direct;
	}
	
	int AL4_console::prev_Foreground = 7;
	int AL4_console::prev_Background;
	bool AL4_console::prev_intensity;
	bool AL4_console::high_intensity;
	
	void AL4_console::con_fg(byte f_color)
	{
	#ifdef MSWINDOWS
	    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
	        f_color | (Last_background_color << 4) );
	    Last_foreground_color = f_color;
	#endif
	}
	
	void AL4_console::con_bg(byte b_color)
	{
	#ifdef MSWINDOWS
	    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
	        Last_foreground_color | (b_color << 4) );
	    Last_background_color = b_color;
	#endif
	}
	
    static int Abs(int X) {
    	if (X >= 0) return X;
    	return -X;
    }
    
    static int console_color_nearest_to(int color_RGB) {
    	int R = color_RGB & 0xff;
    	int G = (color_RGB >> 8) & 0xff;
    	int B = (color_RGB >> 16) & 0xff;
    	int best = 0;
    	int delta = 256 * 3;
    	for (int i = 0; i < 16; i++) {
    		int rgb = 0;
    		switch(i) {
    		case 0: rgb = 0; break; //black
    		case 1: rgb = 0x800000; break; //dark blue
    		case 2: rgb = 0x008000; break; // dark green
    		case 3: rgb = 0x808000; break; // dark cyan
    		case 4: rgb = 0x000080; break; // dark red
    		case 5: rgb = 0x808080; break; // dark magenta
    		case 6: rgb = 0x008080; break; // dark yellow
    		case 7: rgb = 0x808080; break; // dark gray
    		case 8: rgb = 0x404040; break; // dark gray
    		case 9: rgb = 0xC00000; break; // blue
    		case 10: rgb = 0x00C000; break; // green
    		case 11: rgb = 0xC0C000; break; // cyan
    		case 12: rgb = 0x00000C0; break; // red
    		case 13: rgb = 0xC000C0; break; // magenta
    		case 14: rgb = 0x00C0C0; break; // yellow
    		case 15: rgb = 0xC0C0C0; break; // white
    		}
    		int r = rgb & 0xff;
    		int g = (rgb >> 8) & 0xff;
    		int b = (rgb >> 16) & 0xff;
    		int new_delta = Abs(r - R) + Abs(g - G) + Abs(b - B);
    		if (new_delta < delta) {
    			best = i;
    			delta = new_delta;
    		}
    	}
    	return best;
    }
        
	void AL4_console::apply_color_ansi(int param, int color_RGB)
	{
	#ifdef MSWINDOWS
		byte was_Foreground, was_Background;
	    switch (param)
	    {
	    case -1: return;
	    case 0:  high_intensity = false;
	    	con_fg(7); con_bg(0);
	    	break;
	    case 1:  high_intensity = true;
	    	con_fg(Last_foreground_color | 8);
	    	con_bg(Last_background_color | 8);
	    	break;
	    case 7:	was_Foreground = Last_foreground_color;
	            was_Background = Last_background_color;
	            con_fg(was_Background);
	            con_bg(was_Foreground);
	    	break;
	    case 30: if (high_intensity) con_fg(8); else con_fg(0);   // BLACK
	    	break;
	    case 31: if (high_intensity) con_fg(8+4); else con_fg(4); // RED
	    	break;
	    case 32: if (high_intensity) con_fg(8+2); else con_fg(2); // GREEN
	    	break;
	    case 33: if (high_intensity) con_fg(8+6); else con_fg(6); // YELLOW
	    	break;
	    case 34: if (high_intensity) con_fg(8+1); else con_fg(1); // BLUE
	    	break;
	    case 35: if (high_intensity) con_fg(8+5); else con_fg(5); // MAGENTA
	    	break;
	    case 36: if (high_intensity) con_fg(8+3); else con_fg(3); // CYAN
	    	break;
	    case 37: if (high_intensity) con_fg(8+7); else con_fg(7); // WHITE
	    	break;
	    case 38: con_fg(console_color_nearest_to(color_RGB));
	    	break;
	    case 40: if (high_intensity) con_bg(8); else con_bg(0);   // BLACK
	    	break;
	    case 41: if (high_intensity) con_bg(8+4); else con_bg(4); // RED
	    	break;
	    case 42: if (high_intensity) con_bg(8+2); else con_bg(2); // GREEN
	    	break;
	    case 43: if (high_intensity) con_bg(8+6); else con_bg(6); // YELLOW
	    	break;
	    case 44: if (high_intensity) con_bg(8+1); else con_bg(1); // BLUE
	    	break;
	    case 45: if (high_intensity) con_bg(8+5); else con_bg(5); // MAGENTA
	    	break;
	    case 46: if (high_intensity) con_bg(8+3); else con_bg(3); // CYAN
	    	break;
	    case 47: if (high_intensity) con_bg(8+7); else con_bg(7); // WHITE
	    	break;
	    case 48: con_bg(console_color_nearest_to(color_RGB));
	    	break;
	    case 108: 
			prev_Foreground = Last_foreground_color;
			prev_Background = Last_background_color;
			prev_intensity = high_intensity;
	    	break;
	    case 109: 
			high_intensity = prev_intensity;
			con_fg(prev_Foreground);
			con_bg(prev_Background);
	    	break;
	    }
	#endif
	}
	

/*

CONST STR:
    NATIVE_Import_console = @
    "#ifdef SEPARATE_UNITS"
    "       #include " #QU "NATIVE_Console.h" #QU
    "#endif"
    "#include <conio.h>"     
    
    NATIVE_Support_console_ANSI = @
    "	RESULT = true;"

    NATIVE_Console_color = @
    "AL4_console::Last_foreground_color = X_C;"
    "#ifdef MSWINDOWS"
    "SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), X_C);"
    "#else"
    "   std :: string s;"
    "   switch(X_C)"
    "   {"
   ''   case 0: s = "0;30"; break; //BLACK      ''
   ''   case 1: s = "0;34"; break; // BLUE      ''
   ''   case 2: s = "0;32"; break; // GREEN     ''
   ''   case 3: s = "0;36"; break; // TEAL      ''
   ''   case 4: s = "0;31"; break; // MAROON    ''
   ''   case 5: s = "0;35"; break; // MAGENTA   ''
   ''   case 6: s = "0;33"; break; // OLIVE     ''
   ''   case 7: s = "0;37"; break; // GRAY      ''
   ''   case 8: s = "37;1"; break; // SILVER     ''
   ''   case 9: s = "34;1"; break; // LIGHT_BLUE ''
   ''   case 10: s = "32;1"; break; // LIME      ''
   ''   case 11: s = "36;1"; break; // CYAN      ''
   ''   case 12: s = "31;1"; break; // RED       ''
   ''   case 13: s = "35;1"; break; // FUSCHIA   ''
   ''   case 14: s = "33;1"; break; // YELLOW    ''
   ''   default: s = "37;1"; break; // WHITE     ''
    "   }"
   ''   AL4_system::Write(std::string("\033[" + s + "m"));''
    "#endif"

    NATIVE_Console_colors = @
    "AL4_console::Last_foreground_color = X_F;"
    "AL4_console::Last_background_color = X_B;" 
    "#ifdef MSWINDOWS"
    "SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), X_F | X_B << 4);" 
    "#else"
    "   std :: string s;"
    "   switch(X_F)"
    "   {"
   ''   case 0: s = "0;30"; break; //BLACK      ''
   ''   case 1: s = "0;34"; break; // BLUE      ''
   ''   case 2: s = "0;32"; break; // GREEN     ''
   ''   case 3: s = "0;36"; break; // TEAL      ''
   ''   case 4: s = "0;31"; break; // MAROON    ''
   ''   case 5: s = "0;35"; break; // MAGENTA   ''
   ''   case 6: s = "0;33"; break; // OLIVE     ''
   ''   case 7: s = "0;37"; break; // GRAY      ''
   ''   case 8: s = "37;1"; break; // SILVER     ''
   ''   case 9: s = "34;1"; break; // LIGHT_BLUE ''
   ''   case 10: s = "32;1"; break; // LIME      ''
   ''   case 11: s = "36;1"; break; // CYAN      ''
   ''   case 12: s = "31;1"; break; // RED       ''
   ''   case 13: s = "35;1"; break; // FUSCHIA   ''
   ''   case 14: s = "33;1"; break; // YELLOW    ''
   ''   default: s = "37;1"; break; // WHITE     ''
    "   }"
   ''   AL4_system::Write(std::string("\033[" + s + "m"));''
    "   switch(X_B)"
    "   {"
   ''   case 0: s = "40"; break; //BLACK      ''
   ''   case 1: s = "44"; break; // BLUE      ''
   ''   case 2: s = "42"; break; // GREEN     ''
   ''   case 3: s = "46"; break; // TEAL      ''
   ''   case 4: s = "41"; break; // MAROON    ''
   ''   case 5: s = "45"; break; // MAGENTA   ''
   ''   case 6: s = "43"; break; // OLIVE     ''
   ''   case 7: s = "47"; break; // GRAY      ''
   ''   case 8: s = "40"; break; // SILVER     ''
   ''   case 9: s = "44"; break; // LIGHT_BLUE ''
   ''   case 10: s = "42"; break; // LIME      ''
   ''   case 11: s = "46"; break; // CYAN      ''
   ''   case 12: s = "41"; break; // RED       ''
   ''   case 13: s = "45"; break; // FUSCHIA   ''
   ''   case 14: s = "43"; break; // YELLOW    ''
   ''   default: s = "47"; break; // WHITE     ''
    "   }"
   ''   AL4_system::Write(std::string("\033[" + s + "m"));''
    "#endif"
    
    NATIVE_Get_console_color = @
    "if (X_Which == 0)"
    "   RESULT = AL4_console::Last_foreground_color;"
    "else RESULT = AL4_console::Last_background_color;"

	NATIVE_Console_ANSI_colors = @
	"	AL4_console::Console_ANSI_colors(X_Add);"
	
	NATIVE_Write_direct  = @
	"  AL4_system::Write_direct(X_S);"
	
	NATIVE_apply_color_ansi = @
	"#ifdef MSWINDOWS"
	"	AL4_console::apply_color_ansi(X_Param, X_Color);"
	"#endif" 
	
	NATIVE_Get_char = @
	"  RESULT = getch();"
	"  if (RESULT.length() == 1 && "
	"	   RESULT[0] == (char)26)"
	"	  AL4_console::End_input_detected = true;"	     
	
	NATIVE_End_input = @
	"  RESULT = AL4_console::End_input_detected;"     
	
	NATIVE_Input_ready = @
	"	RESULT = false;"
	
	NATIVE_Key_pressed = @
	"#ifdef MSWINDOWS"
	"	RESULT = GetKeyState(X_Key) < 0;"
	"#else"
	"	RESULT = false;"
	"#endif"
	
	NATIVE_Cursor_X = @
	"	RESULT = 0;"
	
	NATIVE_Cursor_Y = @
	"	RESULT = 0;"
	
	NATIVE_Set_cursor_pos = @
	"	"
	
	NATIVE_Console_height = @
	"	RESULT = 24;"
	
	NATIVE_Console_width = @
	"	RESULT = 80;"
	
	NATIVE_Set_console_size = @
	""
	
    .
    

    
END
*/


