/*
//---------------- 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
    {

        /*
        
        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): .
        
        */
        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;" .


        CONST INT :
            MAX_INT|EGER_VALUE = 0x7FFF_FFFF
            MIN_INT|EGER_VALUE = 0xFFFF_FFFF .

        FUN Abs|olute_real_number(REAL X|_argument) ==> REAL, STATIC, NATIVE :
            "    return Math.Abs(X_X);" .
        */
        
		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) ==> REAL :
        	RESULT = 0 .
        
        
        */


    }
}
/*
END
*/
