//  
//  scriptFunctions.cs
//  
//  Author:
//       Robert BRACCAGNI alias Gai-Luron <lfsgailuron@free.fr>
// 
//  Copyright (c) 2010 Gai-Luron
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections;
using UTILS;
using System.Threading;
using System.IO;
using LapperThreads;
using System.Text.RegularExpressions;

namespace LFSLapper
{
    partial class LFSClient
    {
        class LOP
        {
            public string userName = "";
            public string nickName = "";
            public LOP(string pUN, string pNN)
            {
                userName = pUN;
                nickName = pNN;
            }
        }
        public class sortByUName : IComparer
        {
            int IComparer.Compare(object a, object b)
            {
                if (string.Compare((a as LOP).userName, (b as LOP).userName) > 0)
                    return 1;
                else if (string.Compare((a as LOP).userName, (b as LOP).userName) < 0)
                    return -1;
                else
                    return 0;
            }
        }
        public class sortByNName : IComparer
        {
            int IComparer.Compare(object a, object b)
            {
                if (string.Compare((a as LOP).nickName, (b as LOP).nickName) > 0)
                    return 1;
                else if (string.Compare((a as LOP).nickName, (b as LOP).nickName) < 0)
                    return -1;
                else
                    return 0;
            }
        }
        public void initScriptFunction()
        {
            newCfg.CurrApp.registerCallBackFunction("getplayerinfo", getplayerinfo);
            newCfg.CurrApp.registerCallBackFunction("setracegrid", setracegrid);
            newCfg.CurrApp.registerCallBackFunction("requestreo", requestreo);
            newCfg.CurrApp.registerCallBackFunction("getlistofplayers", getlistofplayers);
            newCfg.CurrApp.registerCallBackFunction("getlappervar", getlappervar);
            newCfg.CurrApp.registerCallBackFunction("getconfigvar", getconfigvar);
            newCfg.CurrApp.registerCallBackFunction("setconfigvar", setconfigvar);
            newCfg.CurrApp.registerCallBackFunction("langtranslate", langtranslate);
            newCfg.CurrApp.registerCallBackFunction("langengine", langengine);
            newCfg.CurrApp.registerCallBackFunction("forcerotation", forcerotation);
            newCfg.CurrApp.registerCallBackFunction("termlapper", termlapper);
            newCfg.CurrApp.registerCallBackFunction("setlicense", setlicense);
            newCfg.CurrApp.registerCallBackFunction("myconfig", myconfig);
            newCfg.CurrApp.registerCallBackFunction("http", http);
            newCfg.CurrApp.registerCallBackFunction("userisadmin", userisadmin);
            newCfg.CurrApp.registerCallBackFunction("userisserveradmin", userisserveradmin);
            newCfg.CurrApp.registerCallBackFunction("showhand", showhand);
            newCfg.CurrApp.registerCallBackFunction("lapperversion", lapperversion);
            newCfg.CurrApp.registerCallBackFunction("reload", reload);
            newCfg.CurrApp.registerCallBackFunction("crash", crash);
            newCfg.CurrApp.registerCallBackFunction("getlistoflang", getlistoflang);
            newCfg.CurrApp.registerCallBackFunction("getlistofplayerbuttons", getlistofplayerbuttons);
            newCfg.CurrApp.registerCallBackFunction("striplfscolor", striplfscolor);
            newCfg.CurrApp.registerCallBackFunction("getwr", getwr);
            newCfg.CurrApp.registerCallBackFunction("getlayoutinfo", getlayoutinfo);
            newCfg.CurrApp.registerCallBackFunction("startlightcontrol", startlightcontrol);
            newCfg.CurrApp.registerCallBackFunction("joinrequest", joinrequest);
            newCfg.CurrApp.registerCallBackFunction("setcarhandicap", setcarhandicap);

            //Convertion
            newCfg.CurrApp.registerCallBackFunction("numtomsh", numtomsh);
            newCfg.CurrApp.registerCallBackFunction("numtoms", numtoms);
            newCfg.CurrApp.registerCallBackFunction("mshtonum", mshtonum);
            newCfg.CurrApp.registerCallBackFunction("tokph", tokph);
            newCfg.CurrApp.registerCallBackFunction("tomph", tomph);
            newCfg.CurrApp.registerCallBackFunction("toplayerunit", toplayerunit);

            //Set/get Player Vars
            newCfg.CurrApp.registerCallBackFunction("setcurrentplayervar", setcurrentplayervar);
            newCfg.CurrApp.registerCallBackFunction("getcurrentplayervar", getcurrentplayervar);
            newCfg.CurrApp.registerCallBackFunction("setplayervar", setplayervar);
            newCfg.CurrApp.registerCallBackFunction("getplayervar", getplayervar);
            newCfg.CurrApp.registerCallBackFunction("getplayervarbyucid", getplayervarbyucid);
            newCfg.CurrApp.registerCallBackFunction("getplayervarbyplid", getplayervarbyplid);

            //Get stats
            newCfg.CurrApp.registerCallBackFunction("cleanspb", cleanspb);
            newCfg.CurrApp.registerCallBackFunction("showspb", showspb);
            newCfg.CurrApp.registerCallBackFunction("stats", stats);
            newCfg.CurrApp.registerCallBackFunction("dstats", dstats);
            newCfg.CurrApp.registerCallBackFunction("statsqual", statsqual);
            newCfg.CurrApp.registerCallBackFunction("dstatsqual", dstatsqual);
            newCfg.CurrApp.registerCallBackFunction("getusergrippb", getusergrippb);
            newCfg.CurrApp.registerCallBackFunction("getuserdriftpb", getuserdriftpb);
            newCfg.CurrApp.registerCallBackFunction("getlisttop", getlisttop);
            newCfg.CurrApp.registerCallBackFunction("getlisttopdrift", getlisttopdrift);
            newCfg.CurrApp.registerCallBackFunction("getlisttopuser", getlisttopuser);
            newCfg.CurrApp.registerCallBackFunction("currentplayerlfsworldpb", currentplayerlfsworldpb);
            newCfg.CurrApp.registerCallBackFunction("currentplayerlfsworldpbfrom", currentplayerlfsworldpbfrom);

            //Messages
            newCfg.CurrApp.registerCallBackFunction("privrcm", privrcm);
            newCfg.CurrApp.registerCallBackFunction("globalrcm", globalrcm);
            newCfg.CurrApp.registerCallBackFunction("privmsg", privmsg);
            newCfg.CurrApp.registerCallBackFunction("globalmsg", globalmsg);
            newCfg.CurrApp.registerCallBackFunction("groupcmdlfs", groupcmdlfs);
            newCfg.CurrApp.registerCallBackFunction("cmdlfs", cmdlfs);

            //Buttons
            //OpenButtons
            newCfg.CurrApp.registerCallBackFunction("openprivbutton", openprivbutton);
            newCfg.CurrApp.registerCallBackFunction("openbutton", openbutton);
            newCfg.CurrApp.registerCallBackFunction("textprivbutton", textprivbutton);
            newCfg.CurrApp.registerCallBackFunction("textprivbuttonall", textprivbuttonall);
            newCfg.CurrApp.registerCallBackFunction("openprivtextbutton", openprivtextbutton);
            newCfg.CurrApp.registerCallBackFunction("opentextbutton", opentextbutton);
            newCfg.CurrApp.registerCallBackFunction("openglobalbutton", openglobalbutton);

            //Close Buttons
            newCfg.CurrApp.registerCallBackFunction("closeglobalbutton", closeglobalbutton);
            newCfg.CurrApp.registerCallBackFunction("closeprivbutton", closeprivbutton);
            newCfg.CurrApp.registerCallBackFunction("closebutton", closebutton);

            //Usergroups Create/Delete Usergroups
            newCfg.CurrApp.registerCallBackFunction("moveusertogroup", moveusertogroup);
            newCfg.CurrApp.registerCallBackFunction("getlistofusersgroup", getlistofusersgroup);
            newCfg.CurrApp.registerCallBackFunction("usergroupfromfile", usergroupfromfile);
            newCfg.CurrApp.registerCallBackFunction("usergrouptofile", usergrouptofile);
            newCfg.CurrApp.registerCallBackFunction("removeuserfromgroup", removeuserfromgroup);
            newCfg.CurrApp.registerCallBackFunction("cleargroup", cleargroup);
            newCfg.CurrApp.registerCallBackFunction("useringroup", useringroup);

            //Get/Set/delete Stored (user) values.
            newCfg.CurrApp.registerCallBackFunction("setstoredvalue", setstoredvalue);
            newCfg.CurrApp.registerCallBackFunction("getstoredvalue", getstoredvalue);
            newCfg.CurrApp.registerCallBackFunction("getstorednum", getstorednum);
            newCfg.CurrApp.registerCallBackFunction("deletestoredvalue", deletestoredvalue);
            newCfg.CurrApp.registerCallBackFunction("setuserstoredvalue", setuserstoredvalue);
            newCfg.CurrApp.registerCallBackFunction("setuserstorednum", setuserstoredvalue);
            newCfg.CurrApp.registerCallBackFunction("getuserstoredvalue", getuserstoredvalue);
            newCfg.CurrApp.registerCallBackFunction("getuserstorednum", getuserstorednum);
            newCfg.CurrApp.registerCallBackFunction("deleteuserstoredvalue", deleteuserstoredvalue);

            //DelayedCommand actions
            newCfg.CurrApp.registerCallBackFunction("removedelayedcommand", removedelayedcommand);
            newCfg.CurrApp.registerCallBackFunction("delayedcommand", delayedcommand);
            newCfg.CurrApp.registerCallBackFunction("removeprivdelayedcommand", removeprivdelayedcommand);
            newCfg.CurrApp.registerCallBackFunction("privdelayedcommand", privdelayedcommand);
            newCfg.CurrApp.registerCallBackFunction("removehostdelayedcommand", removehostdelayedcommand);
            newCfg.CurrApp.registerCallBackFunction("hostdelayedcommand", hostdelayedcommand);
            newCfg.CurrApp.registerCallBackFunction("removeplayerdelayedcommand", removeplayerdelayedcommand);
            newCfg.CurrApp.registerCallBackFunction("playerdelayedcommand", playerdelayedcommand);

            newCfg.CurrApp.registerCallBackFunction("getlongtrackname", getlongtrackname);
            newCfg.CurrApp.registerCallBackFunction("getlengthtrack", getlengthtrack);
            newCfg.CurrApp.registerCallBackFunction("getgrouptrack", getgrouptrack);
            newCfg.CurrApp.registerCallBackFunction("getexttrack", getexttrack);

            //Schedule Actions
            newCfg.CurrApp.registerCallBackFunction("registerscheduleaction", registerscheduleaction);
            newCfg.CurrApp.registerCallBackFunction("removescheduleaction", removescheduleaction);

            //Node/Zone Actions
            newCfg.CurrApp.registerCallBackFunction("registernodeaction", registernodeaction);
            newCfg.CurrApp.registerCallBackFunction("removenodeaction", removenodeaction);
            newCfg.CurrApp.registerCallBackFunction("registerzoneaction", registerzoneaction);
            newCfg.CurrApp.registerCallBackFunction("removezoneaction", removezoneaction);

            //Player Detection
            newCfg.CurrApp.registerCallBackFunction("registerplayerdetection", registerplayerdetection);
            newCfg.CurrApp.registerCallBackFunction("removeplayerdetection", removeplayerdetection);

            //Set allowed cars to the server or player
            newCfg.CurrApp.registerCallBackFunction("allowedplayercars", allowedplayercars);
            newCfg.CurrApp.registerCallBackFunction("setallowedcars", setallowedcars);

            //Calculation Distance/Angle between players/objects
            newCfg.CurrApp.registerCallBackFunction("getdistance", trackuserdistance); //Distance measurement between Objects and Players (New)
            newCfg.CurrApp.registerCallBackFunction("trackuserdistance", trackuserdistance); //Distance measurement between Objects and Players (OLD)
            newCfg.CurrApp.registerCallBackFunction("getangle", getangle); //Returns Angle value between Objects and Players

            //axm insimpacket
            newCfg.CurrApp.registerCallBackFunction("addobject", addobject);
            newCfg.CurrApp.registerCallBackFunction("removeobject", removeobject);
            newCfg.CurrApp.registerCallBackFunction("getlytselection", getlytselection);
            newCfg.CurrApp.registerCallBackFunction("setlytselection", setlytselection);
            newCfg.CurrApp.registerCallBackFunction("layoutinfo", layoutinfo); //Info about the layout TINY_AXI
            newCfg.CurrApp.registerCallBackFunction("connectioninfo", connectinfo);//Get extra player (EACH PLAYER IN THE SERVER) info for the host NCI insimpacket

            //Deleting records from database
            newCfg.CurrApp.registerCallBackFunction("deletedriftrecords", deletedriftrecords); //Delete driftrecords from current track from database
            newCfg.CurrApp.registerCallBackFunction("deletelaptimerecords", deletelaptimerecords); //Delete laptime records from current track from database

            //Streetcode Yisc[NL]
            newCfg.CurrApp.registerCallBackFunction("registerstreetaction", registerstreetaction);
            newCfg.CurrApp.registerCallBackFunction("removestreetaction", removestreetaction);

            //Retreive list of layouts from server
            newCfg.CurrApp.registerCallBackFunction("getlistoflayouts", getlistoflayouts);

            //Create/Read/Edit/Delete Files
            newCfg.CurrApp.registerCallBackFunction("createfile", createfile);
            newCfg.CurrApp.registerCallBackFunction("readfile", readfile);
            newCfg.CurrApp.registerCallBackFunction("deletefile", deletefile);
            newCfg.CurrApp.registerCallBackFunction("editfile", editfile);
            newCfg.CurrApp.registerCallBackFunction("fileexist", fileexist);

            //Create/Delete Directory's & Get list of files within the Directory
            newCfg.CurrApp.registerCallBackFunction("CreateDirectory", createdirectory);
            newCfg.CurrApp.registerCallBackFunction("DeleteDirectory", deletedirectory);
            newCfg.CurrApp.registerCallBackFunction("DirectoryExist", directoryexist);
            newCfg.CurrApp.registerCallBackFunction("GetListOfFiles", GetListOfFiles);

            //local feature to turn on Lights/horn of the car
            newCfg.CurrApp.registerCallBackFunction("carswitches", carswitches);

            //Discord Functions
            newCfg.CurrApp.registerCallBackFunction("sendmessagetodiscord", sendmessagetodiscord);
            newCfg.CurrApp.registerCallBackFunction("senddiscordembed", senddiscordembed);

            // Get/Set Allowed mods Functions
            newCfg.CurrApp.registerCallBackFunction("setlistallowedmods", setlistallowedmods);
            newCfg.CurrApp.registerCallBackFunction("getlistallowedmods", getlistallowedmods);

            //TestFunctions
            newCfg.CurrApp.registerCallBackFunction("testfunction", TestFunction);
            newCfg.CurrApp.registerCallBackFunction("getmoddedcarinfo", getmoddedcarinfo);
        }

