/// <summary>
        /// Constructor for the Game.
        /// </summary>
        public TetrisGameRunner()
            : base()
        {
            graphics = new GraphicsDeviceManager(this);
            IsMouseVisible = true;
            Content.RootDirectory = "Content";
            handler = new InputHandler();
            original = null;
            Myself = Process.GetCurrentProcess();
            light = new BlendState();
            light.ColorBlendFunction = BlendFunction.Add;
            light.ColorSourceBlend = Blend.DestinationColor;
            light.ColorDestinationBlend = Blend.One;
            editor = new WorldEditor();
            classic = new MainMenuButton("Play Classic");
            story = new MainMenuButton("Beta Story Mode");
            story.ModifyY(51 * 4);
            options = new MainMenuButton("Options");
            options.ModifyY(51*2);
            maker = new MainMenuButton("Make Levels");
            maker.ModifyY(51*3);
            anyLevel = new MainMenuButton("Play Any Level");
            anyLevel.ModifyY(51);
            exit = new MainMenuButton("Exit");
            exit.ModifyY(51 * 5);

            package = new LevelPack();
            package.AddLevel("Volcano");
            package.AddLevel("Chef");

            package.AddLevel("RaiseDaRoof");

            package.AddLevel("School");

            package.AddLevel("Vault");

            package.AddLevel("TheMugging");

            package.AddLevel("CabinetDiver");

            package.AddLevel("Programmer");
            package.UnlockUpTo(1);

            cache = new MainMenuButton("Cache Off");

            pieceMode = new MainMenuButton("Piece Mode A");
            pieceMode.ModifyY(51);
            back = new MainMenuButton("Back To Menu");
            back.ModifyY(51 * 2);

            Save = new MainMenuButton("Save");
            Load = new MainMenuButton("Load");
            Load.ModifyY(51);

            graphics.PreferredBackBufferHeight = VirtualHeight;
            graphics.PreferredBackBufferWidth = VirtualWidth;

            classicLink = new TajLevelLinker();
            classicLink.OnStart("ClassicTetris 0 %Score \"Score:`0\" SetText");
            classicLink.SetRowCleared("\"Score:`\" $Score 1 + string + SetText $Score 1 + %Score del");

            /*
            TajParser p = new TajParser();
            p.Parse("\"Hello`World`\" 10 string +");
            p.Parse("10 20 + 10 * %Hello");
            p.Parse("$Hello $Hello + %Corn");
            p.Parse("$Corn $Corn * $Corn + %g");
            p.Parse("\"Hello`world`I`am`a`computer.`\" %Computer");
            SaveFileSystem.SaveObjectToFile(p, "Heh.taj");
            p = SaveFileSystem.LoadObjectFromFile<TajParser>("Heh.taj", new GameLoader());

            Console.Beep();
            */
        }
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if(primitiveDrawer == null)
            {
                primitiveDrawer = new PrimitiveDrawer(GraphicsDevice.Viewport.TitleSafeArea.Width, GraphicsDevice.Viewport.TitleSafeArea.Height);
                primitiveDrawer.Setup(GraphicsDevice, 0, 0);
                dragDropInterface = new DragDropInterface(VirtualWidth, VirtualHeight);

            }

            handler.Update();

            if(handler.CheckPressedKey(Keys.LeftShift) && handler.CheckPressedKey(Keys.Escape))
            {
                state = 0;
            }

            currentMouseX = handler.GetMouseX();
            currentMouseY = handler.GetMouseY();

            mainMenu.Update(handler);

            if(state == 2)
            {

                if (handler.CheckJustPressedKey(Keys.Escape))
                {
                    state = 7;
                }

                editor.Update(handler);
                if(editor.Finished())
                {
                    string fileName = editor.GetFileName();
                    string safeFileName = editor.GetSafeFileName();
                    dragDropInterface.SetFile(fileName, safeFileName);
                    state = 3;
                }
            }
            else
            if(state ==4)
            {
                cache.Update(handler);
                pieceMode.Update(handler);
                back.Update(handler);
                optionsMenu.Update(handler);
                if (handler.CheckMouseIn(back) && handler.CheckLeftMouseJustPressed())
                {
                    state = 0;
                }

                if (handler.CheckMouseIn(pieceMode) && handler.CheckLeftMouseJustPressed())
                {
                    pieceModeA = !pieceModeA;

                    pieceMode.SetText((pieceModeA) ? "Piece Mode B" : "Piece Mode A");
                    ClassicTetrisGame.SetPieceMode(pieceModeA);
                }
            }
            else
            if (state == 0)
            {
                classic.Update(handler);
                maker.Update(handler);
                story.Update(handler);

                anyLevel.Update(handler);
                options.Update(handler);
                exit.Update(handler);

                if (handler.CheckMouseIn(options) && handler.CheckLeftMouseJustPressed())
                {
                    state = 4;
                    //classicLink.CreateGame("TajLevel.taj");
                }

                if (handler.CheckMouseIn(story) && handler.CheckLeftMouseJustPressed())
                {
                    string[] levels = package.GetProtectedLevels();

                    this.levels = new MainMenuButton[levels.Length];

                    for (int i = 0;i < levels.Length; i++)
                    {
                        this.levels[i] = new MainMenuButton(levels[i]);
                        this.levels[i].ModifyY(51 * i);
                    }

                        state = 9;
                }

                if (handler.CheckMouseIn(anyLevel) && handler.CheckLeftMouseJustPressed())
                {
                    string[] levelsN = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/TajTetris/LevelPacks");

                    List<string> levels = new List<string>();
                    for (int i = 0;i < levelsN.Length; i++)
                    {
                        if(levelsN[i].EndsWith(".taj"))
                        levels.Add(levelsN[i]);
                    }

                    this.levels = new MainMenuButton[levels.Count];

                    for (int i = 0;i < levels.Count;i++)
                    {
                        this.levels[i] = new MainMenuButton(Path.GetFileNameWithoutExtension(levels[i]));
                        this.levels[i].ModifyY(51 * i);
                    }

                    state = 8;
                }

                if (handler.CheckMouseIn(classic) && handler.CheckLeftMouseJustPressed())
                {
                    classicLink.CreateGame("TajLevel.taj");
                    Logger.WriteLine("Started new Classic Game.");
                    state = 1;
                }

                if (handler.CheckMouseIn(maker) && handler.CheckLeftMouseJustPressed())
                {
                    state = 2;
                }

                if (handler.CheckMouseIn(exit) && handler.CheckLeftMouseJustPressed())
                {
                    this.Exit();
                }
            }
            else
            if(state == 1)
            {

                classicLink.Update(handler);

                if(handler.CheckJustPressedKey(Keys.Escape))
                {
                    state = 5;
                }
            }
            else
            if(state == 3)
            {
                dragDropInterface.Update(handler);
            }
            else
               //dragDropInterface.Update(handler);

            if (state == 5 || state == 12 || state == 13)
            {
                Save.Update(handler);
                Load.Update(handler);
                back.Update(handler);

                if (handler.CheckMouseIn(back) && handler.CheckLeftMouseJustPressed())
                {
                    state = 0;
                }

                if (state == 5)
                {
                    if (handler.CheckMouseIn(Save) && handler.CheckLeftMouseJustPressed())
                    {

                        state = 1;
                        classicLink.SetFullSave(true);

                        Logger.WriteLine("Saved Classic Game.");
                        SaveFileSystem.SaveObjectToFile(classicLink, "ClassicGame.tajSave");
                    }

                    if (handler.CheckMouseIn(Load) && handler.CheckLeftMouseJustPressed())
                    {
                        classicLink = SaveFileSystem.LoadObjectFromFile<TajLevelLinker>("ClassicGame.tajSave", new GameLoader());

                        Logger.WriteLine("Loaded Classic Game.");
                        state = 1;
                    }

                    if (handler.CheckJustPressedKey(Keys.Escape))
                    {
                        state = 1;
                    }

                }

                if (state == 12)
                {
                    if (handler.CheckMouseIn(Save) && handler.CheckLeftMouseJustPressed())
                    {

                        state = 11;
                        freePlayLink.SetFullSave(true);
                        Logger.WriteLine("Saved Free Play Game.");
                        SaveFileSystem.SaveObjectToFile(freePlayLink, "FreePlayGame.tajSave");
                    }

                    if (handler.CheckMouseIn(Load) && handler.CheckLeftMouseJustPressed())
                    {
                        freePlayLink = SaveFileSystem.LoadObjectFromFile<TajLevelLinker>("FreePlayGame.tajSave", new GameLoader());

                        Logger.WriteLine("Loaded Freeplay Game.");
                        state = 11;
                    }

                    if (handler.CheckJustPressedKey(Keys.Escape))
                    {
                        state = 11;
                    }

                }

                if (state == 13)
                {
                    if (handler.CheckMouseIn(Save) && handler.CheckLeftMouseJustPressed())
                    {

                        state = 10;
                        classicLink.SetFullSave(true);

                        Logger.WriteLine("Saved Story Game.");
                        SaveFileSystem.SaveObjectToFile(classicLink, "StoryGame.tajSave");
                    }

                    if (handler.CheckMouseIn(Load) && handler.CheckLeftMouseJustPressed())
                    {
                        classicLink = SaveFileSystem.LoadObjectFromFile<TajLevelLinker>("StoryGame.tajSave", new GameLoader());

                        Logger.WriteLine("Loaded Story Game.");
                        state = 10;
                    }

                    if (handler.CheckJustPressedKey(Keys.Escape))
                    {
                        state = 10;
                    }

                }
            }

            else if (state ==7)
            {
                back.Update(handler);
                if (handler.CheckJustPressedKey(Keys.Escape))
                {
                    state = 2;
                }
                if (handler.CheckMouseIn(back) && handler.CheckLeftMouseJustPressed())
                {
                    state = 0;
                }

            }
            else if (state == 8)
            {
                optionsMenu.Update(handler);

                if (handler.CheckJustPressedKey(Keys.Escape))
                {
                    state = 0;
                }

                foreach (MainMenuButton b in levels)
                {
                    b.Update(handler);
                    b.ModifyY((int)(handler.LeftMouseDraggedBy().Y / 40.0f));

                    if (handler.CheckMouseIn(b) && handler.CheckLeftMouseJustPressed())
                    {

                            freePlayLink = SaveFileSystem.LoadObjectFromFile<TajLevelLinker>("LevelPacks/" + b.GetText() + ".taj", new GameLoader());
                            state = 11;
                            break;
                    }
                }
            }
            else if (state == 9)
            {
                optionsMenu.Update(handler);

                if(handler.CheckJustPressedKey(Keys.Escape))
                {
                    state = 0;
                }

               foreach(MainMenuButton b in levels)
               {
                   b.Update(handler);
                   b.ModifyY((int)(handler.LeftMouseDraggedBy().Y / 40.0f));

                   if (handler.CheckMouseIn(b) && handler.CheckLeftMouseJustPressed())
                   {
                       if(b.GetText() != "Locked")
                       {
                           storyLink = SaveFileSystem.LoadObjectFromFile<TajLevelLinker>("LevelPacks/" + b.GetText() + ".taj", new GameLoader());
                           storyLink.SetLevelPack(package);
                           state = 10;
                           break;
                       }
                   }
               }

            } else if (state == 10)
            {
                if (handler.CheckJustPressedKey(Keys.Escape))
                {
                    state = 13;
                }
                storyLink.Update(handler);

            }
            else if (state == 11)
            {

                if (handler.CheckJustPressedKey(Keys.Escape))
                {
                    state = 12;
                }
                freePlayLink.Update(handler);
            }

            //lnk.Update(handler);
            //tGame.Update(handler);
            base.Update(gameTime);
        }
        private void BuildTajLevelLinker()
        {
            TajLevelLinker tjl = new TajLevelLinker();
            tjl.SetRedCleared((string)variablesToBuild.Peek()["RedCleared"]);
            tjl.SetBlueCleared((string)variablesToBuild.Peek()["BlueCleared"]);
            tjl.SetTealCleared((string)variablesToBuild.Peek()["TealCleared"]);
            tjl.SetYellowCleared((string)variablesToBuild.Peek()["YellowCleared"]);
            tjl.SetPurpleCleared((string)variablesToBuild.Peek()["PurpleCleared"]);
            tjl.SetGreenCleared((string)variablesToBuild.Peek()["GreenCleared"]);
            tjl.SetOrangeCleared((string)variablesToBuild.Peek()["OrangeCleared"]);
            tjl.SetAnyCleared((string)variablesToBuild.Peek()["AnyCleared"]);
            tjl.SetRowCleared((string)variablesToBuild.Peek()["RowCleared"]);

            tjl.OnStart((string)variablesToBuild.Peek()["Start"]);
            tjl.SetFileName((string)variablesToBuild.Peek()["FileName"]);

            buildStack.Push(tjl);
            currentClass.Pop();
            variablesToBuild.Pop();
        }
        private void BuildTajLevelSave()
        {
            TajLevelLinker tjl = new TajLevelLinker();
            tjl.SetRedCleared((string)variablesToBuild.Peek()["RedCleared"]);
            tjl.SetBlueCleared((string)variablesToBuild.Peek()["BlueCleared"]);
            tjl.SetTealCleared((string)variablesToBuild.Peek()["TealCleared"]);
            tjl.SetYellowCleared((string)variablesToBuild.Peek()["YellowCleared"]);
            tjl.SetPurpleCleared((string)variablesToBuild.Peek()["PurpleCleared"]);
            tjl.SetGreenCleared((string)variablesToBuild.Peek()["GreenCleared"]);
            tjl.SetOrangeCleared((string)variablesToBuild.Peek()["OrangeCleared"]);
            tjl.SetAnyCleared((string)variablesToBuild.Peek()["AnyCleared"]);
            tjl.SetRowCleared((string)variablesToBuild.Peek()["RowCleared"]);

            tjl.SetGame((ClassicTetrisGame)variablesToBuild.Peek()["Game"]);
            tjl.SetFlashlight((bool)variablesToBuild.Peek()["Flashlight"]);
            if (variablesToBuild.Peek().ContainsKey("Text"))
                tjl.SetText((String)variablesToBuild.Peek()["Text"]);
            else tjl.SetText("");
            tjl.SetParser((TajParser)variablesToBuild.Peek()["Parser"]);
            tjl.OnStart((string)variablesToBuild.Peek()["Start"]);

            tjl.SetWorld((World)variablesToBuild.Peek()["World"]);
            buildStack.Push(tjl);
            currentClass.Pop();
            variablesToBuild.Pop();
        }
        public void Update(InputHandler inputHandler)
        {
            #region Update Parts
            UpdateMode(inputHandler);
            UpdateElements(inputHandler);
            UpdateScrolling(inputHandler);
            UpdateTextBox(inputHandler);
            UpdateSuggestions(inputHandler);
            #endregion

            if(inputHandler.CheckJustPressedKey(Keys.E) && inputHandler.CheckPressedKey(Keys.D9))
            {
               TajLevelLinker linker = new TajLevelLinker();
               foreach(LooseDragDropLink link in elements)
                {
                    if(link  != null)
                    {
                        if(link.GetElement() is CodeDragDropHolder)
                        {
                            CodeDragDropHolder holder = ((CodeDragDropHolder)link.GetElement());

                            // "Code", "If", "Else", "EndIf", "Start", "Cleared Row", "Cleared Red", "Cleared Blue", "Cleared Teal", "Cleared Purple", "Cleared Orange", "Cleared Yellow", "Cleared Green", "Cleared Any Color"
                            switch(holder.GetMode())
                            {
                            case 4:
                                linker.OnStart(holder.GetCode());
                                break;
                            case 5 :
                                linker.SetRowCleared(holder.GetCode());
                                break;
                            case 6:

                                linker.SetRedCleared(holder.GetCode());
                                break;
                            case 7:

                                linker.SetBlueCleared(holder.GetCode());
                                break;
                            case 8:

                                linker.SetTealCleared(holder.GetCode());
                                break;
                            case 9:
                                linker.SetPurpleCleared(holder.GetCode());
                                break;
                            case 10:

                                linker.SetOrangeCleared(holder.GetCode());
                                break;
                            case 11:

                                linker.SetYellowCleared(holder.GetCode());
                                break;
                            case 12:
                                linker.SetGreenCleared(holder.GetCode());
                                break;
                            case 13:
                                linker.SetAnyCleared(holder.GetCode());
                                break;
                            }

                        }
                    }
                }
               linker.CreateGame(fileName);
               linker.SetFullSave(true);
               SaveFileSystem.SaveObjectToFile(linker, "LevelPacks" + Path.DirectorySeparatorChar + safeFileName);
            }

            /*
            if(inputHandler.CheckJustPressedKey(Keys.Y))
            {

                TempList list = new TempList();
                list.elements = this.elements.ToArray();

                SaveFileSystem.SaveObjectToFile(list, "Haha.taj");
            }
            */
            //Temporary Code
            if(classManager == null && !test)
            {

                suggestions.Add(new LooseDragDropLink(new StringTextbox()));
                suggestions.Add(new LooseDragDropLink(new NumberTextbox()));
                suggestions.Add(new LooseDragDropLink(new BooleanDragDrop()));
                suggestions.Add(new LooseDragDropLink(new NotBooleanMethod()));
                suggestions.Add(new LooseDragDropLink(new BooleanMethod()));
                suggestions.Add(new LooseDragDropLink(new NumberMethodDragDrop()));
                suggestions.Add(new LooseDragDropLink(new NumberMethod()));
                suggestions.Add(new LooseDragDropLink(new StringMethod()));
                suggestions.Add(new LooseDragDropLink(new SetVariableDragDrop()));
                suggestions.Add(new LooseDragDropLink(new GameCommandDragDrop()));
                suggestions.Add(new LooseDragDropLink(new GetVariableDragDrop()));
                suggestions.Add(new LooseDragDropLink(new CodeTextbox()));
                suggestions.Add(new LooseDragDropLink(new CodeDragDropHolder()));

                test = true;
                //Show New Class Button
            }
        }