
/*
CLASS {NATIVE_Console|_CSharp}, NATIVE :

//IMPORT, ANYWAY: {Console} .

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using AL4;

namespace AL4_project
{
    public class Console_functions
    {
    
        public static byte Last_foreground_color = 
                (byte)System.ConsoleColor.DarkGray;
        public static byte Last_background_color = 
                (byte)System.ConsoleColor.Black;
		        
		[DllImport("user32.dll", CharSet = CharSet.Auto, 
		 CallingConvention = CallingConvention.StdCall)]
		 public static extern short GetKeyState(int nVirtKey);
		 
		 public static bool Key_pressed(int nVirtKey)
		 {
		 	return (GetKeyState(nVirtKey) & 0x8000) != 0; 
		 }
		 
		[DllImport("user32.dll", CharSet = CharSet.Auto, 
		 CallingConvention = CallingConvention.StdCall)]
		 public static extern short GetAsyncKeyState(int nVirtKey);
		 
		 public static int Key_pressed_async(int nVirtKey)
		 {
		 	return GetAsyncKeyState(nVirtKey); 
		 }
		 

	public static void Console_ANSI_colors(bool Add_support)
	{
		if (Add_support) AL4_system.Redirect_write = Extended_write;
		else AL4_system.Redirect_write = AL4_system.Write_direct;
	}

	public static void Extended_write(string S)
	{
//?{Console}
		C_Console.M_Extended_write(S);
//.
	}

        static int scan_to_m(string S, int i, ref int param1, ref int param2)
        {
        	bool ignore = false;
        	for (int j = i; j < S.Length; j++)
        	{
        		if (S[j] == 'm') return j;
        		if (S[j] == ':')
        		{
        			ignore = true;
        			param1 = -1;
        			param2 = -1;
        		}
        		else if (S[j] == ';') { }
        		else if (S[j] >= '0' && S[j] <= '9')
        		{
        			int n = 0;
        			while (j < S.Length && S[j] >= '0' && S[j] <= '9')
        			{
        				n = n * 10 + (int)S[j] - (int)'0';
        				j++;
        			}
        			if (param1 < 0 && !ignore) param1 = n;
        			else if (param2 < 0 && !ignore) param2 = n;
        			j--;
        		}
        	}
        	return S.Length;
        }
        
        static int Abs(int X) {
        	if (X >= 0) return X;
        	return -X;
        }
        
        static ConsoleColor console_color_nearest_to(int color_RGB) {
        	int R = color_RGB & 0xff;
        	int G = (color_RGB >> 8) & 0xff;
        	int B = (color_RGB >> 16) & 0xff;
        	ConsoleColor best = ConsoleColor.Black;
        	int delta = 256 * 3;
        	for (int i = 0; i < 16; i++) {
        		int rgb = 0;
        		switch((ConsoleColor)i) {
        		case ConsoleColor.Black: rgb = 0; break;
        		case ConsoleColor.Blue: rgb = 0xC00000; break;
        		case ConsoleColor.Cyan: rgb = 0xC0C000; break;
        		case ConsoleColor.DarkBlue: rgb = 0x800000; break;
        		case ConsoleColor.DarkCyan: rgb = 0x808000; break;
        		case ConsoleColor.DarkGray: rgb = 0x404040; break;
        		case ConsoleColor.DarkGreen: rgb = 0x008000; break;
        		case ConsoleColor.DarkMagenta: rgb = 0x808080; break;
        		case ConsoleColor.DarkRed: rgb = 0x000080; break;
        		case ConsoleColor.DarkYellow: rgb = 0x008080; break;
        		case ConsoleColor.Gray: rgb = 0x808080; break;
        		case ConsoleColor.Green: rgb = 0x00C000; break;
        		case ConsoleColor.Magenta: rgb = 0xC000C0; break;
        		case ConsoleColor.Red: rgb = 0x00000C0; break;
        		case ConsoleColor.White: rgb = 0xC0C0C0; break;
        		case ConsoleColor.Yellow: rgb = 0x00C0C0; break;
        		}
        		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 = (ConsoleColor)i;
        			delta = new_delta;
        		}
        	}
        	return best;
        }
        
        static ConsoleColor prev_Foreground = ConsoleColor.Gray;
        static ConsoleColor prev_Background = ConsoleColor.Black;
        static bool prev_intensity;
        static bool high_intensity;
        
        public static void apply_color_ansi(int param, int color_rgb)
        {
        	switch (param)
        	{
        	case -1: return;
        	case 0:  high_intensity = false;  
					 Console.ForegroundColor = ConsoleColor.Gray;
					 Console.BackgroundColor = ConsoleColor.Black;
        	     	 break;
        	case 1:	 high_intensity = true;
        			 switch (Console.ForegroundColor)
        			 {
        			 	case ConsoleColor.Black:
							Console.ForegroundColor = ConsoleColor.DarkGray;
							break;
        			 	case ConsoleColor.DarkRed:
							Console.ForegroundColor = ConsoleColor.Red;
							break;
        			 	case ConsoleColor.DarkGreen:
							Console.ForegroundColor = ConsoleColor.Green;
							break;
        			 	case ConsoleColor.DarkYellow:
							Console.ForegroundColor = ConsoleColor.Yellow;
							break;
        			 	case ConsoleColor.DarkBlue:
							Console.ForegroundColor = ConsoleColor.Blue;
							break;
        			 	case ConsoleColor.DarkMagenta:
							Console.ForegroundColor = ConsoleColor.Magenta;
							break;
        			 	case ConsoleColor.DarkCyan:
							Console.ForegroundColor = ConsoleColor.Cyan;
							break;
        			 	case ConsoleColor.Gray:
							Console.ForegroundColor = ConsoleColor.White;
							break;
        			 }
        			 switch (Console.BackgroundColor)
        			 {
        			 	case ConsoleColor.Black:
							Console.BackgroundColor = ConsoleColor.DarkGray;
							break;
        			 	case ConsoleColor.DarkRed:
							Console.BackgroundColor = ConsoleColor.Red;
							break;
        			 	case ConsoleColor.DarkGreen:
							Console.BackgroundColor = ConsoleColor.Green;
							break;
        			 	case ConsoleColor.DarkYellow:
							Console.BackgroundColor = ConsoleColor.Yellow;
							break;
        			 	case ConsoleColor.DarkBlue:
							Console.BackgroundColor = ConsoleColor.Blue;
							break;
        			 	case ConsoleColor.DarkMagenta:
							Console.BackgroundColor = ConsoleColor.Magenta;
							break;
        			 	case ConsoleColor.DarkCyan:
							Console.BackgroundColor = ConsoleColor.Cyan;
							break;
        			 	case ConsoleColor.Gray:
							Console.BackgroundColor = ConsoleColor.White;
							break;
        			 }
        			 break;
        	case 7:	 ConsoleColor was_Foreground = Console.ForegroundColor;
        			 ConsoleColor was_Background = Console.BackgroundColor;
        			 Console.ForegroundColor = was_Background;
        			 Console.BackgroundColor = was_Foreground;
        			 break;
        	case 30: Console.ForegroundColor = high_intensity ?
        	     	 ConsoleColor.DarkGray : ConsoleColor.Black;
        	     	 break;
        	case 31: Console.ForegroundColor = high_intensity ?
        	     	 ConsoleColor.Red : ConsoleColor.DarkRed;
        	     	 break;
        	case 32: Console.ForegroundColor = high_intensity ?
        	     	 ConsoleColor.Green : ConsoleColor.DarkGreen;
        	     	 break;
        	case 33: Console.ForegroundColor = high_intensity ?
        	     	 ConsoleColor.Yellow : ConsoleColor.DarkYellow;
        	     	 break;
        	case 34: Console.ForegroundColor = high_intensity ?
        	     	 ConsoleColor.Blue : ConsoleColor.DarkBlue;
        	     	 break;
        	case 35: Console.ForegroundColor = high_intensity ?
        	     	 ConsoleColor.Magenta : ConsoleColor.DarkMagenta;
        	     	 break;
        	case 36: Console.ForegroundColor = high_intensity ?
        	     	 ConsoleColor.Cyan : ConsoleColor.DarkCyan;
        	     	 break;
        	case 37: Console.ForegroundColor = high_intensity ?
        	     	 ConsoleColor.White : ConsoleColor.Gray;
        	     	 break;
        	case 38: Console.ForegroundColor 
        			 = console_color_nearest_to(color_rgb);
        			 break;
        	case 40: Console.BackgroundColor = high_intensity ?
        	     	 ConsoleColor.DarkGray : ConsoleColor.Black;
        	     	 break;
        	case 41: Console.BackgroundColor = high_intensity ?
        	     	 ConsoleColor.Red : ConsoleColor.DarkRed;
        	     	 break;
        	case 42: Console.BackgroundColor = high_intensity ?
        	     	 ConsoleColor.Green : ConsoleColor.DarkGreen;
        	     	 break;
        	case 43: Console.BackgroundColor = high_intensity ?
        	     	 ConsoleColor.Yellow : ConsoleColor.DarkYellow;
        	     	 break;
        	case 44: Console.BackgroundColor = high_intensity ?
        	     	 ConsoleColor.Blue : ConsoleColor.DarkBlue;
        	     	 break;
        	case 45: Console.BackgroundColor = high_intensity ?
        	     	 ConsoleColor.Magenta : ConsoleColor.DarkMagenta;
        	     	 break;
        	case 46: Console.BackgroundColor = high_intensity ?
        	     	 ConsoleColor.Cyan : ConsoleColor.DarkCyan;
        	     	 break;
        	case 47: Console.BackgroundColor = high_intensity ?
        	     	 ConsoleColor.White : ConsoleColor.Gray;
        	     	 break;
        	case 48: Console.BackgroundColor 
        			 = console_color_nearest_to(color_rgb);
        			 break;
        	case 108: prev_Foreground = Console.ForegroundColor;
        			  prev_Background = Console.BackgroundColor;
        			  prev_intensity = high_intensity;
        			  break;
        	case 109: high_intensity = prev_intensity; 
					  Console.ForegroundColor = prev_Foreground;
        			  Console.BackgroundColor = prev_Background;
        			  break;
        	}
        }
        
        public static bool End_input_detected;
        

/*
CONST STR:
    NATIVE_Import_console = @
    ""
    
    NATIVE_Support_console_ANSI = @
    "	RESULT = true;"

    NATIVE_Console_color = @
    "Console.ForegroundColor = (System.ConsoleColor)X_C;"
    "Console_functions.Last_foreground_color = X_C;"

    NATIVE_Console_colors = @
    "Console.ForegroundColor = (System.ConsoleColor)X_F;"
    "Console.BackgroundColor = (System.ConsoleColor)X_B;"
    "Console_functions.Last_foreground_color = X_F;"
    "Console_functions.Last_background_color = X_B;"
    
    NATIVE_Get_console_color = @
    "if (X_Which == 0)"
    "   RESULT = Console_functions.Last_foreground_color;"
    "else RESULT = Console_functions.Last_background_color;"

	NATIVE_Console_ANSI_colors = @
	"	Console_functions.Console_ANSI_colors(X_Add);"
	
	NATIVE_Write_direct  = @
	"  AL4_system.Write_direct(X_S);"
	
	NATIVE_apply_color_ansi = @
	"	Console_functions.apply_color_ansi((int)X_Param, (int)X_Color);"
	
	NATIVE_Get_char = @
	"  RESULT = "#QU#QU" + Console.ReadKey(true).KeyChar;"
	"  if (RESULT.Length == 1 && "
	"	   RESULT[0] == (Char)26)"
	"	  Console_functions.End_input_detected = true;"
	
	NATIVE_End_input = @
	"  RESULT = Console_functions.End_input_detected;"
	
	NATIVE_Input_ready = @
	"	RESULT = Console.KeyAvailable;"
	
	NATIVE_Key_pressed = @
	"	RESULT = Console_functions.Key_pressed((int)X_Key);"
	
	NATIVE_Key_pressed_async = @
	"	RESULT = Console_functions.Key_pressed_async((int)X_Key);"
	
	NATIVE_Cursor_X = @
	"	RESULT = Console.CursorLeft;"
	
	NATIVE_Cursor_Y = @
	"	RESULT = Console.CursorTop;"
	
	NATIVE_Set_cursor_pos = @
	"	Console.SetCursorPosition((int)X_X, (int)X_Y);"
	
	NATIVE_Console_height = @
	"	RESULT = Console.BufferHeight;"
	
	NATIVE_Console_width = @
	"	RESULT = Console.BufferWidth;"
	
	NATIVE_Set_console_size = @
	"	Console.BufferWidth = (int)X_W;"
	"	Console.BufferHeight = (int)X_H;"
	
    .
    

    
END
*/
	}
	
}