        public void getmoddedcarinfo(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer;

            string ident = val.nameFunction;
            string Requestmodinfo = "";
            val.typVal = GLScript.typVal.setOfVar;
            val.setVars = new GLScript.SetOfVars();

            if (args[0].ToString() != "")
            {
                currInfoPlayer = listOfPlayers.getPlayerByUserName(args[0].ToString());

                if (currInfoPlayer == null)
                    Requestmodinfo = args[0].ToString();
                else
                    Requestmodinfo = currInfoPlayer.CName;

                try
                {
                    if (newCfg.varsLapper.RestAPIClientID == "" || newCfg.varsLapper.RestAPIClientSecret == "")
                    {
                        val.setVars.Set(utils.quote("status"), new GLScript.unionVal(0, "\"" + "Incorrect LFSRestAPI ClientID or ClientSecret!" + "\"", GLScript.typVal.str));
                    }
                    else
                    {
                        //Set Number of Layout Var
                        var VehInfo = LFSRestAPI.GetVehicleInfo(newCfg.varsLapper.RestAPIClientID, newCfg.varsLapper.RestAPIClientSecret, Requestmodinfo).Result;
                        if (VehInfo != null)
                        {
                            //Convert PubishedDate from long to proper string format
                            DateTime StartPublishDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                            DateTime PublishDate = StartPublishDate.AddSeconds(VehInfo.data.publishedAt);
                            string newpublisheddate = PublishDate.ToString("ddd d/MM/yyyy HH:mm");

                            //Convert LastDownloadedAt from long to proper string format
                            DateTime StartLastDownload = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                            DateTime LastDownloadDate = StartLastDownload.AddSeconds(VehInfo.data.lastDownloadedAt);
                            string NewLastDownloadDate = LastDownloadDate.ToString("ddd d/MM/yyyy HH:mm");

                            string ClassOfCar = Enum.GetName(typeof(LFSRestAPI.Class), VehInfo.data.Class);
                            string IceLayout = Enum.GetName(typeof(LFSRestAPI.iceLayout), VehInfo.data.vehicle.iceLayout);
                            string DriveTrain = Enum.GetName(typeof(LFSRestAPI.drivetrains), VehInfo.data.vehicle.drive);
                            string ShiftType = Enum.GetName(typeof(LFSRestAPI.shiftType), VehInfo.data.vehicle.shiftType);

                            //Create Array with all the variables retrieved from the REST_API
                            val.setVars.Set(utils.quote("status"), new GLScript.unionVal(0, "\"" + "OK" + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("id"), new GLScript.unionVal(0, "\"" + VehInfo.data.id.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("name"), new GLScript.unionVal(0, "\"" + VehInfo.data.name.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("descriptionshort"), new GLScript.unionVal(0, "\"" + VehInfo.data.descriptionShort.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("description"), new GLScript.unionVal(0, "\"" + VehInfo.data.description.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("userid"), new GLScript.unionVal(0, "\"" + VehInfo.data.userId.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("username"), new GLScript.unionVal(0, "\"" + VehInfo.data.userName.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("wip"), new GLScript.unionVal(0, "\"" + VehInfo.data.wip.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("publishedat"), new GLScript.unionVal(0, "\"" + newpublisheddate + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("numdownloads"), new GLScript.unionVal(0, "\"" + VehInfo.data.numDownloads.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("currusage"), new GLScript.unionVal(0, "\"" + VehInfo.data.curUsage.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("rating"), new GLScript.unionVal(0, "\"" + VehInfo.data.rating.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("numratings"), new GLScript.unionVal(0, "\"" + VehInfo.data.numRatings.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("staffpick"), new GLScript.unionVal(0, "\"" + VehInfo.data.staffPick.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("tweakmod"), new GLScript.unionVal(0, "\"" + VehInfo.data.tweakMod.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("version"), new GLScript.unionVal(0, "\"" + VehInfo.data.version.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("lastdownloadedat"), new GLScript.unionVal(0, "\"" + NewLastDownloadDate + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("class"), new GLScript.unionVal(0, "\"" + ClassOfCar + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("ev"), new GLScript.unionVal(0, "\"" + VehInfo.data.ev.ToString() + "\"", GLScript.typVal.str));

                            //Vehicle Info
                            val.setVars.Set(utils.quote("icecc"), new GLScript.unionVal(0, "\"" + VehInfo.data.vehicle.iceCc.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("icenumcylinders"), new GLScript.unionVal(0, "\"" + VehInfo.data.vehicle.iceNumCylinders.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("icelayout"), new GLScript.unionVal(0, "\"" + IceLayout + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("evredLine"), new GLScript.unionVal(0, "\"" + VehInfo.data.vehicle.evRedLine.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("drive"), new GLScript.unionVal(0, "\"" + DriveTrain + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("shifttype"), new GLScript.unionVal(0, "\"" + ShiftType + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("power"), new GLScript.unionVal(0, "\"" + VehInfo.data.vehicle.power.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("maxpowerrpm"), new GLScript.unionVal(0, "\"" + VehInfo.data.vehicle.maxPowerRpm.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("mass"), new GLScript.unionVal(0, "\"" + VehInfo.data.vehicle.mass.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("bhp"), new GLScript.unionVal(0, "\"" + VehInfo.data.vehicle.bhp.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("powerweightratio"), new GLScript.unionVal(0, "\"" + VehInfo.data.vehicle.powerWeightRatio.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("bhpton"), new GLScript.unionVal(0, "\"" + VehInfo.data.vehicle.bhpTon.ToString() + "\"", GLScript.typVal.str));
                            val.setVars.Set(utils.quote("fueltanksize"), new GLScript.unionVal(0, "\"" + VehInfo.data.vehicle.fuelTankSize.ToString() + "\"", GLScript.typVal.str));
                        }
                    }


                    /*
                    if (args[0].ToString() == "")
                    {
                        //var CarInfo = LFSRestAPI.GetListOfModdedCars(newCfg.varsLapper.RestAPIClientID, newCfg.varsLapper.RestAPIClientSecret).Result;
                        Console.WriteLine(CarInfo[0].name);

                        val.setVars.Set(utils.quote("NrOfMods"), new GLScript.unionVal(0, "\"" + CarInfo.Count + "\"", GLScript.typVal.str));
                        for (int i = 0; i < CarInfo.Count; i++)
                        {

                                val.setVars.Set(i.ToString() + "," + utils.quote("id"), new GLScript.unionVal(0, "\"" + CarInfo[i].id + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("name"), new GLScript.unionVal(0, "\"" + CarInfo[i].name + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("descriptionshort"), new GLScript.unionVal(0, "\"" + CarInfo[i].descriptionShort + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("description"), new GLScript.unionVal(0, "\"" + CarInfo[i].description + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("userid"), new GLScript.unionVal(0, "\"" + CarInfo[i].userId + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("userName"), new GLScript.unionVal(0, "\"" + CarInfo[i].userName + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("wip"), new GLScript.unionVal(0, "\"" + CarInfo[i].wip + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("publishedAt"), new GLScript.unionVal(0, "\"" + CarInfo[i].publishedAt + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("numdownloads"), new GLScript.unionVal(0, "\"" + CarInfo[i].numDownloads + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("numratings"), new GLScript.unionVal(0, "\"" + CarInfo[i].numRatings + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("version"), new GLScript.unionVal(0, "\"" + CarInfo[i].version + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("lastdownloadedat"), new GLScript.unionVal(0, "\"" + CarInfo[i].lastDownloadedAt + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("class"), new GLScript.unionVal(0, "\"" + CarInfo[i]._class + "\"", GLScript.typVal.str));
                                val.setVars.Set(i.ToString() + "," + utils.quote("ev"), new GLScript.unionVal(0, "\"" + CarInfo[i].ev + "\"", GLScript.typVal.str));

                        newCfg.ListOfModdedCar.Add("" + CarInfo[i].id + "," + CarInfo[i].name); //First line of array
                        }

                    }
        */
                }
                catch (Exception ex)
                {
                    val.setVars.Set(utils.quote("status"), new GLScript.unionVal(0, "\"" + "No mod info available!" + "\"", GLScript.typVal.str));
                }
            }
        }

        public void getlistallowedmods(GLScript.unionVal val, ArrayList args)
        {
           
            val.typVal = GLScript.typVal.setOfVar;
            val.setVars = new GLScript.SetOfVars();

            val.setVars.Set(utils.quote("NrOfAllowedMods"), new GLScript.unionVal(0, "\"" + newCfg.varsLapper.AmountofModdedCars + "\"", GLScript.typVal.str));
            for (int i = 0; i < newCfg.varsLapper.AmountofModdedCars; i++)
            {
                string ModHexinfo = newCfg.ListOfAllowedModdedCars[i] as string;
                
                val.setVars.Set(i.ToString() + "," + utils.quote("SkinID"), new GLScript.unionVal(0, "\"" + ModHexinfo + "\"", GLScript.typVal.str));
            }
        }
    
        public void setlistallowedmods(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            int Error = 0;
            string ident = val.nameFunction;
            int MaxModsCount = 120;
            int NumM = 0;
            int ActualCorrectMods = 0;
            int Flag = 0;
            string[] ListOfModsSkinID = new string[MaxModsCount];
            uint[] Mod_SkinID = new uint[MaxModsCount];

            //if list cannot be created. first value is 0.
            Mod_SkinID[0] = 00000000;

            if (args.Count != 1)
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' Incorrect number or parameters");

            //if string is not empty
            if (args[0].ToString() != "")
            {
                ListOfModsSkinID = args[0].ToString().Split(','); //Split String into array 
                NumM = ListOfModsSkinID.Length; //Mods Count
                Mod_SkinID = new uint[NumM];

                //Check amount of set mods.
                if ((NumM < MaxModsCount))
                {
                    for (int i = 0; i < NumM; i++)
                    {
                        //Set blank mods to 0.
                        if (ListOfModsSkinID[i] != "")
                        {
                            Mod_SkinID[ActualCorrectMods] = Convert.ToUInt32(ListOfModsSkinID[i], 16); //Convert String into UInt32
                            ActualCorrectMods++;
                        }
                    }
                }
                else
                {
                    Error = 1;
                    throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' Exceeded mods limit. Limit is 120.");
                }
            }
            else
            {
              
            }

            if (Error == 0)
            {
                //Convert data into Packets and Send MAL packet to LFS
                byte[] mal = myEncoder.MAL(byte.Parse(currInfoPlayer.UCID.ToString()), byte.Parse(ActualCorrectMods.ToString()), byte.Parse(Flag.ToString()), Mod_SkinID);
                insimConnection.Send(mal, mal.Length);
            }
        }


        public void senddiscordembed(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            ulong EmbedDiscordChannel;
            string EmbedTitle;
            string EmbedDescription;
            uint EmbedColor = 0xFFFFFF;
            string EmbedFieldTitle;
            string EmbedFieldInline;
            string EmbedFieldFooter;
            string EmbedThumbNailURL = "";
            string EmbedImageURL = "";

            //Count args
            if (args.Count == 10)
            {
                if(args[0].ToString() != "")
                    EmbedDiscordChannel = UInt64.Parse(args[0].ToString());
                else
                    throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' Discordchannel not valid");

                EmbedTitle = args[1].ToString();
                EmbedDescription = args[2].ToString();

                //Convert Color HexString into Valid Hex value
                if (args[3].ToString().StartsWith("0x"))
                    EmbedColor = Convert.ToUInt32(args[3].ToString(), 16);
                else
                    throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' Invalid colorcode, Hex prefix must start with '0x' 0x000000");

                //Field Values , Multiple fields possible with %nf%
                EmbedFieldTitle = args[4].ToString();

                var EmbedFieldValue = Regex.Unescape(args[5].ToString());
                EmbedFieldInline = args[6].ToString();

                EmbedFieldFooter = args[7].ToString();

                //Thumbnail and Image
                EmbedThumbNailURL = args[8].ToString();
                EmbedImageURL = args[9].ToString();

                DiscordBot.SendDiscordBotEmbed(EmbedDiscordChannel, EmbedTitle, EmbedDescription, EmbedColor, EmbedFieldTitle, EmbedFieldValue, EmbedFieldInline, EmbedFieldFooter, EmbedThumbNailURL, EmbedImageURL);
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' incorrect number of parameters.");
            }
        }

        public void setcarhandicap(GLScript.unionVal val, ArrayList args)
        {
            /*
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            try
            {
                if (args.Count == 3)
                {
                    int CarValue = 0;
                    byte i = 0;
                    string[] SelectedCars = args[0].ToString().Split('+');
                    int H_Mass = int.Parse(args[1].ToString());
                    int H_Tres = int.Parse(args[2].ToString());

                    foreach (string car in SelectedCars)
                    {
                        #region carvalues 
                        switch (car.ToUpper())
                        {
                            case "XFG": CarValue = CarValue + 0; break;
                            case "XRG": CarValue = CarValue + 1; break;
                            case "XRT": CarValue = CarValue + 2; break;
                            case "RB4": CarValue = CarValue + 3; break;
                            case "FXO": CarValue = CarValue + 4; break;
                            case "LX4": CarValue = CarValue + 5; break;
                            case "LX6": CarValue = CarValue + 6; break;
                            case "MRT": CarValue = CarValue + 7; break;
                            case "UF1": CarValue = CarValue + 8; break;
                            case "RAC": CarValue = CarValue + 9; break;
                            case "FZ5": CarValue = CarValue + 10; break;
                            case "FXR": CarValue = CarValue + 15; break;
                            case "XRR": CarValue = CarValue + 16; break;
                            case "FZR": CarValue = CarValue + 17; break;
                            case "UFR": CarValue = CarValue + 13; break;
                            case "XFR": CarValue = CarValue + 12; break;
                            case "FOX": CarValue = CarValue + 11; break;
                            case "FO8": CarValue = CarValue + 14; break;
                            case "FBM": CarValue = CarValue + 19; break;
                            case "BF1": CarValue = CarValue + 18; break;
                        }
                        #endregion
                        i++;
                    }
                    if ((H_Mass > 200) || (H_Mass < 0))
                    {
                        H_Mass = 0;
                    }
                    if ((H_Tres > 50) || (H_Tres < 0))
                    {
                        H_Tres = 0;
                    }
                    byte[] hcp = myEncoder.HCP(byte.Parse(CarValue.ToString()), byte.Parse(H_Mass.ToString()), byte.Parse(H_Tres.ToString()));
                    insimConnection.Send(hcp, hcp.Length);
                }
            }
            catch
            {
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' incorrect number of parameters or invalid parameters.");
            }
            */
        }

        public void sendmessagetodiscord(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            ulong DiscordChannel;

            try
            {
                if (args.Count == 2)
                {
                    var Message = Regex.Unescape(args[1].ToString());
                    DiscordChannel = UInt64.Parse(args[0].ToString());

                    //Putt message into queue
                    incomingdiscordmsgstack.Enqueue(DiscordChannel + "/" + Message);
                }
            }
            catch
            {
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' invalid channel or message.");
            }
        }

        public void registerplayerdetection(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            string AngleOfDetection = "";
            string DistanceOfDetection = "";
            string CmdDetected = "";
            infoPlayer currInfoPlayer;
            if (args.Count == 4)
            {
                currInfoPlayer = listOfPlayers.getPlayerByUserName(args[0].ToString());
                if (currInfoPlayer.userName != "")
                {
                    try
                    {
                        AngleOfDetection = args[1].ToString();
                        DistanceOfDetection = args[2].ToString();
                        CmdDetected = args[3].ToString();
                        currInfoPlayer.PlayerDetectorInfo = AngleOfDetection + "|" + DistanceOfDetection + "|" + CmdDetected;
                    }
                    catch
                    {

                    }
                }
                else
                {
                    throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' Invalid username!");
                }
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' incorrect number of parameters!");
            }
        }
        public void removeplayerdetection(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            infoPlayer currInfoPlayer;
            if (args.Count == 1)
            {
                currInfoPlayer = listOfPlayers.getPlayerByUserName(args[0].ToString());
                if (currInfoPlayer.userName != "")
                {
                    try
                    {
                        currInfoPlayer.PlayerDetectorInfo = "";
                    }
                    catch
                    {

                    }
                }
            }
        }


        #region DirectoryFolders
        public void createdirectory(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            if (args.Count == 2)
            {
                try
                {
                    string Path = args[0].ToString();
                    string DirectoryName = args[1].ToString();
                    string TotalPath = @"" + args[0].ToString()+ "\\" + args[1].ToString();

                    if (!Directory.Exists(TotalPath))
                    {
                        Directory.CreateDirectory(TotalPath);
                    }
                    else
                    {
                        throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' A directory named: " + args[0].ToString() + " already exist!");
                    }
                }
                catch
                {
                    throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' Cannot create the directory, Check the parameters!");
                }
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' incorrect number of parameters!");
            }
        }
        public void deletedirectory(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            if (args.Count == 2)
            {
                try
                {
                    string Path = args[0].ToString();
                    string DirectoryName = args[1].ToString();
                    string TotalPath = @"" + args[0].ToString() + "\\" + args[1].ToString();

                    if (Directory.Exists(TotalPath))
                        Directory.Delete(TotalPath);
                    else
                        throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' A directory named: " + args[0].ToString() + " doesnt exist!");
                }
                catch
                {
                    throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' Cannot delete the directory, Check the parameters!");
                }
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' incorrect number of parameters!");
            }

        }
        public void directoryexist(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            if (args.Count == 2)
            {
                try
                {
                    string Path = args[0].ToString();
                    string DirectoryName = args[1].ToString();
                    string TotalPath = @"" + args[0].ToString() + "\\" + args[1].ToString();

                    val.typVal = GLScript.typVal.num;
                    if (Directory.Exists(TotalPath))
                        val.fval = 1;
                    else
                        val.fval = 0;
                }
                catch
                {
                    throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' Cannot delete the directory, Check the parameters!");
                }
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' incorrect number of parameters!");
            }
        }
        #endregion

        public void carswitches(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            int TotalValueCarSwitch = 0;
            int Signal = int.Parse(args[0].ToString());
            int Flash = int.Parse(args[1].ToString());
            int Headlight = int.Parse(args[2].ToString());
            int Horn = int.Parse(args[3].ToString());
            int Siren = int.Parse(args[4].ToString());
            //Count number of parameters of function
            if ((args.Count < 5)||(args.Count > 5))
            {
                throw new GLScript.GLApp.GLScriptException("Command '" + ident + "' incorrect number of parameters, example: carswitches(0,0,0,0,0); ");
            }
            else
            {
                switch (Signal)
                {
                    case 0: //Off
                        TotalValueCarSwitch = TotalValueCarSwitch + 0 + 1;
                        break;
                    case 1://Left Signal
                        TotalValueCarSwitch = TotalValueCarSwitch + 256 + 1;
                        break;
                    case 2://Right Signal
                        TotalValueCarSwitch = TotalValueCarSwitch + 512 + 1;
                        break;
                    case 3://Hazard
                        TotalValueCarSwitch = TotalValueCarSwitch + 768 + 1;
                        break;
                    default:
                        throw new GLScript.GLApp.GLScriptException("Error on '" + ident + "': 'SIGNAL' Parameter incorrect, must be 0 - 3");
                }

                switch (Flash)
                {
                    case 0: //Off
                        TotalValueCarSwitch = TotalValueCarSwitch + 0 + 2;
                        break;
                    case 1://On
                        TotalValueCarSwitch = TotalValueCarSwitch + 1024 + 2;
                        break;
                    default:
                        throw new GLScript.GLApp.GLScriptException("Error on '" + ident + "': 'FLASH' Parameter incorrect, must be 0 or 1");
                }

                switch (Headlight)
                {
                    case 0: //Off
                        TotalValueCarSwitch = TotalValueCarSwitch + 0 + 4;
                        break;
                    case 1://On
                        TotalValueCarSwitch = TotalValueCarSwitch + 2048 + 4;
                        break;
                    default:
                        throw new GLScript.GLApp.GLScriptException("Error on '" + ident + "': 'HEADLIGHT' Parameter incorrect, must be 0 or 1");
                }

                switch (Horn)
                {
                    case 0: //Off
                        TotalValueCarSwitch = TotalValueCarSwitch + 0 + 8;
                        break;
                    case 1://Horn Type 1
                        TotalValueCarSwitch = TotalValueCarSwitch + 65536 + 8;
                        break;
                    case 2://Horn Type 2
                        TotalValueCarSwitch = TotalValueCarSwitch + 131072 + 8;
                        break;
                    case 3://Horn Type 3
                        TotalValueCarSwitch = TotalValueCarSwitch + 196608 + 8;
                        break;
                    case 4://Horn Type 4
                        TotalValueCarSwitch = TotalValueCarSwitch + 262144 + 8;
                        break;
                    case 5://Horn Type 5
                        TotalValueCarSwitch = TotalValueCarSwitch + 327680 + 8;
                        break;
                    default:
                        throw new GLScript.GLApp.GLScriptException("Error on '" + ident + "': 'SIGNAL' Parameter incorrect, must be 0 - 5");
                }
                switch (Siren)
                {
                    case 0: //Off
                        TotalValueCarSwitch = TotalValueCarSwitch + 0 + 16;
                        break;
                    case 1://Fast Siren
                        TotalValueCarSwitch = TotalValueCarSwitch + 1048576 + 16;
                        break;
                    case 2://Slow Siren
                        TotalValueCarSwitch = TotalValueCarSwitch + 2097152 + 16;
                        break;
                    default:
                        throw new GLScript.GLApp.GLScriptException("Error on '" + ident + "': 'SIREN' Parameter incorrect, must be 0 - 2");
                }
                byte[] lcs = myEncoder.LCS(int.Parse(TotalValueCarSwitch.ToString()));
                insimConnection.Send(lcs, lcs.Length);
            }
        }

        #region Create/Read/edit/Delete/Exist textfiles
        public void GetListOfFiles(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            string Folder = args[0].ToString();

            string FileName = "";
            string FileCreated = "";
            string FileModified = "";
            string FileCreationDate = "";
            string FileModificationDate = "";

            long FileSize = 0;


            if (Directory.Exists(Folder)) //Check folder existing
            {
                ArrayList ListOfFiles = new ArrayList();
                DirectoryInfo dir = new DirectoryInfo(Folder);
                FileInfo[] files = dir.GetFiles();

                ListOfFiles.Add("Retreive ListOfFiles of:  " + Folder + ",Nothing" + ",Nothing" + ",Nothing"); //First line of array
                //Put every file in current folder in a Array  
                foreach (FileInfo FileInFolder in files)
                {
                    FileName = FileInFolder.Name;
                    FileCreationDate = File.GetCreationTime(Folder + "\\" + FileName).ToString();
                    FileModificationDate = File.GetLastWriteTime(Folder + "\\" + FileName).ToString();

                    //Remove Time
                    int IndexspaceCreationDate = FileCreationDate.IndexOf(" ");
                    int IndexspaceModifyDate = FileModificationDate.IndexOf(" ");

                    FileCreated = FileCreationDate.Substring(0, IndexspaceCreationDate);
                    FileModified = FileModificationDate.Substring(0, IndexspaceModifyDate);
                    FileSize = FileInFolder.Length;

                    ListOfFiles.Add(FileName + "," + FileCreated + "," + FileModified + "," + FileSize);
                }

                //Create LapperVars from fileinfo 
                //Get Number of Files in folder
                string NameofFile = "";
                string DateofModification = "";
                string DateofCreation = "";
                string SizeofFile = "";
                string NumberofFiles = (ListOfFiles.Count - 1).ToString(); //Ignore first line of array

                //Set variables for GLScript
                val.typVal = GLScript.typVal.setOfVar;
                val.setVars = new GLScript.SetOfVars();

                //Set Number of Layout Var
                val.setVars.Set(utils.quote("NumberOfFiles"), new GLScript.unionVal(0, "\"" + NumberofFiles + "\"", GLScript.typVal.str));

                for (int i = 1; i < ListOfFiles.Count; i++)
                {
                    string fileinfo = ListOfFiles[i] as string;
                    string[] SplittedLayoutInfo = fileinfo.Split(',');

                    NameofFile = SplittedLayoutInfo[0];
                    DateofModification = SplittedLayoutInfo[1];
                    DateofCreation = SplittedLayoutInfo[2];
                    SizeofFile = SplittedLayoutInfo[3];

                    val.setVars.Set(i.ToString() + "," + utils.quote("FileNumber"), new GLScript.unionVal(0, "\"" + i + "\"", GLScript.typVal.str));
                    val.setVars.Set(i.ToString() + "," + utils.quote("FileName"), new GLScript.unionVal(0, "\"" + NameofFile + "\"", GLScript.typVal.str));
                    val.setVars.Set(i.ToString() + "," + utils.quote("FileCreated"), new GLScript.unionVal(0, "\"" + DateofModification + "\"", GLScript.typVal.str));
                    val.setVars.Set(i.ToString() + "," + utils.quote("FileModified"), new GLScript.unionVal(0, "\"" + DateofCreation + "\"", GLScript.typVal.str));
                    val.setVars.Set(i.ToString() + "," + utils.quote("FileSize"), new GLScript.unionVal(0, "\"" + SizeofFile + "\"", GLScript.typVal.str));
                }
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("ERROR on function: '" + ident + "', Folder does not exist!");
            }
        }
        public void fileexist(GLScript.unionVal val, ArrayList args)
        {
            //IF (FileExist($folder,$FileName,$Extension) == 1) THEN
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            if (args.Count >= 3)
            {
                if ((args[0].ToString() != "") && (args[1].ToString() != "") && (args[2].ToString() != ""))
                {
                    string Folder = args[0].ToString();
                    string FileName = args[1].ToString();
                    string Extension = args[2].ToString(); //.txt for example
                    string Path = @"" + Folder + "\\" + FileName + "" + Extension;

                    FileInfo File = new FileInfo(Path);
                    val.typVal = GLScript.typVal.num;

                    if (File.Exists)
                    {
                        val.fval = 1; //return 1
                    }
                    else
                    {
                        val.fval = 0; // return 0 
                    }
                }
                else
                {
                    throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', One of the parameters are empty");
                }

            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', Incorrect number of parameters");
            }

        }
        public void createfile(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            string FileName = args[0].ToString();
            string Folder = args[1].ToString();
            string FileExistTodo = args[2].ToString();

            if (((FileName != "") && (Folder != "") && (FileExistTodo != "")) && (args.Count == 3))
                {
                        Thread CreateFileThread = new Thread(() => CreateFile(val, currInfoPlayer, ident, FileName, Folder, FileExistTodo));
                        CreateFileThread.Start();
                }
                else
                    throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', incorrect number of parameters or parameters are wrong");

            
        }
        public void readfile(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            string FileName = args[0].ToString();
            string Folder = args[1].ToString();
            string Extension = args[2].ToString();
            string FileCreationDate = "";
            string FileModificationDate = "";
            string FileSize = "";
            string Path = "";

            if (((FileName != "") && (Folder != "") && (Extension != "")) && (args.Count >= 3))
            {
                Path = @"" + Folder + "\\" + FileName + "" + Extension;

                ArrayList LinesofFile = new ArrayList();

                //Get lines of file.
                try
                {
                    int counter = 0;
                    string Line;


                    FileInfo File = new FileInfo(Path);
                    if (File.Exists)
                    {
                        //get info from file like Creationtime and modificationtime
                        FileCreationDate = File.CreationTime.ToString();
                        FileModificationDate = File.LastWriteTime.ToString();
                        FileSize = string.Format("{0}", File.Length);

                        System.IO.StreamReader readfile = new System.IO.StreamReader(Path);
                        //when line isnt empty
                        while ((Line = readfile.ReadLine()) != null)
                        {
                            //Add each line to array.
                            LinesofFile.Add(Line);
                            counter++;
                        }
                        //close file after reading it
                        readfile.Close();


                        //Set vars of each line from array
                        string Numberoflines = (LinesofFile.Count).ToString(); //Ignore first line of array

                        //Set variables for GLScript
                        val.typVal = GLScript.typVal.setOfVar;
                        val.setVars = new GLScript.SetOfVars();

                        //Set Number of Layout Var
                        val.setVars.Set(utils.quote("NumberOfLines"), new GLScript.unionVal(0, "\"" + Numberoflines + "\"", GLScript.typVal.str));
                        val.setVars.Set(utils.quote("TimeOfModification"), new GLScript.unionVal(0, "\"" + FileModificationDate + "\"", GLScript.typVal.str));
                        val.setVars.Set(utils.quote("TimeOfCreation"), new GLScript.unionVal(0, "\"" + FileCreationDate + "\"", GLScript.typVal.str));
                        val.setVars.Set(utils.quote("FileSize"), new GLScript.unionVal(0, "\"" + FileSize + "\"", GLScript.typVal.str));

                        for (int i = 0; i < LinesofFile.Count; i++)
                        {
                            string GetLineFromArray = LinesofFile[i] as string;
                            val.setVars.Set(i.ToString() + "," + utils.quote("LineNumber"), new GLScript.unionVal(0, "\"" + i + "\"", GLScript.typVal.str));
                            val.setVars.Set(i.ToString() + "," + utils.quote("Line"), new GLScript.unionVal(0, "\"" + GetLineFromArray + "\"", GLScript.typVal.str));
                        }
                    }
                }
                catch
                {

                }
            }
            else
                throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', incorrect number of parameters or parameters are wrong");

        }

        public void deletefile(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            string FileName = args[0].ToString();
            string Folder = args[1].ToString();
            string CopyFolder = args[2].ToString();
            string Extension = args[3].ToString();

            if (((FileName != "") && (Folder != "") && (Extension != "")) && (args.Count >= 3))
            {
                Thread DeleteFileThread = new Thread(() => DeleteFile(val, currInfoPlayer, ident, FileName, Folder, CopyFolder, Extension));
                DeleteFileThread.Start();
            }
            else
                throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', incorrect number of parameters or parameters are wrong");
        }

        public void editfile(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            string FileName = args[0].ToString();
            string Folder = args[1].ToString();
            string Text = args[2].ToString();
            string LineToEdit = args[3].ToString();
            string Extension = args[4].ToString();

            if ((FileName != "") && (Folder != "") && (Extension != ""))
            {
                EditFile(val, currInfoPlayer, ident, FileName, Folder, Text, LineToEdit, Extension);
            }
            else
                throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', incorrect number of parameters or parameters are wrong");
        }
        #endregion

        #region Delete stored values
        public void deleteuserstoredvalue(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            try
            {
                string username = args[0].ToString();
                string userstoredvalue = args[1].ToString();

                if (((username != "") || (username != "-")) && ((userstoredvalue != "") || (userstoredvalue != "-")) || (args.Count == 2))
                {
                    testArgs(ident, "SS", args);
                    //                                 Username  userstoredvalue
                    storedSqlDbs.deletestoredvalueuser(username, userstoredvalue);
                }
                else
                {
                    throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', Incorrect number of parameters or parameters are wrong");
                }
            }
            catch
            {
                throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', ncorrect number of parameters or parameters are wrong");
            }
        }

        public void deletestoredvalue(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            try
            {

                string storedvalue = args[0].ToString();

                if ((storedvalue != "") && (args.Count == 1))
                {
                    testArgs(ident, "S", args);
                    //                             StoredValue
                    storedSqlDbs.deletestoredvalue(storedvalue);
                }
                else
                {
                    throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "' Incorrect number of parameters or parameters are wrong");
                }
            }
            catch
            {
                throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "' Incorrect number of parameters or parameters are wrong");
            }
        }
        #endregion

        #region delete drift/laptime records
        public void deletedriftrecords(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string track = currState.ShortTrackName;
            string ident = val.nameFunction;
            if ((args[0].ToString() != "") || (args[1].ToString() != "") || (args.Count == 2))
            {
                //                                  Username            Car            track
                driftSqlDbs.deletetrackrecords(args[0].ToString(), args[1].ToString(), track);
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "' Incorrect number of parameters or parameters are wrong");
            }
        }

        public void deletelaptimerecords(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string track = currState.ShortTrackName;
            string ident = val.nameFunction;
            if ((args[0].ToString() != "") || (args[1].ToString() != "") || (args.Count == 2))
            {
                //                                  Username            Car            track
                gripSqlDbs.deletetrackrecords(args[0].ToString(), args[1].ToString(), track);
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "' Incorrect number of parameters or parameters are wrong");
            }
        }
        #endregion
        #region Streetcode Yisc[NL]
        public void registerstreetaction(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            // string idTask = "";
            // idTask = args[0].ToString();
            testArgs(ident, "SSSSS", args);
            //                      taskID            TrackName          Desc                CmdEnter              CmdLeave
            listOfStreetEvent.Add(args[0].ToString(), args[1].ToString(), args[2].ToString(), args[3].ToString(), args[4].ToString());
        }
        public void removestreetaction(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "SS", args); // ident Task, track
            listOfZoneEvent.Remove(args[0].ToString(), args[1].ToString());
        }
        #endregion
       
        public void connectinfo(GLScript.unionVal val, ArrayList args)
        {
            byte[] nci = myEncoder.NCI();
            insimConnection.Send(nci, nci.Length);
        }

        public void getangle(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            bool FunctionError = false;
            double Player_one_X = 0;
            double Player_one_Y = 0;
            double Player_one_heading = 0;
            double Player_two_X = 0;
            double Player_two_Y = 0;

            double Radians = 0;
            double Degrees = 0;
            double AngleOfObject = 0;

            try
            {
                //===================================
                //Player/Object 1
                //===================================
                try //Detect Player
                {
                    infoPlayer Player_one;
                    Player_one = listOfPlayers.getPlayerByUserName(args[0].ToString());
                    if (Player_one.userName != "")
                    {
                        //get X-axis of player 1: args[0]
                        Player_one_X = Player_one.x;
                        Player_one_Y = Player_one.y;
                        Player_one_heading = Player_one.heading;
                    }
                }
                catch //Detect object
                {
                    string[] object_args_one = args[0].ToString().Split(':');
                    if ((object_args_one[0] == "") || (object_args_one[1] == ""))//X-axis
                    {
                        FunctionError = true;
                    }
                    else
                    {
                        Player_one_X = int.Parse(object_args_one[0].ToString());
                        Player_one_Y = int.Parse(object_args_one[1].ToString());
                    }
                }
                //===================================
                //Player/Object 2
                //===================================
                try //Detect Player
                {
                    infoPlayer Player_two;
                    Player_two = listOfPlayers.getPlayerByUserName(args[1].ToString());
                    if (Player_two.userName != "")
                    {
                        //get X-axis of player 2: args[1]
                        Player_two_X = Player_two.x;
                        Player_two_Y = Player_two.y;
                    }
                }
                catch //Detect object
                {
                    string[] object_args_two = args[1].ToString().Split(':');
                    if ((object_args_two[0] == "") || (object_args_two[1] == ""))//X-axis
                    {
                        FunctionError = true;
                    }
                    else
                    {
                        Player_two_X = int.Parse(object_args_two[0].ToString());
                        Player_two_Y = int.Parse(object_args_two[1].ToString());
                    }
                }

                /// Calculating the angle between 2 objects or players
                ///
                ///

                //calculate distance X and Y 
                int DistX = (int)Player_two_X - (int)Player_one_X;
                int DistY = (int)Player_two_Y - (int)Player_one_Y;

                Radians = Math.Atan2(DistY, DistX);
                //Calculate Degrees + 90(heading car = +90 Y-Axis)
                Degrees = (Radians * 180 / Math.PI) + 90;

                //Calculate angleofobject (Degrees - Heading of Player One + 180 degrees)
                AngleOfObject = ((Degrees - Player_one_heading) + 180);
                //Adjust AngleOfObject 
                if (AngleOfObject > 180)
                {
                    AngleOfObject -= 360;
                }

                if (AngleOfObject < -180)
                {
                    AngleOfObject += 360;
                }

                if (FunctionError == false)
                {
                    val.fval = (float)AngleOfObject;
                    val.typVal = GLScript.typVal.num;
                }
                else
                {
                    val.sval = "\"^1ERROR\"";
                    val.typVal = GLScript.typVal.str;
                }
            }
            catch
            {
                val.sval = "\"^1STRING ERROR\"";
                val.typVal = GLScript.typVal.str;
            }
        }

        public void trackuserdistance(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            bool FunctionError = false;
            double Player_one_X = 0;
            double Player_one_Y = 0;
            double Player_two_X = 0;
            double Player_two_Y = 0;
            try
            {
                //===================================
                //Player/Object 1
                //===================================
                try //Detect Player
                {
                    infoPlayer Player_one;
                    Player_one = listOfPlayers.getPlayerByUserName(args[0].ToString());
                    if (Player_one.userName != "")
                    {
                        //get X-axis of player 1: args[0]
                        Player_one_X = Player_one.x;
                        Player_one_Y = Player_one.y;
                    }
                }
                catch //Detect object
                {
                    string[] object_args_one = args[0].ToString().Split(':');
                    if ((object_args_one[0] == "") || (object_args_one[1] == ""))//X-axis
                    {
                        FunctionError = true;
                    }
                    else
                    {
                        Player_one_X = int.Parse(object_args_one[0].ToString());
                        Player_one_Y = int.Parse(object_args_one[1].ToString());
                    }
                }
                //===================================
                //Player/Object 2
                //===================================
                try //Detect Player
                {
                    infoPlayer Player_two;
                    Player_two = listOfPlayers.getPlayerByUserName(args[1].ToString());
                    if (Player_two.userName != "")
                    {
                        //get X-axis of player 2: args[1]
                        Player_two_X = Player_two.x;
                        Player_two_Y = Player_two.y;
                    }
                }
                catch //Detect object
                {
                    string[] object_args_two = args[1].ToString().Split(':');
                    if ((object_args_two[0] == "") || (object_args_two[1] == ""))//X-axis
                    {
                        FunctionError = true;
                    }
                    else
                    {
                        Player_two_X = int.Parse(object_args_two[0].ToString());
                        Player_two_Y = int.Parse(object_args_two[1].ToString());
                    }
                }
                //calculate X and Y 
                int DistX = (int)Player_one_X - (int)Player_two_X;
                int DistY = (int)Player_one_Y - (int)Player_two_Y;

                float DistanceBetweenPlayers = (float)Math.Sqrt((DistX * DistX) + (DistY * DistY));

                //calculate X and Y
                if (FunctionError == false)
                {
                    val.fval = DistanceBetweenPlayers;
                    val.typVal = GLScript.typVal.num;
                }
                else
                {
                    val.sval = "\"^1ERROR\"";
                    val.typVal = GLScript.typVal.str;
                }
            }
            catch
            {
                val.sval = "\"^1STRING ERROR\"";
                val.typVal = GLScript.typVal.str;
            }
        }


        #region Add/Remove objects & Object info
        
        public void getlistoflayouts(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            string Sort = args[1].ToString();
            string SortType = args[2].ToString();
            string Filter = args[0].ToString();
            string LayoutFolder = @"" + newCfg.varsLapper.LayoutFolder;

            string LayoutName = "";
            string DateModified = "";
            string DateCreated = "";
            try
            {
                //Checking layoutfolder
                if (LayoutFolder == "")
                {
                    SendMsgToConnection(currInfoPlayer.UCID, "^1ERROR: ^7Layoutfolder not defined",4);
                    SendMsgToConnection(currInfoPlayer.UCID, "^7Please contact the administrator",0);
                }

                if (!Directory.Exists(LayoutFolder))
                {
                    SendMsgToConnection(currInfoPlayer.UCID, "^1ERROR: ^7Layoutfolder not found!",4);
                    SendMsgToConnection(currInfoPlayer.UCID, "^7Please contact the administrator",0);
                }
                else
                {
                    //Layoutfolder found
                    string[] files = Directory.GetFiles(LayoutFolder, "*.lyt");

                    if ((Sort != "") && (SortType != "") && (args.Count == 3))
                    {
                        ArrayList LayoutList = GetListOfLayouts(Filter, Sort, SortType, currState.ShortTrackName, LayoutFolder);

                        string NumberofLayouts = (LayoutList.Count - 1).ToString(); //Ignore first line of array

                        //Set variables for GLScript
                        val.typVal = GLScript.typVal.setOfVar;
                        val.setVars = new GLScript.SetOfVars();

                        //Set Number of Layout Var
                        val.setVars.Set(utils.quote("NumberOfLayouts"), new GLScript.unionVal(0, "\"" + NumberofLayouts + "\"", GLScript.typVal.str));

                        for (int i = 1; i < LayoutList.Count; i++)
                        {
                            string Layoutinfo = LayoutList[i] as string;
                            string[] SplittedLayoutInfo = Layoutinfo.Split(',');

                            LayoutName = SplittedLayoutInfo[0];
                            DateModified = SplittedLayoutInfo[1];
                            DateCreated = SplittedLayoutInfo[2];

                            val.setVars.Set(i.ToString() + "," + utils.quote("LayoutNumber"), new GLScript.unionVal(0, "\"" + i + "\"", GLScript.typVal.str));
                            val.setVars.Set(i.ToString() + "," + utils.quote("LayoutName"), new GLScript.unionVal(0, "\"" + LayoutName + "\"", GLScript.typVal.str));
                            val.setVars.Set(i.ToString() + "," + utils.quote("DateCreated"), new GLScript.unionVal(0, "\"" + DateModified + "\"", GLScript.typVal.str));
                            val.setVars.Set(i.ToString() + "," + utils.quote("DateModified"), new GLScript.unionVal(0, "\"" + DateCreated + "\"", GLScript.typVal.str));
                        }
                    }
                    else
                    {
                        throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "' Incorrect number of parameters or parameters are wrong");
                    }
                }
            }
            catch
            {
                SendMsgToConnection(currInfoPlayer.UCID, "^1Error: ^7Cannot retreive info from layoutfolder.",4);
                SendMsgToConnection(currInfoPlayer.UCID, "^7Please contact the administrator",0);
            }
        }
        
        public void layoutinfo(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            PlayerLayoutInfoRequest = currInfoPlayer.UCID;

            byte[] axi = myEncoder.AXI();
            insimConnection.Send(axi, axi.Length);
        }

        public void getlayoutinfo(GLScript.unionVal val, ArrayList args)
        {
            // Request an AXI packet
            byte[] axi = myEncoder.AXI();
            insimConnection.Send(axi, axi.Length);
            val.typVal = GLScript.typVal.str;
            val.sval = utils.quote("");
        }

        public void getlytselection(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            byte[] ttc = myEncoder.TTC(250, byte.Parse(currInfoPlayer.UCID.ToString()));
            insimConnection.Send(ttc, ttc.Length);
        }

        public void setlytselection(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            string PMOFlag;

            if (args.Count == 2)
            {
                if (args[0].ToString() == "0" || args[0].ToString() == "4")
                {
                    PMOFlag = args[0].ToString();
                    if (args[1].ToString().Contains(","))
                    {
                        args = new ArrayList(args[1].ToString().Split(','));
                    }
                    else
                    {
                        string arg = args[1].ToString();
                        args = new ArrayList();
                        args.Add(arg);
                    }
                }
                else
                {
                    throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': PMOFlag must be either 0 or 4.");
                }
            }
            else
            {
                if (args.Count == 0) // if no argument then clear selection
                {
                    PMOFlag = "0";
                }
                else
                {
                    throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "' takes 2 or arguments or none.");
                }
            }

            //byte NumO, byte UCID, byte PMOAction, byte PMOFlags, short X, short Y, byte Z, byte Flags, byte Index, byte Heading
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            int Numberofobjects = args.Count; //count numbers of args
            byte ActionPMO = 6;
            byte PMOFlags = Convert.ToByte(PMOFlag);
            byte FunctionError = 0;
            int MaxSelectedObjects = 60;

            //arrays of objects (Max 30 objects)
            short[] Obj_X = new short[Numberofobjects];
            short[] Obj_Y = new short[Numberofobjects];
            byte[] Obj_Z = new byte[Numberofobjects];
            byte[] Obj_Flag = new byte[Numberofobjects];
            byte[] Obj_Index = new byte[Numberofobjects];
            byte[] Obj_Heading = new byte[Numberofobjects];

            if (Numberofobjects <= MaxSelectedObjects)
            {
                for (byte i = 0; i < Numberofobjects; i++)
                {
                    string[] obj = args[i].ToString().Split(':'); //Split string
                    if ((obj[0] != "") && (obj[1] != "") && (obj[2] != "") && (obj[3] != "") && (obj[4] != "") && (obj[5] != ""))
                    {
                        byte number_two;
                        bool byteresult_two = Byte.TryParse(obj[3], out number_two);
                        bool byteresult_three = Byte.TryParse(obj[4], out number_two);
                        if (!byteresult_two || !byteresult_three)
                        {
                            FunctionError = 2;
                        }
                        //Everything is fine , continue
                        if (FunctionError == 0)
                        {
                            try
                            {
                                //X Axis Get info from object
                                int RoundedValue_X;
                                int CommaValue_X;
                                if (obj[0].Contains("."))
                                {
                                    string[] Object_X_Value = obj[0].Split('.');
                                    RoundedValue_X = int.Parse(Object_X_Value[0].ToString());

                                    // if input is XX.X then make it XX.X0
                                    if (Object_X_Value[1].Length == 1)
                                    {
                                        CommaValue_X = int.Parse(Object_X_Value[1] + "0");
                                    }
                                    else
                                    {
                                        CommaValue_X = int.Parse(Object_X_Value[1].ToString());
                                    }
                                }
                                else
                                {
                                    RoundedValue_X = int.Parse(obj[0]);
                                    CommaValue_X = 00;
                                }

                                //Calculate total Value for the Axis
                                int Total_Rounded_X_Value = (RoundedValue_X * 16);
                                double Total_Comma_X_Value = Math.Round((16.00 / 100.00 * CommaValue_X));
                                int Total_X_Value = Total_Rounded_X_Value;
                                if (Total_Rounded_X_Value < 0)
                                {
                                    Total_X_Value = int.Parse((Total_Rounded_X_Value - Total_Comma_X_Value).ToString());
                                }
                                else
                                {
                                    Total_X_Value = int.Parse((Total_Rounded_X_Value + Total_Comma_X_Value).ToString());
                                }

                                //Y Axis Get info from object
                                int RoundedValue_Y;
                                int CommaValue_Y;
                                if (obj[1].Contains("."))
                                {
                                    string[] Object_Y_Value = obj[1].Split('.');
                                    RoundedValue_Y = int.Parse(Object_Y_Value[0].ToString());

                                    // if input is XX.X then make it XX.X0
                                    if (Object_Y_Value[1].Length == 1)
                                    {
                                        CommaValue_Y = int.Parse(Object_Y_Value[1] + "0");
                                    }
                                    else
                                    {
                                        CommaValue_Y = int.Parse(Object_Y_Value[1].ToString());
                                    }
                                }
                                else
                                {
                                    RoundedValue_Y = int.Parse(obj[1]);
                                    CommaValue_Y = 00;
                                }

                                //Calculate total Value for the Axis
                                int Total_Rounded_Y_Value = (RoundedValue_Y * 16);
                                double Total_Comma_Y_Value = Math.Round((16.00 / 100.00 * CommaValue_Y));
                                int Total_Y_Value = Total_Rounded_Y_Value;
                                if (Total_Rounded_Y_Value < 0)
                                {
                                    Total_Y_Value = int.Parse((Total_Rounded_Y_Value - Total_Comma_Y_Value).ToString());
                                }
                                else
                                {
                                    Total_Y_Value = int.Parse((Total_Rounded_Y_Value + Total_Comma_Y_Value).ToString());
                                }

                                //Z Axis Get info from object
                                int RoundedValue_Z;
                                int CommaValue_Z;
                                if (obj[2].Contains("."))
                                {
                                    string[] Object_Z_Value = obj[2].Split('.');
                                    RoundedValue_Z = int.Parse(Object_Z_Value[0].ToString());

                                    // if input is XX.X then make it XX.X0
                                    if (Object_Z_Value[1].Length == 1)
                                    {
                                        CommaValue_Z = int.Parse(Object_Z_Value[1] + "0");
                                    }
                                    else
                                    {
                                        CommaValue_Z = int.Parse(Object_Z_Value[1].ToString());
                                    }
                                }
                                else
                                {
                                    RoundedValue_Z = int.Parse(obj[2]);
                                    CommaValue_Z = 00;
                                }

                                //Calculate total Value for the Axis
                                int Total_Rounded_Z_Value = (RoundedValue_Z * 4);
                                double Total_Comma_Z_Value = Math.Round((4.00 / 100.00 * CommaValue_Z));
                                int Total_Z_Value = Int16.Parse((Total_Rounded_Z_Value + Total_Comma_Z_Value).ToString());

                                //Calculate Heading
                                int ObjHeading = ((int.Parse(obj[5].ToString()) + 180) * 256 / 360);


                                Obj_X[i] = short.Parse(Total_X_Value.ToString()); //short X
                                Obj_Y[i] = short.Parse(Total_Y_Value.ToString()); //short Y
                                Obj_Z[i] = byte.Parse(Total_Z_Value.ToString()); //Byte Z
                                Obj_Flag[i] = byte.Parse(obj[3].ToString()); //byte flag
                                Obj_Index[i] = byte.Parse(obj[4].ToString()); //byte Index
                                Obj_Heading[i] = byte.Parse(ObjHeading.ToString()); //byte Heading
                                                                                    //Console.WriteLine("Number of added object: [" + i + "] X:" + Obj_X[i] + " Y:" + Obj_Y[i] + " Z:" + Obj_Z[i] + " Flag:" + Obj_Flag[i] + " Index:" + Obj_Index[i] + " Heading:" + Obj_Heading[i]);
                            }
                            catch
                            {
                                throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': Object:[" + i + "] incorrect Floating Values for object: X = 000.00 and Y = 000.00 and Z = 00.00");
                            }
                        }
                    }
                    else
                    {
                        FunctionError = 3;
                        //Console.WriteLine("Function '" + ident + "' Object:[" + i + "] incorrect number of parameters");
                        throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': Object:[" + i + "] incorrect number of parameters");
                    }
                }
                //Everything is oke
                if (FunctionError == 0)
                {
                    PlayerOfObject = currInfoPlayer.userName;
                    byte[] axm = myEncoder.AXM(byte.Parse(Numberofobjects.ToString()), //byte NumO
                                                byte.Parse(currInfoPlayer.UCID.ToString()), //byte UCID, //UCID default 0
                                                byte.Parse(ActionPMO.ToString()), //byte PMOAction
                                                byte.Parse(PMOFlags.ToString()), //byte PMOFlags
                                                Obj_X, //short X
                                                Obj_Y, //short Y
                                                Obj_Z, //short Z
                                                Obj_Flag, //Flag of object
                                                Obj_Index, //byte Index
                                                Obj_Heading); //byte Heading
                    insimConnection.Send(axm, axm.Length);
                }
                //To many object in 1 array Error
                if (FunctionError == 1)
                {
                    throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': Contains to many objects (Max 30)");
                }
                //Values higher that 255 or negative
                if (FunctionError == 2)
                {
                    throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': One of the values '4'or'5'or'6' are higher than 255 or are negative");
                }
                //Invalid objects
                if (FunctionError == 3)
                {
                    throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': One of the objects is not valid!");
                }
            }
        }

        public void addobject(GLScript.unionVal val, ArrayList args)
        {
            // If input is only one var but contains "," then split the string
            if (args.Count == 1 & args[0].ToString().Contains(","))
            {
                args = new ArrayList(args[0].ToString().Split(','));
            }

            //byte NumO, byte UCID, byte PMOAction, byte PMOFlags, short X, short Y, byte Z, byte Flags, byte Index, byte Heading
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            int Numberofobjects = args.Count; //count numbers of args
            byte ActionPMO = 1;
            byte PMOFlags = 1;
            byte FunctionError = 0;
            int MaxSelectedObjects = 60;

            //arrays of objects (Max 60 objects) //Updated from 30 to 60 objects 06-11-2021
            short[] Obj_X = new short[Numberofobjects];
            short[] Obj_Y = new short[Numberofobjects];
            byte[] Obj_Z = new byte[Numberofobjects];
            byte[] Obj_Flag = new byte[Numberofobjects];
            byte[] Obj_Index = new byte[Numberofobjects];
            byte[] Obj_Heading = new byte[Numberofobjects];

            if (Numberofobjects <= MaxSelectedObjects) //Updated from 30 to 60 objects 06-11-2021
            {
                for (byte i = 0; i < Numberofobjects; i++)
                {
                    string[] obj = args[i].ToString().Split(':'); //Split string
                    if ((obj[0] != "") && (obj[1] != "") && (obj[2] != "") && (obj[3] != "") && (obj[4] != "") && (obj[5] != ""))
                    {
                        byte number_two;
                        bool byteresult_two = Byte.TryParse(obj[3], out number_two);
                        bool byteresult_three = Byte.TryParse(obj[4], out number_two);
                        if (!byteresult_two || !byteresult_three)
                        {
                            FunctionError = 2;
                        }
                        //Everything is fine , continue
                        if (FunctionError == 0)
                        {
                            try
                            {
                                //X Axis Get info from object
                                int RoundedValue_X;
                                int CommaValue_X;
                                if (obj[0].Contains("."))
                                {
                                    string[] Object_X_Value = obj[0].Split('.');
                                    RoundedValue_X = int.Parse(Object_X_Value[0].ToString());

                                    // if input is XX.X then make it XX.X0
                                    if (Object_X_Value[1].Length == 1)
                                    {
                                        CommaValue_X = int.Parse(Object_X_Value[1] + "0");
                                    }
                                    else
                                    {
                                        CommaValue_X = int.Parse(Object_X_Value[1].ToString());
                                    }
                                }
                                else
                                {
                                    RoundedValue_X = int.Parse(obj[0]);
                                    CommaValue_X = 00;
                                }

                                //Calculate total Value for the Axis
                                int Total_Rounded_X_Value = (RoundedValue_X * 16);
                                double Total_Comma_X_Value = Math.Round((16.00 / 100.00 * CommaValue_X));
                                int Total_X_Value = Total_Rounded_X_Value;
                                if (Total_Rounded_X_Value < 0)
                                {
                                    Total_X_Value = int.Parse((Total_Rounded_X_Value - Total_Comma_X_Value).ToString());
                                }
                                else
                                {
                                    Total_X_Value = int.Parse((Total_Rounded_X_Value + Total_Comma_X_Value).ToString());
                                }

                                //Y Axis Get info from object
                                int RoundedValue_Y;
                                int CommaValue_Y;
                                if (obj[1].Contains("."))
                                {
                                    string[] Object_Y_Value = obj[1].Split('.');
                                    RoundedValue_Y = int.Parse(Object_Y_Value[0].ToString());

                                    // if input is XX.X then make it XX.X0
                                    if (Object_Y_Value[1].Length == 1)
                                    {
                                        CommaValue_Y = int.Parse(Object_Y_Value[1] + "0");
                                    }
                                    else
                                    {
                                        CommaValue_Y = int.Parse(Object_Y_Value[1].ToString());
                                    }
                                }
                                else
                                {
                                    RoundedValue_Y = int.Parse(obj[1]);
                                    CommaValue_Y = 00;
                                }

                                //Calculate total Value for the Axis
                                int Total_Rounded_Y_Value = (RoundedValue_Y * 16);
                                double Total_Comma_Y_Value = Math.Round((16.00 / 100.00 * CommaValue_Y));
                                int Total_Y_Value = Total_Rounded_Y_Value;
                                if (Total_Rounded_Y_Value < 0)
                                {
                                    Total_Y_Value = int.Parse((Total_Rounded_Y_Value - Total_Comma_Y_Value).ToString());
                                }
                                else
                                {
                                    Total_Y_Value = int.Parse((Total_Rounded_Y_Value + Total_Comma_Y_Value).ToString());
                                }

                                //Z Axis Get info from object
                                int RoundedValue_Z;
                                int CommaValue_Z;
                                if (obj[2].Contains("."))
                                {
                                    string[] Object_Z_Value = obj[2].Split('.');
                                    RoundedValue_Z = int.Parse(Object_Z_Value[0].ToString());

                                    // if input is XX.X then make it XX.X0
                                    if (Object_Z_Value[1].Length == 1)
                                    {
                                        CommaValue_Z = int.Parse(Object_Z_Value[1] + "0");
                                    }
                                    else
                                    {
                                        CommaValue_Z = int.Parse(Object_Z_Value[1].ToString());
                                    }
                                }
                                else
                                {
                                    RoundedValue_Z = int.Parse(obj[2]);
                                    CommaValue_Z = 00;
                                }

                                //Calculate total Value for the Axis
                                int Total_Rounded_Z_Value = (RoundedValue_Z * 4);
                                double Total_Comma_Z_Value = Math.Round((4.00 / 100.00 * CommaValue_Z));
                                int Total_Z_Value = Int16.Parse((Total_Rounded_Z_Value + Total_Comma_Z_Value).ToString());

                                //Calculate Heading
                                int ObjHeading = ((int.Parse(obj[5].ToString()) + 180) * 256 / 360);


                                Obj_X[i] = short.Parse(Total_X_Value.ToString()); //short X
                                Obj_Y[i] = short.Parse(Total_Y_Value.ToString()); //short Y
                                Obj_Z[i] = byte.Parse(Total_Z_Value.ToString()); //Byte Z
                                Obj_Flag[i] = byte.Parse(obj[3].ToString()); //byte flag
                                Obj_Index[i] = byte.Parse(obj[4].ToString()); //byte Index
                                Obj_Heading[i] = byte.Parse(ObjHeading.ToString()); //byte Heading
                                                                                //Console.WriteLine("Number of added object: [" + i + "] X:" + Obj_X[i] + " Y:" + Obj_Y[i] + " Z:" + Obj_Z[i] + " Flag:" + Obj_Flag[i] + " Index:" + Obj_Index[i] + " Heading:" + Obj_Heading[i]);
                            }
                            catch
                            {
                                throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': Object:[" + i + "] incorrect Floating Values for object: X = 000.00 and Y = 000.00 and Z = 00.00");
                            }
                        }
                    }
                    else
                    {
                        FunctionError = 3;
                        //Console.WriteLine("Function '" + ident + "' Object:[" + i + "] incorrect number of parameters");
                        throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': Object:[" + i + "] incorrect number of parameters");
                    }
                }
                //Everything is oke
                if (FunctionError == 0)
                {
                    PlayerOfObject = currInfoPlayer.userName;
                    byte[] axm = myEncoder.AXM(byte.Parse(Numberofobjects.ToString()), //byte NumO
                                                0, //UCID default 0
                                                byte.Parse(ActionPMO.ToString()), //byte PMOAction
                                                byte.Parse(PMOFlags.ToString()), //byte PMOFlags
                                                Obj_X, //short X
                                                Obj_Y, //short Y
                                                Obj_Z, //short Z
                                                Obj_Flag, //Flag of object
                                                Obj_Index, //byte Index
                                                Obj_Heading); //byte Heading
                    insimConnection.Send(axm, axm.Length);
                }
                //To many object in 1 array Error
                if (FunctionError == 1)
                {
                    throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': Contains to many objects (Max 30)");
                }
                //Values higher that 255 or negative
                if (FunctionError == 2)
                {
                    throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': One of the values '4'or'5'or'6' are higher than 255 or are negative");
                }
                //Invalid objects
                if (FunctionError == 3)
                {
                    throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': One of the objects is not valid!");
                }
            }
        }
        public void removeobject(GLScript.unionVal val, ArrayList args)
        {
            // If input is only one var but contains "," then split the string
            if (args.Count == 1 & args[0].ToString().Contains(","))
            {
                args = new ArrayList(args[0].ToString().Split(','));
            }

            //byte NumO, byte UCID, byte PMOAction, byte PMOFlags, short X, short Y, byte Z, byte Flags, byte Index, byte Heading
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            int Numberofobjects = args.Count; //count numbers of args
            byte ActionPMO = 2;
            byte PMOFlags = 1;
            byte FunctionError = 0;
            int MaxSelectedObjects = 60;

            //arrays of objects (Max 60 objects)
            short[] Obj_X = new short[Numberofobjects];
            short[] Obj_Y = new short[Numberofobjects];
            byte[] Obj_Z = new byte[Numberofobjects];
            byte[] Obj_Flag = new byte[Numberofobjects];
            byte[] Obj_Index = new byte[Numberofobjects];
            byte[] Obj_Heading = new byte[Numberofobjects];

            if (Numberofobjects <= MaxSelectedObjects)
            {
                for (byte i = 0; i < Numberofobjects; i++)
                {
                    string[] obj = args[i].ToString().Split(':'); //Split string
                    if ((obj[0] != "") && (obj[1] != "") && (obj[2] != "") && (obj[3] != "") && (obj[4] != "") && (obj[5] != ""))
                    {
                        //Check for value higher than 255 or negative
                        byte number_two;
                        bool byteresult_two = Byte.TryParse(obj[3], out number_two);
                        bool byteresult_three = Byte.TryParse(obj[4], out number_two);
                        if (!byteresult_two || !byteresult_three)
                        {
                            FunctionError = 2;
                        }
                        //Everything is fine , continue
                        if (FunctionError == 0)
                        {
                            try
                            {
                                //X Axis Get info from object
                                int RoundedValue_X;
                                int CommaValue_X;
                                if (obj[0].Contains("."))
                                {
                                    string[] Object_X_Value = obj[0].Split('.');
                                    RoundedValue_X = int.Parse(Object_X_Value[0].ToString());

                                    // if input is XX.X then make it XX.X0
                                    if (Object_X_Value[1].Length == 1)
                                    {
                                        CommaValue_X = int.Parse(Object_X_Value[1] + "0");
                                    }
                                    else
                                    {
                                        CommaValue_X = int.Parse(Object_X_Value[1].ToString());
                                    }
                                }
                                else
                                {
                                    RoundedValue_X = int.Parse(obj[0]);
                                    CommaValue_X = 00;
                                }

                                //Calculate total Value for the Axis
                                int Total_Rounded_X_Value = (RoundedValue_X * 16);
                                double Total_Comma_X_Value = Math.Round((16.00 / 100.00 * CommaValue_X));
                                int Total_X_Value = Total_Rounded_X_Value;
                                if (Total_Rounded_X_Value < 0)
                                {
                                    Total_X_Value = int.Parse((Total_Rounded_X_Value - Total_Comma_X_Value).ToString());
                                }
                                else
                                {
                                    Total_X_Value = int.Parse((Total_Rounded_X_Value + Total_Comma_X_Value).ToString());
                                }

                                //Y Axis Get info from object
                                int RoundedValue_Y;
                                int CommaValue_Y;
                                if (obj[1].Contains("."))
                                {
                                    string[] Object_Y_Value = obj[1].Split('.');
                                    RoundedValue_Y = int.Parse(Object_Y_Value[0].ToString());

                                    // if input is XX.X then make it XX.X0
                                    if (Object_Y_Value[1].Length == 1)
                                    {
                                        CommaValue_Y = int.Parse(Object_Y_Value[1] + "0");
                                    }
                                    else
                                    {
                                        CommaValue_Y = int.Parse(Object_Y_Value[1].ToString());
                                    }
                                }
                                else
                                {
                                    RoundedValue_Y = int.Parse(obj[1]);
                                    CommaValue_Y = 00;
                                }

                                //Calculate total Value for the Axis
                                int Total_Rounded_Y_Value = (RoundedValue_Y * 16);
                                double Total_Comma_Y_Value = Math.Round((16.00 / 100.00 * CommaValue_Y));
                                int Total_Y_Value = Total_Rounded_Y_Value;
                                if (Total_Rounded_Y_Value < 0)
                                {
                                    Total_Y_Value = int.Parse((Total_Rounded_Y_Value - Total_Comma_Y_Value).ToString());
                                }
                                else
                                {
                                    Total_Y_Value = int.Parse((Total_Rounded_Y_Value + Total_Comma_Y_Value).ToString());
                                }

                                //Z Axis Get info from object
                                int RoundedValue_Z;
                                int CommaValue_Z;
                                if (obj[2].Contains("."))
                                {
                                    string[] Object_Z_Value = obj[2].Split('.');
                                    RoundedValue_Z = int.Parse(Object_Z_Value[0].ToString());

                                    // if input is XX.X then make it XX.X0
                                    if (Object_Z_Value[1].Length == 1)
                                    {
                                        CommaValue_Z = int.Parse(Object_Z_Value[1] + "0");
                                    }
                                    else
                                    {
                                        CommaValue_Z = int.Parse(Object_Z_Value[1].ToString());
                                    }
                                }
                                else
                                {
                                    RoundedValue_Z = int.Parse(obj[2]);
                                    CommaValue_Z = 00;
                                }

                                //Calculate total Value for the Axis
                                int Total_Rounded_Z_Value = (RoundedValue_Z * 4);
                                double Total_Comma_Z_Value = Math.Round((4.00 / 100.00 * CommaValue_Z));
                                int Total_Z_Value = Int16.Parse((Total_Rounded_Z_Value + Total_Comma_Z_Value).ToString());

                                //Calculate Heading
                                int ObjHeading = ((int.Parse(obj[5].ToString()) + 180) * 256 / 360);

                                //Convertion
                                Obj_X[i] = short.Parse(Total_X_Value.ToString()); //short X
                                Obj_Y[i] = short.Parse(Total_Y_Value.ToString()); //short Y
                                Obj_Z[i] = byte.Parse(Total_Z_Value.ToString()); //Byte Z
                                Obj_Flag[i] = byte.Parse(obj[3].ToString()); //byte flag
                                Obj_Index[i] = byte.Parse(obj[4].ToString()); //byte Index
                                Obj_Heading[i] = byte.Parse(ObjHeading.ToString()); //byte Heading
                                                                                //Console.WriteLine("Number of added object: [" + i + "] X:" + Obj_X[i] + " Y:" + Obj_Y[i] + " Z:" + Obj_Z[i] + " Flag:" + Obj_Flag[i] + " Index:" + Obj_Index[i] + " Heading:" + Obj_Heading[i]);
                            }
                            catch
                            {
                                throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': Object:[" + i + "] incorrect Floating Values for object: X = 000.00 and Y = 000.00 and Z = 00.00");
                            }
                    }
                    }
                    else
                    {
                        FunctionError = 3;
                        //Console.WriteLine("Function '" + ident + "' Object:[" + i + "] incorrect number of parameters");
                        throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "' Object: [" + i + "] incorrect number of parameters");
                    }
                }
                if (FunctionError == 0)
                {
                    PlayerOfObject = currInfoPlayer.userName;
                    byte[] axm = myEncoder.AXM(byte.Parse(Numberofobjects.ToString()), //byte NumO
                                                0, //UCID default
                                                byte.Parse(ActionPMO.ToString()), //byte PMOAction
                                                byte.Parse(PMOFlags.ToString()), //byte PMOFlags
                                                Obj_X, //short X
                                                Obj_Y, //short Y
                                                Obj_Z, //short Z
                                                Obj_Flag, //Flag of object
                                                Obj_Index, //byte Index
                                                Obj_Heading); //byte Heading
                    insimConnection.Send(axm, axm.Length);
                }
                //To many object in 1 array Error
                if (FunctionError == 1)
                {
                    throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': Contains to many objects (Max 30)");
                }
                //Values higher that 255 or negative
                if (FunctionError == 2)
                {
                    throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': One of the values 4'or'5'or'6' are higher than 255 or are negative");
                }
                //Invalid objects
                if (FunctionError == 3)
                {
                    throw new GLScript.GLApp.GLScriptException("Error Function '" + ident + "': One of the objects is not valid!");
                }
            }
        }
        #endregion
        #region Set allowed cars
        public void setallowedcars(GLScript.unionVal val, ArrayList args)
        {
            int CarValue = 0;
            byte i = 0;
            string[] cars = args[0].ToString().Split('+');
            foreach (string car in cars)
            {
                #region carvalues 
                switch (car.ToUpper())
                {
                    case "UF1":
                        CarValue = CarValue + 256;
                        break;
                    case "XFG":
                        CarValue = CarValue + 1;
                        break;
                    case "XRG":
                        CarValue = CarValue + 2;
                        break;
                    case "XRT":
                        CarValue = CarValue + 4;
                        break;
                    case "RB4":
                        CarValue = CarValue + 8;
                        break;
                    case "FXO":
                        CarValue = CarValue + 16;
                        break;
                    case "FZ5":
                        CarValue = CarValue + 1024;
                        break;
                    case "RAC":
                        CarValue = CarValue + 512;
                        break;
                    case "LX4":
                        CarValue = CarValue + 32;
                        break;
                    case "LX6":
                        CarValue = CarValue + 64;
                        break;
                    case "FXR":
                        CarValue = CarValue + 32768;
                        break;
                    case "XRR":
                        CarValue = CarValue + 65536;
                        break;
                    case "FZR":
                        CarValue = CarValue + 131072;
                        break;
                    case "UFR":
                        CarValue = CarValue + 8192;
                        break;
                    case "XFR":
                        CarValue = CarValue + 4096;
                        break;
                    case "FOX":
                        CarValue = CarValue + 2048;
                        break;
                    case "FO8":
                        CarValue = CarValue + 16384;
                        break;
                    case "MRT":
                        CarValue = CarValue + 128;
                        break;
                    case "FBM":
                        CarValue = CarValue + 524288;
                        break;
                    case "BF1":
                        CarValue = CarValue + 262144;
                        break;
                }
                #endregion
                i++;
            }
            byte[] alc = myEncoder.ALC(int.Parse(CarValue.ToString()));
            insimConnection.Send(alc, alc.Length);
        }

        public void allowedplayercars(GLScript.unionVal val, ArrayList args)
        {
            /*
            infoPlayer currInfoPlayer;
            currInfoPlayer = listOfPlayers.getPlayerByUserName(args[0].ToString());
            int CarValue = 0;
            byte i = 0;
            string[] cars = args[1].ToString().Split('+');
            foreach (string car in cars)
            {
                #region carvalues 
                switch (car.ToUpper())
                {
                    case "UF1":
                        CarValue = CarValue + 256;
                        break;
                    case "XFG":
                        CarValue = CarValue + 1;
                        break;
                    case "XRG":
                        CarValue = CarValue + 2;
                        break;
                    case "XRT":
                        CarValue = CarValue + 4;
                        break;
                    case "RB4":
                        CarValue = CarValue + 8;
                        break;
                    case "FXO":
                        CarValue = CarValue + 16;
                        break;
                    case "FZ5":
                        CarValue = CarValue + 1024;
                        break;
                    case "RAC":
                        CarValue = CarValue + 512;
                        break;
                    case "LX4":
                        CarValue = CarValue + 32;
                        break;
                    case "LX6":
                        CarValue = CarValue + 64;
                        break;
                    case "FXR":
                        CarValue = CarValue + 32768;
                        break;
                    case "XRR":
                        CarValue = CarValue + 65536;
                        break;
                    case "FZR":
                        CarValue = CarValue + 131072;
                        break;
                    case "UFR":
                        CarValue = CarValue + 8192;
                        break;
                    case "XFR":
                        CarValue = CarValue + 4096;
                        break;
                    case "FOX":
                        CarValue = CarValue + 2048;
                        break;
                    case "FO8":
                        CarValue = CarValue + 16384;
                        break;
                    case "MRT":
                        CarValue = CarValue + 128;
                        break;
                    case "FBM":
                        CarValue = CarValue + 524288;
                        break;
                    case "BF1":
                        CarValue = CarValue + 262144;
                        break;
                }
                #endregion
                i++;
            }
            byte[] plc = myEncoder.PLC(byte.Parse(currInfoPlayer.UCID.ToString()), int.Parse(CarValue.ToString()));
            insimConnection.Send(plc, plc.Length);
            */
        }
        #endregion
        public void joinrequest(GLScript.unionVal val, ArrayList args)
        {
            //convert objects from string to integer
            int FLags = Int16.Parse(args[3].ToString());
            int Heading = ((int.Parse(args[4].ToString()) + 180) * 256 / 360);
            int PLID = Int16.Parse(args[6].ToString());
            string ident = val.nameFunction;
            if (args.Count < 8)
            {
                throw new GLScript.GLApp.GLScriptException("Command '" + ident + "' incorrect number of parameters");
            }
                else
                {
                if (FLags == 128 && PLID == -1)
                {
                    throw new GLScript.GLApp.GLScriptException("Warning on Command: '" + ident + "' Cannot spawn spectated players");
                }
                else
                {
                    //X Axis Get info from joinrequest
                    int RoundedValue_X;
                    int CommaValue_X;
                    if (args[0].ToString().Contains("."))
                    {
                        string[] JRR_X_Value = args[0].ToString().Split('.');
                        RoundedValue_X = int.Parse(JRR_X_Value[0].ToString());

                        // if input is XX.X then make it XX.X0
                        if (JRR_X_Value[1].Length == 1)
                        {
                            CommaValue_X = int.Parse(JRR_X_Value[1] + "0");
                        }
                        else
                        {
                            CommaValue_X = int.Parse(JRR_X_Value[1].ToString());
                        }
                    }
                    else
                    {
                        RoundedValue_X = int.Parse(args[0].ToString());
                        CommaValue_X = 00;
                    }
                    //Calculate total Value for the Axis
                    int Total_Rounded_X_Value = (RoundedValue_X * 16);
                    double Total_Comma_X_Value = Math.Round((16.00 / 100.00 * CommaValue_X));
                    int Total_X_Value = Total_Rounded_X_Value;
                    if (Total_Rounded_X_Value < 0)
                    {
                        Total_X_Value = int.Parse((Total_Rounded_X_Value - Total_Comma_X_Value).ToString());
                    }
                    else
                    {
                        Total_X_Value = int.Parse((Total_Rounded_X_Value + Total_Comma_X_Value).ToString());
                    }


                    //Y Axis Get info from joinrequest
                    int RoundedValue_Y;
                    int CommaValue_Y;
                    if (args[1].ToString().Contains("."))
                    {
                        string[] JRR_Y_Value = args[1].ToString().Split('.');
                        RoundedValue_Y = int.Parse(JRR_Y_Value[0].ToString());

                        // if input is XX.X then make it XX.X0
                        if (JRR_Y_Value[1].Length == 1)
                        {
                            CommaValue_Y = int.Parse(JRR_Y_Value[1] + "0");
                        }
                        else
                        {
                            CommaValue_Y = int.Parse(JRR_Y_Value[1].ToString());
                        }
                    }
                    else
                    {
                        RoundedValue_Y = int.Parse(args[1].ToString());
                        CommaValue_Y = 00;
                    }

                    //Z Axis Get info from object
                    int RoundedValue_Z;
                    int CommaValue_Z;
                    if (args[2].ToString().Contains("."))
                    {
                        string[] Object_Z_Value = args[2].ToString().Split('.');
                        RoundedValue_Z = int.Parse(Object_Z_Value[0].ToString());

                        // if input is XX.X then make it XX.X0
                        if (Object_Z_Value[1].Length == 1)
                        {
                            CommaValue_Z = int.Parse(Object_Z_Value[1] + "0");
                        }
                        else
                        {
                            CommaValue_Z = int.Parse(Object_Z_Value[1].ToString());
                        }
                    }
                    else
                    {
                        RoundedValue_Z = int.Parse(args[2].ToString());
                        CommaValue_Z = 00;
                    }

                    //Calculate total Value for the Axis
                    int Total_Rounded_Z_Value = (RoundedValue_Z * 4);
                    double Total_Comma_Z_Value = Math.Round((4.00 / 100.00 * CommaValue_Z));
                    int Total_Z_Value = Int16.Parse((Total_Rounded_Z_Value + Total_Comma_Z_Value).ToString());

                    //Calculate total Value for the Axis
                    int Total_Rounded_Y_Value = (RoundedValue_Y * 16);
                    double Total_Comma_Y_Value = Math.Round((16.00 / 100.00 * CommaValue_Y));
                    int Total_Y_Value = Total_Rounded_Y_Value;
                    if (Total_Rounded_Y_Value < 0)
                    {
                        Total_Y_Value = int.Parse((Total_Rounded_Y_Value - Total_Comma_Y_Value).ToString());
                    }
                    else
                    {
                        Total_Y_Value = int.Parse((Total_Rounded_Y_Value + Total_Comma_Y_Value).ToString());
                    }

                    short JRR_X = short.Parse(Total_X_Value.ToString()); //short X
                    short JRR_Y = short.Parse(Total_Y_Value.ToString()); //short Y

                    if (Total_Z_Value > 0)
                    {
                        byte[] jrr = myEncoder.JRR(JRR_X, JRR_Y, byte.Parse(Total_Z_Value.ToString()), byte.Parse(args[3].ToString()), byte.Parse(Heading.ToString()), byte.Parse(args[5].ToString()), byte.Parse(args[6].ToString()), byte.Parse(args[7].ToString()));
                        insimConnection.Send(jrr, jrr.Length);
                    }
                }
            }
        }
        public void startlightcontrol(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            try
            {
                if (args.Count < 4)
                {
                    throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' incorrect number of parameters");
                }
                else
                {
                    byte[] oco = myEncoder.OCO(byte.Parse(args[0].ToString()), byte.Parse(args[1].ToString()), byte.Parse(args[2].ToString()), byte.Parse(args[3].ToString()));
                    insimConnection.Send(oco, oco.Length);
                }
            }
            catch
            {
                throw new GLScript.GLApp.GLScriptException("Error on Command: '" + ident + "' One of the parameters arent correct.");
            }
        }
        void testArgs(string ident, string pattern, System.Collections.ArrayList args)
        {
            if (pattern.Length != args.Count)
            {
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' incorrect number of parameters");
            }
            for (int i = 0; i < pattern.Length; i++)
            {
                if (pattern[i] == 'I')
                {
                    try
                    {
                        int val = int.Parse(args[i].ToString());

                    }
                    catch
                    {
                        throw new GLScript.GLApp.GLScriptException("'" + ident + "' parameter #" + i.ToString() + "(" + args[i] + ") is wrong type at line #");
                    }
                }
                if (pattern[i] == 'F')
                {
                    try
                    {
                        float val = float.Parse(args[i].ToString());

                    }
                    catch
                    {
                        throw new GLScript.GLApp.GLScriptException("'" + ident + "' parameter #" + i.ToString() + "(" + args[i] + ") is wrong type at line #");
                    }
                }
            }
        }
        public void getlappervar(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            if ((args.Count < 1) && (args.Count > 2))
            {
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' incorrect number of parameters");
            }
            else
            {
                string idVar = "";
                string value = "";
                if (args.Count >= 1)
                {
                    idVar = args[0].ToString();
                }
                if (args.Count == 2)
                {
                    value = args[1].ToString();
                }

                #region globalVar
                //Debug messages
                if (newCfg.varsLapper.DisplayLapperVar == 1)
                {
                    Console.WriteLine("GetLapperVar( " + utils.quote(idVar.ToLower()) + " )");
                }
                switch (idVar.ToLower())
                {
                    case "lapperversion":
                        val.typVal = GLScript.typVal.str;
                        val.sval = "\"" + LFSLapper.getShortVersion(4) + "\"";
                        return;
                    case "lfsversion":
                        val.typVal = GLScript.typVal.str;
                        val.sval = "\"" + insimConnection.Version + "\"";
                        return;
                    case "lfsmode":
                        val.typVal = GLScript.typVal.str;
                        val.sval = "\"" + insimConnection.Product + "\"";
                        return;
                    case "lapperstate":
                        val.typVal = GLScript.typVal.str;
                        val.sval = "\"" + paramLapper.LapperState + "\"";
                        return;
                    case "rotatein":
                        val.typVal = GLScript.typVal.num;
                        if (newCfg.varsLapper.EnableRotation)
                            val.fval = newCfg.varsLapper.RotateEveryNbRaces - currRace.racesDone;
                        else
                            val.fval = 0;
                        return;
                    case "racelapsleft":
                        val.typVal = GLScript.typVal.num;
                        if (currRace.inRace)
                            val.fval = currRace.raceLapsLeft;
                        else
                            val.fval = 0;
                        return;

                    case "hostname":
                        val.typVal = GLScript.typVal.str;
                        val.sval = utils.quote(currentHName);
                        return;
                    case "shorttrackname":
                        val.typVal = GLScript.typVal.str;
                        val.sval = utils.quote(currState.ShortTrackName);
                        return;
                    case "longtrackname":
                        val.typVal = GLScript.typVal.str;
                        val.sval = utils.quote(UTILS.utils.getLongTrackName(currState.ShortTrackName));
                        return;
                    case "trackid":
                        val.typVal = GLScript.typVal.str;
                        val.sval = utils.quote(UTILS.utils.convTrackShortnameToId(currState.ShortTrackName));
                        return;
                    case "shorttime":
                        val.typVal = GLScript.typVal.str;
                        if (value == "")
                        {
                            val.sval = utils.quote(System.DateTime.Now.ToString(newCfg.varsLapper.ShortTimeFormat));
                        }
                        else
                        {
                            /*
                            DateTime CurrentTime = DateTime.Now;
                            DateTime newTime = CurrentTime.AddHours
                            */
                            val.sval = utils.quote(System.DateTime.Now.ToString(newCfg.varsLapper.ShortTimeFormat));
                        }


                        return;
                    case "longtime":
                        val.typVal = GLScript.typVal.str;
                        val.sval = utils.quote(System.DateTime.Now.ToString(newCfg.varsLapper.LongTimeFormat));
                        return;
                    //Edited @ 24/11/2018
                    case "shortdate":
                        val.typVal = GLScript.typVal.str;
                        if (value == "")
                        {
                            val.sval = utils.quote(System.DateTime.Now.ToString(newCfg.varsLapper.DateFormat));
                        }
                        else
                        {
                            DateTime CurrentDate = DateTime.Today;
                            int Numericvalue = int.Parse(value.ToString());
                            DateTime newDate = CurrentDate.AddDays(Numericvalue);
                            //Return Value
                            val.sval = utils.quote(newDate.ToString(newCfg.varsLapper.DateFormat));
                        }
                        return;
                    case "longdate":
                        val.typVal = GLScript.typVal.str;
                        val.sval = utils.quote(System.DateTime.Now.ToString(newCfg.varsLapper.LongDateFormat));
                        return;
                    case "nextrotatecar":
                        {
                            val.typVal = GLScript.typVal.str;
                            int nextCar = currRace.currRotateCar + 1;
                            string[] tmpCars = newCfg.varsLapper.RotateCars.Split(',');
                            if (nextCar > tmpCars.Length - 1)
                                nextCar = 0;
                            val.sval = utils.quote(tmpCars[nextCar]);
                        }
                        return;
                    case "nextrotatetrack":
                    case "nextlongrotatetrack":
                        {
                            val.typVal = GLScript.typVal.str;
                            int nextTrack = currRace.currRotateTrack + 1;
                            string[] tmpTracks = newCfg.varsLapper.RotateTracks.Split(',');
                            if (nextTrack > tmpTracks.Length - 1)
                                nextTrack = 0;
                            if (idVar == "nextrotatetrack")
                                val.sval = utils.quote(tmpTracks[nextTrack]);
                            else
                                val.sval = utils.quote(UTILS.utils.getLongTrackName(tmpTracks[nextTrack]));

                        }
                        return;
                    case "currrotatecar":
                        {
                            val.typVal = GLScript.typVal.str;
                            int nextCar = currRace.currRotateCar;
                            string[] tmpCars = newCfg.varsLapper.RotateCars.Split(',');
                            if (nextCar > tmpCars.Length - 1)
                                nextCar = 0;
                            val.sval = utils.quote(tmpCars[nextCar]);
                        }
                        return;
                    case "currrotatetrack":
                    case "currlongrotatetrack":
                        {
                            val.typVal = GLScript.typVal.str;
                            int nextTrack = currRace.currRotateTrack;
                            string[] tmpTracks = newCfg.varsLapper.RotateTracks.Split(',');
                            if (nextTrack > tmpTracks.Length - 1)
                                nextTrack = 0;
                            if (idVar == "CurrRotateTrack")
                                val.sval = utils.quote(tmpTracks[nextTrack]);
                            else
                                val.sval = utils.quote(UTILS.utils.getLongTrackName(tmpTracks[nextTrack]));
                        }
                        return;
                    case "requiredflags":
                        val.typVal = GLScript.typVal.str;
                        val.sval = utils.quote(sFlagsRequired);
                        return;
                    case "nbplayersontrack":
                        val.typVal = GLScript.typVal.num;
                        val.fval = listOfPlayers.nbPlayerOnTrack;
                        return;
                    case "dateracestarted":
                        val.typVal = GLScript.typVal.str;
                        val.sval = utils.quote(currRace.started.ToString("yyyy-MM-dd-hh-mm-ss"));
                        return;

                    //Retreive Laps/Hours from LFS
                    /*
                     // RaceLaps (rl) : (various meanings depending on range)

                     // 0       : practice
                     // 1-99    : number of laps...   laps  = rl
                     // 100-190 : 100 to 1000 laps... laps  = (rl - 100) * 10 + 100
                     // 191-238 : 1 to 48 hours...    hours = rl - 190
                    */
                    case "racelaps":
                        int laps;
                        if (currState.RaceLaps < 190)
                        {
                            //laps
                            if ((currState.RaceLaps > 100) && (currState.RaceLaps < 190))
                            {

                                laps = ((currState.RaceLaps - 100) * 10 + 100);
                            }
                            else
                            {
                                laps = currState.RaceLaps;
                            }
                        }
                        else
                        {
                            laps = 0; // IF Hours is set Return 0 
                        }
                        val.typVal = GLScript.typVal.num;
                        val.fval = laps;
                        return;

                    case "racehours":
                        int hours;
                        if (currState.RaceLaps > 190)
                        {
                            hours = (currState.RaceLaps - 190);
                        }
                        else
                        {
                            hours = 0; // IF Laps is set Return 0 
                        }
                        val.typVal = GLScript.typVal.num;
                        val.fval = hours;
                        return;

                    case "raceinprog":
                        val.typVal = GLScript.typVal.num;
                        val.fval = currState.RaceInProg;
                        return;
                    case "racemins":
                        val.typVal = GLScript.typVal.num;
                        val.fval = currRace.raceMins;
                        return;
                    case "elapsedmins":
                        TimeSpan interval = DateTime.Now.Subtract(currRace.started);
                        val.typVal = GLScript.typVal.num;
                        val.fval = (float)interval.TotalMinutes;
                        return;
                    case "elapsedsecs":
                        TimeSpan interval2 = DateTime.Now.Subtract(currRace.started);
                        val.typVal = GLScript.typVal.num;
                        val.fval = (float)interval2.TotalSeconds;
                        return;
                    case "elapsedms":
                        TimeSpan intervalms = DateTime.Now.Subtract(currRace.started);
                        val.typVal = GLScript.typVal.num;
                        val.fval = (float)intervalms.TotalMilliseconds;
                        return;
                    case "numfinished":
                        val.typVal = GLScript.typVal.num;
                        val.fval = currState.NumFinished;
                        return;
                    case "racetime":
                        TimeSpan intervalm = DateTime.Now.Subtract(currRace.started);
                        double RaceTimer = long.Parse(Math.Round(intervalm.TotalMilliseconds).ToString());
                        val.typVal = GLScript.typVal.num;
                        val.fval = (float)RaceTimer;
                        return;
                    case "allowedcars":
                        val.typVal = GLScript.typVal.str;
                        val.sval = "\"" + newCfg.varsLapper.AllowedCars + "\"";
                        return;
                    case "qualmins":
                        val.typVal = GLScript.typVal.num;
                        val.fval = currRace.qualMins;
                        return;
                    case "numconns":
                        val.typVal = GLScript.typVal.num;
                        val.fval = currState.NumConns;
                        return;
                    case "wind":
                        val.typVal = GLScript.typVal.num;
                        val.fval = currState.Wind;
                        return;
                    case "weather":
                        val.typVal = GLScript.typVal.num;
                        val.fval = (currState.Weather + 1);
                        return;
                    case "numplayers":
                        val.typVal = GLScript.typVal.num;
                        val.fval = currState.NumP;
                        return;
                    #region RaceFlags
                    case "canvote": //Guests may vote
                        val.typVal = GLScript.typVal.num;
                        if ((currRace.raceFlags & 1) == 1)
                            val.fval = 1;
                        else
                            val.fval = 0;
                        return;
                    case "canselect": //Guests can select car/track
                        val.typVal = GLScript.typVal.num;
                        if ((currRace.raceFlags & 2) == 2)
                            val.fval = 1;
                        else
                            val.fval = 0;
                        return;
                    case "midracejoin": //Guests are allowed to join during a race
                        val.typVal = GLScript.typVal.num;
                        if ((currRace.raceFlags & 32) == 32)
                            val.fval = 1;
                        else
                            val.fval = 0;
                        return;
                    case "mustpit": //Guests must pit during a race
                        val.typVal = GLScript.typVal.num;
                        if ((currRace.raceFlags & 64) == 64)
                            val.fval = 1;
                        else
                            val.fval = 0;
                        return;
                    case "canreset": //Guests may reset theire car
                        val.typVal = GLScript.typVal.num;
                        if ((currRace.raceFlags & 128) == 128)
                            val.fval = 1;
                        else
                            val.fval = 0;
                        return;
                    case "forcedcockpitview": //Guests are forced to use cockpitview
                        val.typVal = GLScript.typVal.num;
                        if ((currRace.raceFlags & 256) == 256)
                            val.fval = 1;
                        else
                            val.fval = 0;
                        return;
                    case "cruise": //Guests are allowed to drive wrong way
                        val.typVal = GLScript.typVal.num;
                        if ((currRace.raceFlags & 512) == 512)
                            val.fval = 1;
                        else
                            val.fval = 0;
                        return;
                    case "timing": //Type of Timing
                        val.typVal = GLScript.typVal.num;
                        if ((currRace.timing & 64) == 64)
                            val.fval = 1;
                        if ((currRace.timing & 128) == 128)
                            val.fval = 2;
                        if ((currRace.timing & 192) == 192)
                            val.fval = 0;
                        return;

                    case "nbofcheckpoints": //Number of checkpoints (0 ,1,2 or 3) Insim checkpoints does not count
                        val.typVal = GLScript.typVal.num;
                        if ((currRace.timing & 192) == 192) //No laptiming, See 'timing' var
                            val.fval = 0;
                        if ((currRace.timing & 1) == 1) //1 checkpoint
                            val.fval = 1;
                        if ((currRace.timing & 2) == 2) //2 checkpoints
                            val.fval = 2;
                        if ((currRace.timing & 3) == 3) //3 checkpoints
                            val.fval = 3;
                        return;
                    #endregion
                    default:
                        val.typVal = GLScript.typVal.str;
                        val.sval = utils.quote("");
                        return;
                }
            }
            #endregion
        }
        public void getplayerinfo(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            infoPlayer currPly = null;
            if (args.Count > 0)
            {
                testArgs("getplayerinfo", "S", args);
                currPly = listOfPlayers.getPlayerByUserName((string)args[0]);
            }
            else
            {
                currPly = listOfPlayers.getPlayerByUserName((string)currInfoPlayer.userName);
            }
            if (currPly == null)
            {
                val.typVal = GLScript.typVal.str;
                val.sval = utils.quote("");
                return;
            }
            val.typVal = GLScript.typVal.setOfVar;
            val.setVars = new GLScript.SetOfVars();
            foreach (string pvar in Enum.GetNames(typeof(playerVars)))
            {
                val.setVars.Set(utils.quote(pvar), currPly.playerVars.Get(utils.quote(pvar)));
            }
        }

        #region Button functions
        public void openprivbutton(GLScript.unionVal val, ArrayList args)
        {

            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            if (args.Count == 9)
                args.Add("");
            testArgs(ident, "SIIIIIIISS", args);
            string text = args[8].ToString();
            if (text == "[[TranslateEngine]]")
                text = lfsLang.replaceParmsLangStr(currInfoPlayer.idLang);
            currInfoPlayer.playerBox.create(
                                                args[0].ToString(), // ID du boutton
                                                currInfoPlayer.UCID,
                                                int.Parse(args[1].ToString()), // X
                                                int.Parse(args[2].ToString()), // Y
                                                int.Parse(args[3].ToString()),  // Largeur
                                                int.Parse(args[4].ToString()),  // Hauteur
                                                int.Parse(args[5].ToString()),  // Interligne
                                                int.Parse(args[6].ToString()), // Sec Visible
                                                0,                              // TypeIn
                                                int.Parse(args[7].ToString()),  // Bstyle
                                                "",                             // Caption
                                                text,             // Button Text
                                                args[9].ToString()              // BackCall
            );
            currInfoPlayer.playerBox.show(args[0].ToString(), currInfoPlayer.UCID);

        }
        public void closeprivbutton(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            testArgs(ident, "S", args);
            currInfoPlayer.privateButtonClose(args[0].ToString());
        }
        public void openbutton(GLScript.unionVal val, ArrayList args)
        {

            infoPlayer currPly;
            string ident = val.nameFunction;
            currPly = listOfPlayers.getPlayerByUserName((string)args[0]);
            if (currPly == null)
            {
                throw new GLScript.GLApp.GLScriptException("Player name " + (string)args[0] + " in function " + ident + " not a player");
            }
            args.RemoveAt(0);
            if (args.Count == 9)
                args.Add("");
            testArgs(ident, "SIIIIIIISS", args);
            string text = args[8].ToString();
            if (text == "[[TranslateEngine]]")
                text = lfsLang.replaceParmsLangStr(currPly.idLang);
            currPly.playerBox.create(
                                                args[0].ToString(), // ID du boutton
                                                currPly.UCID,
                                                int.Parse(args[1].ToString()), // X
                                                int.Parse(args[2].ToString()), // Y
                                                int.Parse(args[3].ToString()),  // Largeur
                                                int.Parse(args[4].ToString()),  // Hauteur
                                                int.Parse(args[5].ToString()),  // Interligne
                                                int.Parse(args[6].ToString()), // Sec Visible
                                                0,                              // TypeIn
                                                int.Parse(args[7].ToString()),  // Bstyle
                                                "",                             // Caption
                                                text,             // Button Text
                                                args[9].ToString()              // BackCall
            );
            currPly.playerBox.show(args[0].ToString(), currPly.UCID);

        }
        public void opentextbutton(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currPly = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            currPly = listOfPlayers.getPlayerByUserName((string)args[0]);
            if (currPly == null)
            {
                throw new GLScript.GLApp.GLScriptException("Player name " + (string)args[0] + " in function " + ident + " not a player");
            }
            args.RemoveAt(0);
            testArgs(ident, "SIIIIIISSIS", args);
            string text = args[8].ToString();
            if (text == "[[TranslateEngine]]")
                text = lfsLang.replaceParmsLangStr(currPly.idLang);

            currPly.playerBox.create(args[0].ToString(), // ID du boutton
                                                currPly.UCID,
                                                int.Parse(args[1].ToString()),  // X
                                                int.Parse(args[2].ToString()),  // Y
                                                int.Parse(args[3].ToString()),  // Largeur
                                                int.Parse(args[4].ToString()),  // Hauteur
                                                int.Parse(args[5].ToString()),  // Interligne
                                                -1,                              // Sec Visible
                                                int.Parse(args[9].ToString()),  // TypeIn
                                                int.Parse(args[6].ToString()),  // Bstyle
                                                args[7].ToString(),             // Caption
                                                text,            // Button Text
                                                args[10].ToString()             // BackCall
            );
            currPly.playerBox.show(args[0].ToString(), currPly.UCID);
        }
        public void closebutton(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currPly;
            string ident = val.nameFunction;
            currPly = listOfPlayers.getPlayerByUserName((string)args[0]);
            if (currPly == null)
            {
                throw new GLScript.GLApp.GLScriptException("Player name " + (string)args[0] + " in function " + ident + " not a player");
            }
            args.RemoveAt(0);
            testArgs(ident, "S", args);
            currPly.privateButtonClose(args[0].ToString());
        }
        #endregion
        public void getlistoflang(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;

            string[] lang = lfsLang.getAllLang();

            val.typVal = GLScript.typVal.setOfVar;
            val.setVars = new GLScript.SetOfVars();
            for (int i = 0; i < lang.Length; i++)
            {
                val.setVars.Set(i.ToString(), new GLScript.unionVal(0, utils.quote(lang[i]), GLScript.typVal.str));
            }
        }
        public void getwr(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            string car = "";
            wr.wrInfo wi = null;
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");

            val.typVal = GLScript.typVal.setOfVar;
            val.setVars = new GLScript.SetOfVars();
            if (args.Count > 0)
            {
                car = args[0].ToString();
            }
            else
            {
                car = currInfoPlayer.CName;
            }
            //get WR from lfsworld
            wi = currWr.getWR(currState.ShortTrackName, car);

            if (wi == null)
            {
                val.setVars.Set(utils.quote("CName"), new GLScript.unionVal(0, utils.quote(""), GLScript.typVal.str));
                val.setVars.Set(utils.quote("Track"), new GLScript.unionVal(0, utils.quote(""), GLScript.typVal.str));
                val.setVars.Set(utils.quote("racerName"), new GLScript.unionVal(0, utils.quote(""), GLScript.typVal.str));
                val.setVars.Set(utils.quote("WRTime"), new GLScript.unionVal(0, utils.quote("0"), GLScript.typVal.str));
                val.setVars.Set(utils.quote("Split1"), new GLScript.unionVal(0, utils.quote("0"), GLScript.typVal.str));
                val.setVars.Set(utils.quote("Split2"), new GLScript.unionVal(0, utils.quote("0"), GLScript.typVal.str));
                val.setVars.Set(utils.quote("Split3"), new GLScript.unionVal(0, utils.quote("0"), GLScript.typVal.str));
                val.setVars.Set(utils.quote("SectorLast"), new GLScript.unionVal(0, utils.quote("0"), GLScript.typVal.str));
                val.setVars.Set(utils.quote("DateTime"), new GLScript.unionVal(0, utils.quote("0"), GLScript.typVal.str));
            }
            else
            {
                val.setVars.Set(utils.quote("CName"), new GLScript.unionVal(0, utils.quote(wi.CName), GLScript.typVal.str));
                val.setVars.Set(utils.quote("Track"), new GLScript.unionVal(0, utils.quote(wi.track), GLScript.typVal.str));
                val.setVars.Set(utils.quote("racerName"), new GLScript.unionVal(0, utils.quote(wi.racerName), GLScript.typVal.str));
                val.setVars.Set(utils.quote("WRTime"), new GLScript.unionVal(0, utils.quote(wi.WRTime.ToString()), GLScript.typVal.str));
                val.setVars.Set(utils.quote("Split1"), new GLScript.unionVal(0, utils.quote(wi.split[0].ToString()), GLScript.typVal.str));
                val.setVars.Set(utils.quote("Split2"), new GLScript.unionVal(0, utils.quote(wi.split[1].ToString()), GLScript.typVal.str));
                val.setVars.Set(utils.quote("Split3"), new GLScript.unionVal(0, utils.quote(wi.split[2].ToString()), GLScript.typVal.str));
                val.setVars.Set(utils.quote("SectorLast"), new GLScript.unionVal(0, utils.quote(wi.sectorSplitLast.ToString()), GLScript.typVal.str));

                // Example of a UNIX timestamp for 11-29-2013 4:58:30
                double timestamp = wi.flags;
            
                // Format our new DateTime object to start at the UNIX Epoch
                System.DateTime dateTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0);

                // Add the timestamp (number of seconds since the Epoch) to be converted
                dateTime = dateTime.AddSeconds(timestamp);

                string Date = dateTime.ToString(newCfg.varsLapper.DateFormat);
                string Time = dateTime.ToString("HH:mm:ss");
                val.setVars.Set(utils.quote("Date"), new GLScript.unionVal(0, utils.quote(Date.ToString()), GLScript.typVal.str));
                val.setVars.Set(utils.quote("Time"), new GLScript.unionVal(0, utils.quote(Time.ToString()), GLScript.typVal.str));
            }
        }
        public void striplfscolor(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            val.typVal = GLScript.typVal.str;
            val.sval = utils.quote(UTILS.utils.stripLFSColor((string)args[0]));
        }
        public void setracegrid(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;

            if (args.Count == 1)
            {
                testArgs(ident, "S", args);
                //string subF = "";
            }
            else if (args.Count == 2)
            {
                testArgs(ident, "SS", args);
                //string subF = (string)args[1];
            }

            //            for (int i = 0; i < currGridOrder.Length - 1; i++)
            //                currGridOrder[i] = 0;


            /*			// Loop through the comma separated string provided for new race order as PLIDs
                        string[] thisPLID = args[0].ToString().Split(',');
                        for (int i = 0; i < thisPLID.Length; i++)
                        {
                            try
                            {
                                currGridOrder[i] = int.Parse(thisPLID[i].ToString());
                            }
                            catch
                            {
                                throw new GLScript.GLApp.GLScriptException("'" + ident + "' parameter #" + i.ToString() + "(" + thisPLID[i] + ") is wrong type at line #");
                            }
                        }
            */
            val.typVal = GLScript.typVal.str;
            val.sval = utils.quote("");
        }
        public void requestreo(GLScript.unionVal val, ArrayList args)
        {
            // Request an REO packet
            byte[] reo = myEncoder.REO(250);
            insimConnection.Send(reo, reo.Length);
            val.typVal = GLScript.typVal.str;
            val.sval = utils.quote("");
        }
        public void getlistofplayers(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            ArrayList lply = new ArrayList();

            val.typVal = GLScript.typVal.setOfVar;
            val.setVars = new GLScript.SetOfVars();
            foreach (DictionaryEntry de in listOfPlayers.playersUCID)
            {
                infoPlayer CI = (infoPlayer)de.Value;
                if (CI.UCID == 0)
                    continue;
                lply.Add(new LOP(CI.userName, UTILS.utils.stripLFSColor(CI.nickName)));
            }
            lply.Sort(new sortByUName());
            if (args.Count == 1)
            {
                string sort = (string)args[0];
                if (sort.ToLower() == "n")
                    lply.Sort(new sortByNName());
            }
            for (int i = 0; i < lply.Count; i++)
            {
                val.setVars.Set(i.ToString(), new GLScript.unionVal(0, utils.quote((lply[i] as LOP).userName), GLScript.typVal.str));
            }
        }
        public void setplayervar(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "SSS", args);
            SetVarPlayer(val, utils.quote((string)args[1]), (string)args[0], (string)args[2]);
            if (newCfg.varsLapper.DisplaySetPlayerVar == 1)
            {
                Console.WriteLine("SetPlayerVar( " + (string)args[0] + " , " + (string)args[1] + " , " + (string)args[2]+" )");
            }
        }
        public void getplayervar(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "SS", args);

            infoPlayer currInfoPlayer = listOfPlayers.getPlayerByUserName((string)args[0]);
            if (currInfoPlayer == null)
            {
                val.typVal = GLScript.typVal.str;
                val.sval = utils.quote("");
                return;
            }
            GLScript.unionVal retVal = currInfoPlayer.playerVars.Get(utils.quote((string)args[1]));
            val.typVal = retVal.typVal;
            val.sval = retVal.sval;
            val.fval = retVal.fval;
            if (newCfg.varsLapper.DisplayGetPlayerVar == 1)
            {
                Console.WriteLine("GetPlayerVar( " + (string)args[0] + " , " + (string)args[1] + ") = " + retVal.sval + "/" + val.fval);
            }
        }
        public void getplayervarbyucid(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "IS", args);

            infoPlayer currInfoPlayer = listOfPlayers.getPlayerByUCID(int.Parse(args[0].ToString()));
            if (currInfoPlayer == null)
            {
                val.typVal = GLScript.typVal.str;
                val.sval = utils.quote("");
                return;
            }
            GLScript.unionVal retVal = currInfoPlayer.playerVars.Get(utils.quote((string)args[1]));
            val.typVal = retVal.typVal;
            val.sval = retVal.sval;
            val.fval = retVal.fval;
        }
        public void getplayervarbyplid(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "IS", args);

            infoPlayer currInfoPlayer = listOfPlayers.getPlayerByPLID(int.Parse(args[0].ToString()));
            if (currInfoPlayer == null)
            {
                val.typVal = GLScript.typVal.str;
                val.sval = utils.quote("");
                return;
            }
            GLScript.unionVal retVal = currInfoPlayer.playerVars.Get(utils.quote((string)args[1]));
            val.typVal = retVal.typVal;
            val.sval = retVal.sval;
            val.fval = retVal.fval;
        }
        public void getconfigvar(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            getConfigVar(val, (string)args[0]);

        }
        public void setconfigvar(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "SS", args);
            setConfigVar(val, (string)args[0], (string)args[1]);
            //Discord
            if((string)args[0] == "DiscordBotStatus")
            {
                DiscordBot.ChangeBotStatus((string)args[1]);
            }
        }
        public void numtomsh(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            string valargs = args[0].ToString();
            testArgs(ident, "S", args);
            val.typVal = GLScript.typVal.str;
            try
            {
                if(!valargs.Contains(":"))
                    val.sval = utils.quote(unitConv.LongToHMS(long.Parse((string)args[0])));
                else
                    val.sval = utils.quote((string)args[0]);
            }
            catch
            {
                val.sval = "";
            }
        }
        public void numtoms(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            val.typVal = GLScript.typVal.str;
            try
            {
                val.sval = utils.quote(unitConv.LongToMS(long.Parse((string)args[0])));
            }
            catch
            {
                val.sval = "";
            }
        }
        public void mshtonum(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            val.typVal = GLScript.typVal.num;
            val.fval = unitConv.HMSToLong(args[0].ToString());
        }
        public void tokph(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "F", args);
            val.typVal = GLScript.typVal.num;
            val.fval = (float)unitConv.toKph(float.Parse(args[0].ToString()));
        }
        public void tomph(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "F", args);
            val.typVal = GLScript.typVal.num;
            val.fval = (float)unitConv.toMph(float.Parse(args[0].ToString()));
        }
        public void toplayerunit(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "F", args);
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            val.typVal = GLScript.typVal.num;
            val.fval = float.Parse(string.Format("{0:n}", unitConv.getSpeed(currInfoPlayer.unitSpeedKmh, float.Parse(args[0].ToString()))));
        }
        public void langtranslate(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            string lang = "en";
            if (args.Count < 1)
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' incorrect number of parameters");
            if (currInfoPlayer != null)
                lang = currInfoPlayer.idLang;
            string tmpStr = (string)args[0];
            tmpStr = lfsLang.replaceLangStr(lang, tmpStr);
            args.RemoveAt(0);
            try
            {
                val.sval = "\"" + string.Format(tmpStr, args.ToArray()) + "\"";
            }
            catch
            {
                val.sval = "\"" + "Wrong format " + tmpStr + "\"";
            }
            val.typVal = GLScript.typVal.str;
        }
        public void langengine(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            if (args.Count < 1)
                throw new GLScript.GLApp.GLScriptException("Error on Command '" + ident + "' incorrect number of parameters");
            string tmpStr = (string)args[0];
            args.RemoveAt(0);
            lfsLang.setParmsTranslate(tmpStr, args);
            val.sval = "\"" + "[[TranslateEngine]]" + "\"";
            val.typVal = GLScript.typVal.str;
        }
        public void forcerotation(GLScript.unionVal val, ArrayList args)
        {
            ForceRotation = 1;
            val.typVal = GLScript.typVal.str;
            val.sval = utils.quote("");
        }
        public void termlapper(GLScript.unionVal val, ArrayList args)
        {
            TermProg = true;
            val.typVal = GLScript.typVal.str;
            val.sval = utils.quote("");
        }
        public void groupcmdlfs(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            outgoingCmdStack.Enqueue(args[0]);
        }
        public void cmdlfs(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            SendMsg(args[0].ToString());
        }
        public void setlicense(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            {
                string arg = args[0].ToString().Trim().ToLower();
                if (arg == "on")
                {
                    SendMsg("License ON");
                    SystemAuth.AuthOn = true;
                }
                if (arg == "off")
                {
                    SendMsg("License OFF");
                    SystemAuth.AuthOn = false;
                }
                if (arg == "?" || arg == "")
                {
                    if (SystemAuth.AuthOn)
                        SendMsg("License Status = ON");
                    else
                        SendMsg("License Status = OFF");
                }
            }
        }
        public void setcurrentplayervar(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "SS", args);
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            SetVarPlayer(val, utils.quote((string)args[0]), currInfoPlayer.userName, (string)args[1]);
        }
        public void getcurrentplayervar(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");

            GLScript.unionVal retVal = currInfoPlayer.playerVars.Get(utils.quote((string)args[0]));
            val.typVal = retVal.typVal;
            val.sval = retVal.sval;
            val.fval = retVal.fval;
        }

        public void privmsg(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            if ((args.Count >= 1) && (args.Count <= 3))
            {
                infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
                infoPlayer sendMsgToPlayer = listOfPlayers.getPlayerByUserName((string)args[0]);
                string text = "";
                int MsgSound = 0; // Silent

                if (args.Count == 1) //Function contains 1 argument
                {
                    text = args[0].ToString();
                }

                if (args.Count == 2) //Function contains 2 arguments
                {
                    if (sendMsgToPlayer == null)
                    {
                        MsgSound = int.Parse(args[1].ToString());
                        if ((MsgSound >= 0) && (MsgSound <= 5))
                        {
                            text = args[0].ToString();
                            MsgSound = int.Parse(args[1].ToString());
                        }
                        else
                        {
                            SendMsgToConnection(currInfoPlayer.UCID, "^6Unable to sent a message to player: ^7" + (string)args[0], 1);  //Sent message to player
                        }
                    }
                    else
                    {
                        text = args[1].ToString();
                    }
                }
                if (args.Count == 3) //Function contains 3 arguments
                {
                    if (sendMsgToPlayer == null)
                    {
                        SendMsgToConnection(currInfoPlayer.UCID, "^6Unable to sent a message to player: ^7" + (string)args[0], 1);  //Sent message to player
                    }
                    else
                    {
                        text = args[1].ToString();
                        if ((MsgSound >= 0) && (MsgSound <= 5))
                        {
                            MsgSound = int.Parse(args[2].ToString());
                        }
                        else
                        {
                            throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', Wrong msgsound! (0-5)");
                        }
                    }
                }
                    if (text == "[[TranslateEngine]]")
                        text = lfsLang.replaceParmsLangStr(currInfoPlayer.idLang);

                    if (sendMsgToPlayer == null)
                    {
                        SendMsgToConnection(currInfoPlayer.UCID, text, MsgSound);  //Sent message to player
                    }
                    else
                    {
                        SendMsgToConnection(sendMsgToPlayer.UCID, text, MsgSound);   //Sent message to player
                    }
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', Incorrect number of parameters");
            }
        }

        public void globalmsg(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer;
            string ident = val.nameFunction;
            if ((args.Count > 0) && (args.Count < 3))
            {
                string text = args[0].ToString();
                string newText = "";
                int MsgSound = 0; // Silent

                //When the function contains 2 arguments.
                if (args.Count == 2)
                {
                    MsgSound = int.Parse(args[1].ToString());
                }
               
                foreach (DictionaryEntry de in listOfPlayers.playersUserName)
                {
                    currInfoPlayer = (infoPlayer)de.Value;
                    if (currInfoPlayer.userName != null)
                    {
                        if (text != "[[TranslateEngine]]")
                        {
                            newText = text;
                        }
                        else
                        {
                            newText = lfsLang.replaceParmsLangStr(currInfoPlayer.idLang);
                        }
                        SendMsgToConnection(currInfoPlayer.UCID, newText, MsgSound);
                    }
                }
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', Incorrect number of parameters");
            }
        }
        public void cleanspb(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            currInfoPlayer.splitLast = 0;
            for (int i = 0; i < (int)paramLapper.maxSplit; i++)
                currInfoPlayer.sessBestSplitDiff[i] = 0;
            currInfoPlayer.sessBestSplitDiffLast = 0;
            currInfoPlayer.bestSpeed = (double)0;
            SendMsgToConnection(currInfoPlayer.UCID, currInfoPlayer.nickName + "^8 SPB Cleaned",0);

        }
        public void showspb(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            string spb = "";
            try
            {
                switch (currInfoPlayer.viewSPBSplit)
                {
                    case "W":
                    case "P":
                        spb = "PB ";
                        for (int i = 0; i < (int)paramLapper.maxSplit; i++)
                        {
                            if (currInfoPlayer.gripDriverLapInfo.PBBestSplitDiff[i] != 0)
                                spb = spb + "^7SP" + (i + 1).ToString() + ":^8" + unitConv.LongToHMS(currInfoPlayer.gripDriverLapInfo.PBBestSplitDiff[i]);
                        }
                        if (currInfoPlayer.gripDriverLapInfo.PBBestSplitDiffLast != 0)
                            spb = spb + "^7SPL:^8" + unitConv.LongToHMS(currInfoPlayer.gripDriverLapInfo.PBBestSplitDiffLast);
                        break;
                    case "S":
                        spb = "Sess ";
                        for (int i = 0; i < (int)paramLapper.maxSplit; i++)
                        {
                            if (currInfoPlayer.sessBestSplitDiff[i] != 0)
                                spb = spb + "^7SP" + (i + 1).ToString() + ":^8" + unitConv.LongToHMS(currInfoPlayer.sessBestSplitDiff[i]);
                        }
                        if (currInfoPlayer.sessBestSplitDiffLast != 0)
                            spb = spb + "^7SPL:^8" + unitConv.LongToHMS(currInfoPlayer.sessBestSplitDiffLast);
                        break;
                }
                SendMsgToConnection(currInfoPlayer.UCID, spb,0);
                SendMsgToConnection(currInfoPlayer.UCID, unitConv.LongToHMS(currInfoPlayer.TPb),0);
            }
            catch (Exception) { }

        }
        public void showhand(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            if (newCfg.varsLapper.RefreshHandicapUsers)
                UpdateHandicapUsers(newCfg.varsLapper.HandicapUsers);
            ShowHand(currInfoPlayer, args[0].ToString());
        }
        public void lapperversion(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            Ver(currInfoPlayer.UCID);
        }
        public void stats(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            testArgs(ident, "S", args);
            ShowStats(currInfoPlayer.UCID, currInfoPlayer.userName, currInfoPlayer.nickName, args[0].ToString(), false);
        }
        public void dstats(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            testArgs(ident, "S", args);
            ShowDriftStats(currInfoPlayer.UCID, currInfoPlayer.userName, currInfoPlayer.nickName, args[0].ToString(), false);
        }
        public void statsqual(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            testArgs(ident, "S", args);
            ShowStats(currInfoPlayer.UCID, currInfoPlayer.userName, currInfoPlayer.nickName, args[0].ToString(), true);
        }
        public void dstatsqual(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            testArgs(ident, "S", args);
            ShowDriftStats(currInfoPlayer.UCID, currInfoPlayer.userName, currInfoPlayer.nickName, args[0].ToString(), true);
        }

        public void currentplayerlfsworldpb(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            testArgs(ident, "S", args);
            lfsWorldPB(currInfoPlayer.UCID, currInfoPlayer.userName, currInfoPlayer.nickName, args[0].ToString(), 0);
        }
        public void currentplayerlfsworldpbfrom(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            testArgs(ident, "SI", args);
            lfsWorldPB(currInfoPlayer.UCID, currInfoPlayer.userName, currInfoPlayer.nickName, args[0].ToString(), int.Parse(args[1].ToString()));
        }
        public void getlisttop(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            bool flagQual = false;
            bool flagNear = false;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            testArgs(ident, "SII", args);
            if (int.Parse((string)args[1]) == 1)
                flagQual = true;
            if (int.Parse((string)args[2]) == 1)
                flagNear = true;
            ArrayList list = GetListTopGrip(currInfoPlayer.userName, args[0].ToString(), flagQual, flagNear);

            val.typVal = GLScript.typVal.setOfVar;
            val.setVars = new GLScript.SetOfVars();
            for (int i = 0; i < list.Count; i++)
            {
                LFSDbs.gripDbs.DriverLapEntry elem = (LFSDbs.gripDbs.DriverLapEntry)list[i];
                val.setVars.Set(i.ToString() + "," + utils.quote("ID"), new GLScript.unionVal(0, utils.quote(elem.ID), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("UserName"), new GLScript.unionVal(0, utils.quote(elem.userName), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("NickName"), new GLScript.unionVal(0, utils.quote(elem.nickName), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("CName"), new GLScript.unionVal(0, utils.quote(elem.carName), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("DatePb"), new GLScript.unionVal(0, utils.quote(elem.datePb), GLScript.typVal.str));
                string sgroup = "";
                if (elem.group != -1)
                {
                    sgroup = ((char)(elem.group + 65)).ToString();
                }
                val.setVars.Set(i.ToString() + "," + utils.quote("Group"), new GLScript.unionVal(0, utils.quote(sgroup), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("Laps"), new GLScript.unionVal(elem.laps, utils.quote(""), GLScript.typVal.num));
                for (int j = 0; j < elem.PBBestSplitDiff.Length; j++)
                    val.setVars.Set(i.ToString() + "," + utils.quote("PbBestSplitDiff" + j.ToString()), new GLScript.unionVal(elem.PBBestSplitDiff[j], utils.quote(""), GLScript.typVal.num));
                val.setVars.Set(i.ToString() + "," + utils.quote("PbBestSplitDiffLast"), new GLScript.unionVal(elem.PBBestSplitDiffLast, utils.quote(""), GLScript.typVal.num));
                val.setVars.Set(i.ToString() + "," + utils.quote("PbLapTime"), new GLScript.unionVal(elem.personalBestLapTime, utils.quote(""), GLScript.typVal.num));
                val.setVars.Set(i.ToString() + "," + utils.quote("Pos"), new GLScript.unionVal(elem.pos, utils.quote(""), GLScript.typVal.num));
                for (int j = 0; j < elem.splitTime.Length; j++)
                    val.setVars.Set(i.ToString() + "," + utils.quote("SplitTime" + j.ToString()), new GLScript.unionVal(elem.splitTime[j], utils.quote(""), GLScript.typVal.num));
                val.setVars.Set(i.ToString() + "," + utils.quote("TimePb"), new GLScript.unionVal(0, utils.quote(elem.timePb), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("Total"), new GLScript.unionVal(elem.total, utils.quote(""), GLScript.typVal.num));
                string ListPb = "";
                string sep = "";
                for (int j = 0; j < elem.listPB.Count; j++)
                {
                    ListPb += sep + (elem.listPB[j] as LFSDbs.gripDbs.PbLapEntry).personalBestLapTime;
                    sep = ",";
                }
                val.setVars.Set(i.ToString() + "," + utils.quote("ListPb"), new GLScript.unionVal(0, utils.quote(ListPb), GLScript.typVal.str));

            }

        }
        public void getlisttopdrift(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            bool flagQual = false;
            bool flagNear = false;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            testArgs(ident, "SII", args);
            //Get Qualify flags
            if (int.Parse((string)args[1]) == 1)
                flagQual = true;
            if (int.Parse((string)args[2]) == 1)
                flagNear = true;

            ArrayList list = GetListTopDrift(currInfoPlayer.userName, args[0].ToString(), flagQual, flagNear);

            val.typVal = GLScript.typVal.setOfVar;
            val.setVars = new GLScript.SetOfVars();
            for (int i = 0; i < list.Count; i++)
            {
                LFSDbs.driftDbs.DriverLapEntry elem = (LFSDbs.driftDbs.DriverLapEntry)list[i];
                val.setVars.Set(i.ToString() + "," + utils.quote("UserName"), new GLScript.unionVal(0, utils.quote(elem.userName), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("NickName"), new GLScript.unionVal(0, utils.quote(elem.nickName), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("CName"), new GLScript.unionVal(0, utils.quote(elem.carName), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("DatePb"), new GLScript.unionVal(0, utils.quote(elem.datePb), GLScript.typVal.str));
                string sgroup = "";
                if (elem.group != -1)
                {
                    sgroup = ((char)(elem.group + 65)).ToString();
                }
                val.setVars.Set(i.ToString() + "," + utils.quote("DriftPoints"), new GLScript.unionVal(elem.driftPoints, utils.quote(""), GLScript.typVal.num));
                val.setVars.Set(i.ToString() + "," + utils.quote("Group"), new GLScript.unionVal(0, utils.quote(sgroup), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("Pos"), new GLScript.unionVal(elem.pos, utils.quote(""), GLScript.typVal.num));
            }
        }

        public void getlisttopuser(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            bool flagNear = false;
            bool flagDesc = false;

            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            testArgs(ident, "SSSS", args);

            string key = args[0].ToString();
            flagDesc = false;

            if (args[1].ToString().ToLower() == "desc")
                flagDesc = true;
            if (int.Parse((string)args[2]) == 1)
                flagNear = true;

            ArrayList list = GetListTopUser(key, currInfoPlayer.userName, args[3].ToString(), flagNear, flagDesc);

            val.typVal = GLScript.typVal.setOfVar;
            val.setVars = new GLScript.SetOfVars();

            for (int i = 0; i < list.Count; i++)
            {
                LFSDbs.storedDbs.DriverLapEntry elem = (LFSDbs.storedDbs.DriverLapEntry)list[i];
                val.setVars.Set(i.ToString() + "," + utils.quote("UserName"), new GLScript.unionVal(0, utils.quote(elem.userName), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("NickName"), new GLScript.unionVal(0, utils.quote(elem.nickName), GLScript.typVal.str));
                val.setVars.Set(i.ToString() + "," + utils.quote("Value"), new GLScript.unionVal(elem.sumNumVal, utils.quote(""), GLScript.typVal.num));
                val.setVars.Set(i.ToString() + "," + utils.quote("Pos"), new GLScript.unionVal(elem.pos, utils.quote(""), GLScript.typVal.num));
            }
        }

        public void privrcm(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            testArgs(ident, "S", args);
            string text = args[0].ToString();
            if (text == "[[TranslateEngine]]")
                text = lfsLang.replaceParmsLangStr(currInfoPlayer.idLang);
            SendMsg("/rcm " + text);
            SendMsg("/rcm_ply " + currInfoPlayer.nickName);
        }
        public void textprivbutton(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            if (args.Count == 9)
                args.Add("");
            testArgs(ident, "SS", args);
            string text = args[1].ToString();
            if (text == "[[TranslateEngine]]")
                text = lfsLang.replaceParmsLangStr(currInfoPlayer.idLang);

            currInfoPlayer.playerBox.update(
                                                args[0].ToString(), // ID du boutton
                                                currInfoPlayer.UCID,
                                                text  // Button Text
            );
            currInfoPlayer.playerBox.show(args[0].ToString(), currInfoPlayer.UCID);
        }
        public void textprivbuttonall(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "SS", args);

            string text = args[1].ToString();
            string newText = "";

            foreach (DictionaryEntry de in listOfPlayers.playersUCID)
            {
                infoPlayer CI = (infoPlayer)de.Value;
                newText = text;
                if (newText == "[[TranslateEngine]]")
                    newText = lfsLang.replaceParmsLangStr(currInfoPlayer.idLang);
                else
                    CI.playerBox.update(
                            args[0].ToString(), // ID du boutton
                            CI.UCID,
                            newText);  // Button Text
                CI.playerBox.show(args[0].ToString(), CI.UCID);
            }
        }
        public void openprivtextbutton(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");

            testArgs(ident, "SIIIIIISSIS", args);
            string text = args[8].ToString();
            if (text == "[[TranslateEngine]]")
                text = lfsLang.replaceParmsLangStr(currInfoPlayer.idLang);

            currInfoPlayer.playerBox.create(args[0].ToString(), // ID du boutton
                                                currInfoPlayer.UCID,
                                                int.Parse(args[1].ToString()),  // X
                                                int.Parse(args[2].ToString()),  // Y
                                                int.Parse(args[3].ToString()),  // Largeur
                                                int.Parse(args[4].ToString()),  // Hauteur
                                                int.Parse(args[5].ToString()),  // Interligne
                                                -1,                              // Sec Visible
                                                int.Parse(args[9].ToString()),  // TypeIn
                                                int.Parse(args[6].ToString()),  // Bstyle
                                                args[7].ToString(),             // Caption
                                                text,            // Button Text
                                                args[10].ToString()             // BackCall
            );
            currInfoPlayer.playerBox.show(args[0].ToString(), currInfoPlayer.UCID);
        }
        public void myconfig(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
            showConfigPlayer(currInfoPlayer);
        }
        public void setuserstoredvalue(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            bool PlayerOnline = false;
            if (args.Count > 2)
            {
                testArgs(ident, "SSS", args);
                infoPlayer storedInfoPlayer;
                storedInfoPlayer = listOfPlayers.getPlayerByUserName((string)args[0]);
                if (storedInfoPlayer != null)
                {
                    PlayerOnline = true;
                    storedSqlDbs.updateRowUser(args[1].ToString(), storedInfoPlayer.userName, storedInfoPlayer.nickName, args[2].ToString(), PlayerOnline, newCfg.varsLapper.StoreOfflineData);
                }
                else
                {
                    if(newCfg.varsLapper.StoreOfflineData == 1)
                    {
                        storedSqlDbs.updateRowUser(args[1].ToString(), (string)args[0], "", args[2].ToString(), PlayerOnline, newCfg.varsLapper.StoreOfflineData);
                    }
                }
            }
            else
            {
                if (currInfoPlayer == null)
                    throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");

                testArgs(ident, "SS", args);
                PlayerOnline = true;
                storedSqlDbs.updateRowUser(args[0].ToString(), currInfoPlayer.userName, currInfoPlayer.nickName, args[1].ToString(), PlayerOnline, newCfg.varsLapper.StoreOfflineData);
            }
        }
        public void getuserstorednum(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            string tempStr;
            if (args.Count > 1)
            {
                testArgs(ident, "SS", args);
                tempStr = storedSqlDbs.retreiveRowUser(args[1].ToString(), args[0].ToString());
            }
            else
            {
                if (currInfoPlayer == null)
                    throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
                testArgs(ident, "S", args);
                tempStr = storedSqlDbs.retreiveRowUser(args[0].ToString(), currInfoPlayer.userName);
            }
            val.typVal = GLScript.typVal.num;
            try
            {
                val.fval = float.Parse(tempStr);
            }
            catch
            {
                val.fval = -1;
            }
            return;

        }
        public void getuserstoredvalue(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            val.typVal = GLScript.typVal.str;
            if (args.Count > 1)
            {
                testArgs(ident, "SS", args);
                val.sval = utils.quote(storedSqlDbs.retreiveRowUser(args[1].ToString(), args[0].ToString()));
            }
            else
            {
                if (currInfoPlayer == null)
                    throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");
                testArgs(ident, "S", args);
                val.sval = utils.quote(storedSqlDbs.retreiveRowUser(args[0].ToString(), currInfoPlayer.userName));
            }
        }
        public void openglobalbutton(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (args.Count == 9)
                args.Add("");
            testArgs(ident, "SIIIIIIISS", args);
            listOfPlayers.globalButtonMessage(args[0].ToString(),
                                                int.Parse(args[1].ToString()),
                                                int.Parse(args[2].ToString()),
                                                int.Parse(args[3].ToString()),
                                                int.Parse(args[4].ToString()),
                                                int.Parse(args[5].ToString()),
                                                int.Parse(args[6].ToString()),
                                                0,
                                                int.Parse(args[7].ToString()),
                                                "",
                                                args[8].ToString(),
                                                args[9].ToString()
            );
        }
        public void globalrcm(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);

            string newText = "";
            string text = args[0].ToString();
            foreach (DictionaryEntry de in listOfPlayers.playersUCID)
            {
                currInfoPlayer = (infoPlayer)de.Value;
                if (text == "[[TranslateEngine]]")
                    newText = lfsLang.replaceParmsLangStr(currInfoPlayer.idLang);
                else
                    newText = text;
                SendMsg("/rcm " + newText);
                SendMsg("/rcm_ply " + currInfoPlayer.nickName);
            }
        }
        public void closeglobalbutton(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            listOfPlayers.globalButtonClose(args[0].ToString());
        }
        public void http(GLScript.unionVal val, ArrayList args)
        {
            int PlyUCID;
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            if (args.Count == 1)
            {
                if (currInfoPlayer == null)
                {
                    PlyUCID = 0;
                }
                else
                {
                    PlyUCID = currInfoPlayer.UCID;
                }

                objWebCmd.sendWebCmd(PlyUCID, args[0].ToString());
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("ERROR on Function: '" + ident + "', Incorrect number of parameters");
            }
        }
        public void moveusertogroup(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "SS", args);
            uGroup.addUser(args[0].ToString(), args[1].ToString());
        }
        public void getlistofusersgroup(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            val.clear();
            val.typVal = GLScript.typVal.str;
            val.typArray = true;
            string[] arRet = uGroup.listOfUsersGroup(args[0].ToString());
            for (int i = 0; i < arRet.Length; i++)
                val.add(utils.quote(arRet[i]));
            val.strSort();
            val.add(utils.quote(""));
        }
        public void getlistofplayerbuttons(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            testArgs(ident, "S", args);
            val.clear();
            val.typVal = GLScript.typVal.str;
            val.typArray = true;
            string userName = args[0].ToString();
            currInfoPlayer = listOfPlayers.getPlayerByUserName(userName);
            if (currInfoPlayer == null)
            {
                throw new GLScript.GLApp.GLScriptException("Player name " + (string)args[0] + " in function " + ident + " is not a player");
            }
            string[] lob = currInfoPlayer.playerBox.listOfbutton();
            if (lob.Length == 0)
                val.add(utils.quote(""));
            for (int i = 0; i < lob.Length; i++)
                val.add(utils.quote(lob[i]));
            val.strSort();
        }
        public void usergroupfromfile(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "SS", args);
            uGroup.clear(args[0].ToString());
            uGroup.addUserFromFile(args[0].ToString(), newCfg.varsLapper.WorkingDir + "/" + args[1].ToString());
        }
        public void usergrouptofile(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "SS", args);
            uGroup.addUserToFile(args[0].ToString(), newCfg.varsLapper.WorkingDir + "/" + args[1].ToString());
        }
        public void removeuserfromgroup(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "SS", args);
            uGroup.removeUser(args[0].ToString(), args[1].ToString());
        }
        public void cleargroup(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            uGroup.clear(args[0].ToString());
        }
        public void userisserveradmin(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            val.typVal = GLScript.typVal.num;
            if (currInfoPlayer.isServerAdmin == true)
                val.fval = 1;
            else
                val.fval = 0;
        }
        public void userisadmin(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            val.typVal = GLScript.typVal.num;
            uGroup.clear("admin");
            uGroup.addUserFromFile("admin", newCfg.varsLapper.WorkingDir + "/" + newCfg.varsLapper.AdminFile);
            if (uGroup.userExist("admin", args[0].ToString()) || currInfoPlayer.UCID == 0 || currInfoPlayer.isServerAdmin == true)
                val.fval = 1;
            else
                val.fval = 0;
        }
        public void useringroup(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "SS", args);
            val.typVal = GLScript.typVal.num;
            if (uGroup.userExist(args[0].ToString(), args[1].ToString()))
                val.fval = 1;
            else
                val.fval = 0;
        }
        public void getusergrippb(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            val.typVal = GLScript.typVal.num;
            val.fval = gripSqlDbs.retreivePB(args[0].ToString(), args[0].ToString(), args[1].ToString(), args[2].ToString());
        }
        public void getuserdriftpb(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            val.typVal = GLScript.typVal.num;
            val.fval = (float)driftSqlDbs.retreiveDriftPoint(args[0].ToString(), args[0].ToString(), args[1].ToString(), args[2].ToString());
        }
        public void setstoredvalue(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "SS", args);
            storedSqlDbs.updateRow(args[0].ToString(), args[1].ToString());
        }
        public void getstoredvalue(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            val.typVal = GLScript.typVal.str;
            val.sval = utils.quote(storedSqlDbs.retreiveRow(args[0].ToString()));
        }
        public void getstorednum(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            string tempStr;
            tempStr = storedSqlDbs.retreiveRow(args[0].ToString());
            val.typVal = GLScript.typVal.num;
            try
            {
                val.fval = float.Parse(tempStr);
            }
            catch
            {
                val.fval = -1;
            }
            return;
        }

        //PlayerDelayedCommands
        public void playerdelayedcommand(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer;
            string ident = val.nameFunction;
            string idTask = "";
            int SecDelay = 0;
            string Player = "";
            string SubCallback = "";
            try {
                //Get vars
                if (args.Count == 4)
                {
                    Player = args[0].ToString();
                    SecDelay = int.Parse(args[2].ToString());
                    idTask = args[1].ToString();
                    SubCallback = args[3].ToString();

                    //GetPlayerInfo
                    currInfoPlayer = listOfPlayers.getPlayerByUserName(Player);

                    if (currInfoPlayer == null)
                        throw new GLScript.GLApp.GLScriptException("ERROR on Function '" + ident + "': Cannot execute playerdelayedcommand, '" + Player + "' does not exist.");

                    if ((idTask != "") && (SubCallback != ""))
                        currInfoPlayer.tasks.Add(new Task("PlyDelayed_" + idTask, SubCallback, System.DateTime.Now + new System.TimeSpan(0, 0, SecDelay)));
                    else
                        throw new GLScript.GLApp.GLScriptException("ERROR on Function '" + ident + "': Cannot execute playerdelayedcommand, parameters are wrong or empty");

                }
                else
                {
                    throw new GLScript.GLApp.GLScriptException("Cannot start playerdelayedcommand, incorrect number of parameters");
                }
            }
            catch
            {
                throw new GLScript.GLApp.GLScriptException("ERROR on Function '" + ident + "': function unexpectedly stopped working");
            }
        }

        public void removeplayerdelayedcommand(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer;
            string ident = val.nameFunction;
            string idTask = "";
            string Player = "";
            try
            {
                if (args.Count == 2)
                {
                    Player = args[0].ToString();
                    idTask = "PlyDelayed_" + args[1].ToString();

                    //GetPlayerInfo
                    currInfoPlayer = listOfPlayers.getPlayerByUserName(Player);

                    if (currInfoPlayer == null)
                        throw new GLScript.GLApp.GLScriptException("ERROR on Function '" + ident + "': Cannot execute removeplayerdelayedcommand, '" + Player + "' does not exist.");

                    if (args[1].ToString() != "")
                    {
                        for (int i = currInfoPlayer.tasks.Count - 1; i >= 0; i--)
                        {
                            //Remove task from current player
                            if ((currInfoPlayer.tasks[i] as Task).idTask == idTask)
                            {
                                currInfoPlayer.tasks.RemoveAt(i);
                            }
                        }
                    }
                }
                else
                {
                    throw new GLScript.GLApp.GLScriptException("ERROR on Function '" + ident + "': Cannot execute removeplayerdelayedcommand, incorrect number of parameters");
                }
            }
            catch
            {
                throw new GLScript.GLApp.GLScriptException("ERROR on Function '" + ident + "': function unexpectedly stopped working");
            }
        }

        //Private Delayed commands.
        public void removeprivdelayedcommand(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            testArgs(ident, "S", args);

            //Get to get info from Player 
            try
            {
                if (currInfoPlayer == null)
                    throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");

                if (currInfoPlayer.userName != "")
                {
                    string idTask = "delayed_" + (string)args[0];
                    for (int i = currInfoPlayer.tasks.Count - 1; i >= 0; i--)
                    {
                        //Remove task from current player
                        if ((currInfoPlayer.tasks[i] as Task).idTask == idTask)
                        {
                            currInfoPlayer.tasks.RemoveAt(i);
                        }
                    }
                }
                else
                {
                    throw new GLScript.GLApp.GLScriptException("Function " + ident + " abort: Player does not exist");
                }
            }
            catch
            {

            }
        }
        public void privdelayedcommand(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            string idTask = "";

            if (args.Count == 3)
            {
                testArgs(ident, "SIS", args);
                idTask = args[0].ToString();
                args.RemoveAt(0);
            }

            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, not a player event");

            testArgs(ident, "IS", args);
            currInfoPlayer.tasks.Add(new Task("delayed_" + idTask, args[1].ToString(), System.DateTime.Now + new System.TimeSpan(0, 0, int.Parse(args[0].ToString()))));

        }

        //Host Delayed commands.
        public void removehostdelayedcommand(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = listOfPlayers.getPlayerByUCID(0);
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            try
            {
                if (currInfoPlayer == null)
                    throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, no valid host found");

                string idTask = "delayed_" + (string)args[0];
                for (int i = currInfoPlayer.tasks.Count - 1; i >= 0; i--)
                {
                    if ((currInfoPlayer.tasks[i] as Task).idTask == idTask)
                        currInfoPlayer.tasks.RemoveAt(i);
                }
            }
            catch
            {

            }
        }
        public void hostdelayedcommand(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = listOfPlayers.getPlayerByUCID(0);
            string ident = val.nameFunction;
            string idTask = "";
            if (args.Count == 3)
            {
                testArgs(ident, "SIS", args);
                idTask = args[0].ToString();
                args.RemoveAt(0);
            }
            if (currInfoPlayer == null)
                throw new GLScript.GLApp.GLScriptException("You can't use " + ident + " in this context, no valid host found");
  
                    testArgs(ident, "IS", args);
                    currInfoPlayer.tasks.Add(new Task("delayed_" + idTask, args[1].ToString(), System.DateTime.Now + new System.TimeSpan(0, 0, int.Parse(args[0].ToString()))));
        }


        //Global Delayed commands.
        public void removedelayedcommand(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            string idTask = "delayed_" + (string)args[0];
            for (int i = Tasks.Count - 1; i >= 0; i--)
            {
                if ((Tasks[i] as Task).idTask == idTask)
                    Tasks.RemoveAt(i);
            }
        }
        public void delayedcommand(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            string idTask = "";
            if (args.Count == 3)
            {
                testArgs(ident, "SIS", args);
                idTask = args[0].ToString();
                args.RemoveAt(0);
            }
            testArgs(ident, "IS", args);
            Tasks.Add(new Task("delayed_" + idTask, args[1].ToString(), System.DateTime.Now + new System.TimeSpan(0, 0, int.Parse(args[0].ToString()))));

        }
        public void getlongtrackname(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            val.typVal = GLScript.typVal.str;
            val.sval = utils.quote(UTILS.utils.getLongTrackName(args[0].ToString()));
        }
        public void getlengthtrack(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            val.typVal = GLScript.typVal.num;
            if (args.Count > 0)
            {
                testArgs(ident, "S", args);
                val.fval = utils.getLenTrack(args[0].ToString());
            }
            else
            {
                val.fval = utils.getLenTrack(currState.ShortTrackName);
            }
        }
        public void getgrouptrack(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            val.typVal = GLScript.typVal.str;
            val.sval = utils.quote(UTILS.utils.getGroupTrack(args[0].ToString()));
        }
        public void getexttrack(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            val.typVal = GLScript.typVal.str;
            val.sval = utils.quote(UTILS.utils.getExtTrack(args[0].ToString()));
        }
        public void removescheduleaction(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            testArgs(ident, "S", args);
            string idTask = (string)args[0];
            for (int i = Tasks.Count - 1; i >= 0; i--)
            {
                if ((Tasks[i] as Task).idTask == idTask)
                    Tasks.RemoveAt(i);
            }
        }
        public void registerscheduleaction(GLScript.unionVal val, ArrayList args)
        {
            string ident = val.nameFunction;
            string idTask = "";
            string strCmd = "";
            string strCron = "";
            bool execute = true;
            if (args.Count == 2)
            {
                testArgs(ident, "SS", args);
                strCron = (string)args[0];
                strCmd = (string)args[1];
                if (strCmd == "")
                {
                    execute = false;
                }
            }
            else if (args.Count == 3)
            {
                testArgs(ident, "SSS", args);
                idTask = (string)args[0];
                strCron = (string)args[1];
                strCmd = (string)args[2];
                if ((idTask == "") || (strCmd == ""))
                {
                    execute = false;
                }
            }
            if (execute == true)
            {
                string[] cronTimer = strCron.ToString().Split(':');
                for (int i = 0; i < cronTimer.Length; i++)
                {
                    Tasks.Add(new Task(idTask, strCmd, cronTimer[i]));
                }
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("Error on " + ident + " : one or more of the parameter values are incorrect");
            }
        }
        public void removenodeaction(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            testArgs(ident, "SS", args); // ident Task, track
            listOfNodeEvent.Remove(args[0].ToString(), args[1].ToString());
        }
        public void registernodeaction(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            string idTask = "";
            if (args.Count == 5)
            {
                testArgs(ident, "SSISS", args);
                idTask = args[0].ToString();
                args.RemoveAt(0);
            }
            testArgs(ident, "SISS", args);
            listOfNodeEvent.Add(idTask, args[0].ToString(), int.Parse(args[1].ToString()), args[2].ToString(), args[3].ToString());
        }
        public void registerzoneaction(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;

            //Set variables 
            string idTask = args[0].ToString();
            string shorttrackname = args[1].ToString();

            //X value
            int X = 0;
            if (args[2].ToString().Contains("."))
            {
                string[] zone_X_Value = args[2].ToString().Split('.');
                X = int.Parse(zone_X_Value[0].ToString());
            }
            else
            {
                X = int.Parse(args[2].ToString());
            }

            //Y value
            int Y = 0;
            if (args[3].ToString().Contains("."))
            {
                string[] zone_Y_Value = args[3].ToString().Split('.');
                Y = int.Parse(zone_Y_Value[0].ToString());
            }
            else
            {
                Y = int.Parse(args[3].ToString());
            }
            //Width of the zone value
            int dist = 0;
            if (args[4].ToString().Contains("."))
            {
                string[] zone_Y_Value = args[4].ToString().Split('.');
                dist = int.Parse(zone_Y_Value[0].ToString());
            }
            else
            {
                dist = int.Parse(args[4].ToString());
            }

            string EnterZone = args[5].ToString();
            string LeaveZone = args[6].ToString();

            listOfZoneEvent.Add(idTask, shorttrackname, X, Y, dist, EnterZone, LeaveZone);
        }
        public void removezoneaction(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();

            string ident = val.nameFunction;
            testArgs(ident, "SS", args); // ident Task, track

            //Set variables
            string idTask = args[0].ToString();
            string shorttrackname = args[1].ToString();

            listOfZoneEvent.Remove(idTask, shorttrackname);
        }
        public void reload(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            this.TermProg = true;
            this.RestartProg = true;
        }
        public void crash(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = null;
            Console.WriteLine(currInfoPlayer.userName);
        }

        public void TestFunction(GLScript.unionVal val, ArrayList args)
        {
            infoPlayer currInfoPlayer = newCfg.getCurrInfoPlayer();
            string ident = val.nameFunction;
            string text = args[0].ToString();
      
            SendMsgToConnection(currInfoPlayer.UCID, text,0);
            //SendMsg(args[0].ToString());
        }
    }

}