public int LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                // Marshal the KeyboardHookStruct data from the callback lParam
                KBDLLHOOKSTRUCT keyboardLLHookStruct = (KBDLLHOOKSTRUCT)
                                                       Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));


                Keys            vkCode     = (Keys)keyboardLLHookStruct.vkCode;
                KeyboardMessage wmKeyboard = (KeyboardMessage)wParam; // Get the keyboard WM from the wParam parameter


                typeOfPressedKey = InputUtils.GetKeyType(vkCode);//Gets a type of pressed key

                TriggerFlagsInitialization(typeOfPressedKey, vkCode, wmKeyboard);

                if (typeOfPressedKey == "system")
                {
                    for (int i = 0; i < InputUtils.systemKeys.Length; i++)// Have to check every possible trigger key
                    {
                        TriggerFlags(vkCode, InputUtils.ReturnSystemKey(i), wmKeyboard, i);
                    }
                }


                if (wmKeyboard == keyUp || wmKeyboard == keyUpSys)
                {
                    mainController.LastKeyPressed_LiftOff(vkCode);
                }

                if (wmKeyboard == keyDown || wmKeyboard == keyDownSys)
                {
                    try
                    {
                        ExeUtils.AsyncGetExeID();
                    }
                    catch (Exception)
                    {
                        /* In case of failure keeps old one */
                    }

                    /* Sets up timer and stopwatch. Can't time timer */
                    if (!userLevelTimer.Enabled)
                    {
                        userLevelTimer.Enabled = true;
                        userLevelTimer.Start();
                        timer2.Start();
                    }

                    if (!inputStopWatch.IsRunning)
                    {
                        inputStopWatch.Start();
                    }
                    int timePassed = (int)inputStopWatch.ElapsedMilliseconds;

                    if (ExeUtils.isTrackable)
                    {
                        mainController.AddToInputBuffer(vkCode, timePassed, ExeUtils.exeID, typeOfPressedKey);
                    }

                    switch (typeOfPressedKey)
                    {
                    case "system":
                        /* in case there's stuff to do */
                        break;

                    case "panic":
                        bufferObj.Clear();
                        WriteAndClearTuple_nTimer();
                        break;

                    case "rule":
                        if (bufferObj.Count() > 0)
                        {
                            int key = 0;     /* WHEN BACKSPACE */
                            if (vkCode == Keys.Delete)
                            {
                                key = 1;     /* WHEN DELETE */
                            }

                            if (rules.OneWordValidation(vkCode, bufferObj))     /* Checks if space wasn't deleted. If it was just save to db */
                            {
                                SortTupleList();
                                WriteAndClearTuple_nTimer();
                            }

                            if (bufferObj.ValidateBounds(key))     /*  */
                            {
                                preDeleteBuffer.Add(bufferObj.GetInputForMistakes(vkCode));
                                tupleBuffer = rules.RuleKey(vkCode, tupleBuffer, bufferObj, (int)normalInputSW.ElapsedMilliseconds);
                                bufferObj.SendRuleKeys(vkCode);
                                bufferObj.ruleKeyPressed = true;
                            }
                            else
                            {
                                WriteAndClearTuple_nTimer();
                            }
                        }
                        break;

                    case "pointer":
                        string triggerFlag = TriggerFlags_Enabled_Keys();
                        if (triggerFlag != "Sys")
                        {
                            if (triggerFlag == "None")
                            {
                                bufferObj.SendRuleKeys(vkCode);
                            }
                            else if (triggerFlag == "Ctrl")
                            {
                                bufferObj.SendRuleKeys(vkCode, true);
                            }
                            WriteAndClearTuple();
                        }
                        break;

                    case "normal":

                        if (!flagArray.Contains(true))
                        {
                            if (bufferObj.ruleKeyPressed == true)
                            {
                                SortTupleList();

                                if (InputUtils.seperatorKeys.Contains(vkCode))    //space and rest of the buch
                                {
                                    WriteAndClearTuple_nTimer();
                                    Action(vkCode, wmKeyboard);
                                }
                                else
                                {
                                    string replaceWith = InputUtils.GetCharsFromKeys(vkCode);

                                    rules.NormalKey(tupleBuffer, replaceWith, (int)normalInputSW.ElapsedMilliseconds);
                                    Action(vkCode, wmKeyboard);
                                }
                            }
                            else
                            {
                                Action(vkCode, wmKeyboard);
                            }
                        }
                        else
                        {
                            WriteAndClearTuple_nTimer();
                        }
                        if (normalInputSW.IsRunning)
                        {
                            normalInputSW.Restart();
                        }
                        else
                        {
                            normalInputSW.Start();
                        }
                        break;

                    default:

                        break;
                    }
                    userLevelTimer.Stop();
                    userLevelTimer.Start();
                    inputStopWatch.Restart();
                }
            }
            return(WindowsAPI.CallNextHookEx(hGlobalLLKeyboardHook, nCode, wParam, lParam));
        }