/*
//---------------- set of system functions to use in a final (compiled) project
// This file should be copied to the destination directory if it is necessary.
// To do so, use an option /copy System_functions.cs (source directory should
// be listed with /src option).

CLASS {System_functions|_4primary_compiler_only}, NATIVE, UNTESTED, STOPPING :

IMPORT: {String_functions}, {Console} ;

NATIVE: "using System.Diagnostics;" .
NATIVE: "using System.IO;" .

*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;

namespace AL4_project
{
    public class System_functions
    {

        /*
------------------------------------------ 'INT range'

    CONST INT :
        MAX_INT|EGER_32_VALUE = 0x7FFF_FFFF
        MIN_INT|EGER_32_VALUE = 0x8000_0000 .
        
    ENUMERATION {bool|ean}: //, SYSTEM :
        'FALSE|_Condition_check_failed', 'TRUE|_Condition_satisfied' .
        
    //CONST {bool} :
    //    TRUE | _value = 'TRUE'
    //    FALSE| _value = 'FALSE' .
        
    ENUMERATION {byte|_8_bits}: //, SYSTEM :
        '00|H_BYTE', '01|H_BYTE', '02|H_BYTE', '03|H_BYTE', '04|H_BYTE',
        '05|H_BYTE', '06|H_BYTE', '07|H_BYTE',
        '08|H_BYTE', '09|H_BYTE', '0A|H_BYTE', '0B|H_BYTE', '0C|H_BYTE',
        '0D|H_BYTE', '0E|H_BYTE', '0F|H_BYTE',
        '10|H_BYTE', '11|H_BYTE', '12|H_BYTE', '13|H_BYTE', '14|H_BYTE',
        '15|H_BYTE', '16|H_BYTE', '17|H_BYTE',
        '18|H_BYTE', '19|H_BYTE', '1A|H_BYTE', '1B|H_BYTE', '1C|H_BYTE',
        '1D|H_BYTE', '1E|H_BYTE', '1F|H_BYTE',
        '20|H_BYTE', '21|H_BYTE', '22|H_BYTE', '23|H_BYTE', '24|H_BYTE',
        '25|H_BYTE', '26|H_BYTE', '27|H_BYTE',
        '28|H_BYTE', '29|H_BYTE', '2A|H_BYTE', '2B|H_BYTE', '2C|H_BYTE',
        '2D|H_BYTE', '2E|H_BYTE', '2F|H_BYTE',
        '30|H_BYTE', '31|H_BYTE', '32|H_BYTE', '33|H_BYTE', '34|H_BYTE',
        '35|H_BYTE', '36|H_BYTE', '37|H_BYTE',
        '38|H_BYTE', '39|H_BYTE', '3A|H_BYTE', '3B|H_BYTE', '3C|H_BYTE',
        '3D|H_BYTE', '3E|H_BYTE', '3F|H_BYTE',
        '40|H_BYTE', '41|H_BYTE', '42|H_BYTE', '43|H_BYTE', '44|H_BYTE',
        '45|H_BYTE', '46|H_BYTE', '47|H_BYTE',
        '48|H_BYTE', '49|H_BYTE', '4A|H_BYTE', '4B|H_BYTE', '4C|H_BYTE',
        '4D|H_BYTE', '4E|H_BYTE', '4F|H_BYTE',
        '50|H_BYTE', '51|H_BYTE', '52|H_BYTE', '53|H_BYTE', '54|H_BYTE',
        '55|H_BYTE', '56|H_BYTE', '57|H_BYTE',
        '58|H_BYTE', '59|H_BYTE', '5A|H_BYTE', '5B|H_BYTE', '5C|H_BYTE',
        '5D|H_BYTE', '5E|H_BYTE', '5F|H_BYTE',
        '60|H_BYTE', '61|H_BYTE', '62|H_BYTE', '63|H_BYTE', '64|H_BYTE',
        '65|H_BYTE', '66|H_BYTE', '67|H_BYTE',
        '68|H_BYTE', '69|H_BYTE', '6A|H_BYTE', '6B|H_BYTE', '6C|H_BYTE',
        '6D|H_BYTE', '6E|H_BYTE', '6F|H_BYTE',
        '70|H_BYTE', '71|H_BYTE', '72|H_BYTE', '73|H_BYTE', '74|H_BYTE',
        '75|H_BYTE', '76|H_BYTE', '77|H_BYTE',
        '78|H_BYTE', '79|H_BYTE', '7A|H_BYTE', '7B|H_BYTE', '7C|H_BYTE',
        '7D|H_BYTE', '7E|H_BYTE', '7F|H_BYTE',
        '80|H_BYTE', '81|H_BYTE', '82|H_BYTE', '83|H_BYTE', '84|H_BYTE',
        '85|H_BYTE', '86|H_BYTE', '87|H_BYTE',
        '88|H_BYTE', '89|H_BYTE', '8A|H_BYTE', '8B|H_BYTE', '8C|H_BYTE',
        '8D|H_BYTE', '8E|H_BYTE', '8F|H_BYTE',
        '90|H_BYTE', '91|H_BYTE', '92|H_BYTE', '93|H_BYTE', '94|H_BYTE',
        '95|H_BYTE', '96|H_BYTE', '97|H_BYTE',
        '98|H_BYTE', '99|H_BYTE', '9A|H_BYTE', '9B|H_BYTE', '9C|H_BYTE',
        '9D|H_BYTE', '9E|H_BYTE', '9F|H_BYTE',
        'A0|H_BYTE', 'A1|H_BYTE', 'A2|H_BYTE', 'A3|H_BYTE', 'A4|H_BYTE',
        'A5|H_BYTE', 'A6|H_BYTE', 'A7|H_BYTE',
        'A8|H_BYTE', 'A9|H_BYTE', 'AA|H_BYTE', 'AB|H_BYTE', 'AC|H_BYTE',
        'AD|H_BYTE', 'AE|H_BYTE', 'AF|H_BYTE',
        'B0|H_BYTE', 'B1|H_BYTE', 'B2|H_BYTE', 'B3|H_BYTE', 'B4|H_BYTE',
        'B5|H_BYTE', 'B6|H_BYTE', 'B7|H_BYTE',
        'B8|H_BYTE', 'B9|H_BYTE', 'BA|H_BYTE', 'BB|H_BYTE', 'BC|H_BYTE',
        'BD|H_BYTE', 'BE|H_BYTE', 'BF|H_BYTE',
        'C0|H_BYTE', 'C1|H_BYTE', 'C2|H_BYTE', 'C3|H_BYTE', 'C4|H_BYTE',
        'C5|H_BYTE', 'C6|H_BYTE', 'C7|H_BYTE',
        'C8|H_BYTE', 'C9|H_BYTE', 'CA|H_BYTE', 'CB|H_BYTE', 'CC|H_BYTE',
        'CD|H_BYTE', 'CE|H_BYTE', 'CF|H_BYTE',
        'D0|H_BYTE', 'D1|H_BYTE', 'D2|H_BYTE', 'D3|H_BYTE', 'D4|H_BYTE',
        'D5|H_BYTE', 'D6|H_BYTE', 'D7|H_BYTE',
        'D8|H_BYTE', 'D9|H_BYTE', 'DA|H_BYTE', 'DB|H_BYTE', 'DC|H_BYTE',
        'DD|H_BYTE', 'DE|H_BYTE', 'DF|H_BYTE',
        'E0|H_BYTE', 'E1|H_BYTE', 'E2|H_BYTE', 'E3|H_BYTE', 'E4|H_BYTE',
        'E5|H_BYTE', 'E6|H_BYTE', 'E7|H_BYTE',
        'E8|H_BYTE', 'E9|H_BYTE', 'EA|H_BYTE', 'EB|H_BYTE', 'EC|H_BYTE',
        'ED|H_BYTE', 'EE|H_BYTE', 'EF|H_BYTE',
        'F0|H_BYTE', 'F1|H_BYTE', 'F2|H_BYTE', 'F3|H_BYTE', 'F4|H_BYTE',
        'F5|H_BYTE', 'F6|H_BYTE', 'F7|H_BYTE',
        'F8|H_BYTE', 'F9|H_BYTE', 'FA|H_BYTE', 'FB|H_BYTE', 'FC|H_BYTE',
        'FD|H_BYTE', 'FE|H_BYTE', 'FF|H_BYTE' .
        
    FUNCTION As_byte|_from_integer(
    INT Value|_0_to_255) ==> {byte}, NATIVE : @
        "return (byte)X_Value;" .
        
        
        
        FUN Platform_info|_DUMMY ==> STR : RESULT = "" .
        
        FUN Path_sep|arator ==> STR :
            RESULT = "\" .
        
        FUNCTION Power|_of(
        REAL B|ase_value, REAL Exp|onent) ==> REAL, STATIC, NATIVE :
            "    return Math.Pow(X_B, X_Exp);" .
            
        FUNCTION TEST|_stage ==> BOOL : RESULT = FALSE .
        
		FUNCTION Maximum_recursion|_deep ==> INT: RESULT = 128 .
		
		FUN Set_maximum_recursion|_deep(INT Desired|_value_Dummy): .
        
        */
        public static double Power(double B, double Exp)
        {
            return Math.Pow(B, Exp);
        }
        
        public static string test_command_line = "";

        /*
        //ENUM {colors|_of_console} : 'BLACK|_COLOR', 'BLUE|_COLOR',
        //     'GREEN|_COLOR', 'TEAL|_COLOR', 'MAROON|_COLOR', 'MAGENTA|_COLOR',
        //     'OLIVE|_COLOR', 'GRAY|_COLOR', 'SILVER|_COLOR',
        //     'LIGHT_BLUE|_COLOR',
        //     'LIME|_COLOR', 'CYAN|_COLOR', 'RED|_COLOR', 'FUCHSIA|_COLOR',
        //     'YELLOW|_COLOR', 'WHITE|_COLOR' .

        FUN Console_color|_text_on_black({colors} C|olor_for_text),
                STATIC, NATIVE :
            "Console.ForegroundColor = (System.ConsoleColor)X_C;" .

        FUN Console_colors|_text_and_background(
            {colors} C|olor_for_text, {colors} B|ackground),
                STATIC, NATIVE :
           @"Console.ForegroundColor = (System.ConsoleColor)X_C;"
            "Console.BackgroundColor = (System.ConsoleColor)X_B;" .


        */
        
		public static List<string> Parameters = new List<string>();
        /*
        
 		FUN Count_param|eters_in_command_line ==> INT, NATIVE :
		@   "   //return System_functions.Parameters.Count + 1;" 
			"	return Environment.GetCommandLineArgs().Length;".
		
		FUN Parameter|_in_command_line_by_index(
		INT Index|_of_parameter) ==> STR,
		    NATIVE :
		@	"   if (X_Index < 0 || "
            "       //X_Index >= System_functions.Parameters.Count + 1)"
            "       X_Index >= Environment.GetCommandLineArgs().Length)"
            "       return " #QU#QU ";"
            "	//if (X_Index == 0)"
			"	//	return Environment.GetCommandLineArgs()[0];"   
			"   //else return AL4_system.System_parameters[X_Index-1];"
			"	return Environment.GetCommandLineArgs()[X_Index];" .       
	
        FUNCTION Get_command_line ==> STR, STATIC, NATIVE :
           @"    if (System_functions.test_command_line != " #QU #QU ")"
            "        return System_functions.test_command_line;"
            "    return Environment.CommandLine;" .
        */
        public static string Get_command_line()
        {
            return Environment.CommandLine;
        }

        /*
        
        FUNCTION Change_command_line(
        STR Val|ue_to_set), STATIC, NATIVE :
            "    System_functions.test_command_line = X_Val;" .
        */

        /****************)
        FUN Set_working_dir|ectory(STR Path|_directory), STATIC, NATIVE :
            "    Directory.SetCurrentDirectory(X_Path);" .
        (****************/
        public static void Set_working_dir(string Path_dir)
        {
            Directory.SetCurrentDirectory(Path_dir);
        }

        /*
        
        FUN Get_working_dir|ectory ==> STR, STATIC, NATIVE :
            "    return Directory.GetCurrentDirectory();" .
        */


        /*
        
        FUN Get_windows_dir|ectory ==> STR, STATIC, NATIVE :
            "    return System.IO.Path.GetDirectoryName"
            "(Environment.SystemDirectory);" .
        */
        public static string Get_windows_dir()
        {
            return System.IO.Path.GetDirectoryName(Environment.SystemDirectory);
        }

        /*
        
        FUN Execute_program(STR App|lication_path, STR Param|eters,
                INT Redirect|_output_error) ==> STR, STATIC :
            CASE TEST ?
                 STOP "In TEST mode, can not execute external programs" ;
            RESULT = execute_program(App, Param, Redirect) .

        FUN execute_program(STR App|lication_path, STR Param|eters,
                INT Redirect|_output_error) ==> STR, STATIC, NATIVE :
           @"    string outp = " #QU #QU ";"
            "    try {"
            "        Process p = new Process {"
            "            StartInfo = new ProcessStartInfo {"
            "                FileName = X_App,"
            "                Arguments = X_Param"
            "            }"
            "        };"
            "        if (X_Redirect != 0) {"
            "           p.StartInfo.UseShellExecute = false;"
            "           p.StartInfo.RedirectStandardOutput ="
            "               (X_Redirect & 1) != 0;"
            "           p.StartInfo.RedirectStandardError ="
            "               (X_Redirect & 2) != 0;"
            "           p.Start();"
            "           if ((X_Redirect & 2) != 0 &&"
            "              !p.StandardError.EndOfStream)"
            "              outp += p.StandardError.ReadToEnd();"
            "           if ((X_Redirect & 1) != 0 &&"
            "              !p.StandardOutput.EndOfStream)"
            "              outp += p.StandardOutput.ReadToEnd();"
            "           p.WaitForExit();"
            "           return outp;"
            "        }"
            "        p.Start();"
            "        p.WaitForExit();"
            "        return " #QU #QU ";"
            "    }"
            "    catch (Exception E) {"
            "          outp += " #QU "\r\n" #QU " + E.Message;"
            "          return outp;"
            "    }" .
        */
        public static string Execute_program(string App, string Param, bool Redirect)
        {
            Process p = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = App,
                    Arguments = Param
                }
            };
            if (Redirect)
            {
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.UseShellExecute = false;
                p.Start();
                string outp = p.StandardOutput.ReadToEnd();
                p.WaitForExit();
                return outp;
            }
            p.Start();
            p.WaitForExit();
            return "";
        }

        /*
        
        FUN Start_program(
        STR App|lication_path, STR Param|eters),
                STATIC :
            CASE TEST ? STOP "In TEST mode, can not start external programs" ;
            start_program(App, Param) .

        FUN start_program(STR App|lication_path, STR Param|eters),
                STATIC, NATIVE :
            "    Process.Start(X_App, X_Param);" .
        */
        public static void Start_program(string App, string Param)
        {
            Process.Start(App, Param);
        }

        /*
        
        FUN Ref_count(
        {Object} Obj|ect_inspecting) ==> INT, STATIC, NATIVE :
            "return X_Obj.Count;" .
        
        
        FUN Stop_if_test(STR T|est_must_be_present), STATIC :
            CASE !TEST ? ==> ;
            CASE "test" IN T.Lower ? ==> ;
            STOP "In test mode files can not be changed unless these have "
                 "'test' substring in a name or a path".
                 
		FUNCTION Sleep|_milliseconds(
		INT M|illiseconds), NATIVE :
            "    System.Threading.Thread.Sleep(X_M);" .

        FUN Get_environment_var|iable(
            STR Name|_of_variable) ==> STR, STATIC, NATIVE :
            "    return System_functions.Do_Get_environment_var(X_Name);" .
        */
        public static string Do_Get_environment_var(string Name)
        {
            string Result = Environment.GetEnvironmentVariable(Name);
            if (Result == null) Result = "";
            return Result;
        }

        /*
        FUNCTION Start_dir ==> STR, STATIC :
            RESULT = startup_path.Trailing_slash .

        FUN startup_path ==> STR, STATIC, NATIVE :
            "    return Path.GetDirectoryName("
            "Environment.GetCommandLineArgs()[0]);" .
            
        FUN Total_obj_index( {Object} Obj|ect_of_any_class ) ==> INT, 
            STATIC, NATIVE :
           @"    return X_Obj.Obj.TOTAL_obj_index;" .
           
        FUN Absolute_path|_from_relative_path( STR Path|_relative ) ==> STR, 
            STATIC, NATIVE :
           @"   return Path.GetFullPath(X_Path);" .
        */
        public static string Start_dir()
        {
            string Result = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);
            if (Result != "" && Result[Result.Length - 1] != '\\')
                Result += "\\";
            return Result;
        }
        
        /*

        FUN File_size_kbytes(STR File_name|Dummy) ==> REAL :
        	RESULT = 0 .
        --------------------- 'debug control'
		
		FUN Trace_blocks|_DUMMY_varinat(BOOL On|_tracing_DUMMY) : .
        
        */


    }
}
/*
END
*/
