public GameManagerController(GameManagerScope scope, UIManagerService uiManager, CreateUIService createUIService,
            ClientSiteManagerService clientSiteManagerService, MessageService messageService)
        {
            myScope = scope;
            myUIManager = uiManager;
            this.createUIService = createUIService;
            myClientSiteManagerService = clientSiteManagerService;
            myMessageService = messageService;
            myScope.Model = new GameManagerModel();
            myScope.Visible = true;
            myClientSiteManagerService.GetGamesByUser(myUIManager.ClientInfo.LoggedInUser.Hash);

            myClientSiteManagerService.OnGetGamesByUserReceived += OnOnGetGamesByUserReceivedFn;
            myClientSiteManagerService.OnDeveloperCreateGameReceived += OnDeveloperCreateGameReceivedFn;
            myClientSiteManagerService.OnDoesGameNameExistReceived += OnDoesGameNameExistReceivedFn;

            myScope.Model.CreateGame += CreateGameFn;
            myScope.Model.DeleteGame += DeleteGameFn;
            myScope.Watch("model.selectedGame",
                () =>
                {
                    if (myScope.Model.SelectedGame == null) return;

                    createUIService.CreateSingleton<GameEditorScope>(GameEditorController.View,
                        (_scope, elem) =>
                        {
                            _scope.Model = new GameEditorModel();
                            _scope.Model.Game = myScope.Model.SelectedGame;
                        });
                    if (!scope.Minimized)
                        scope.Minimize();
                });
        }
        public GameTestEditorController(GameTestEditorScope scope, ClientSiteManagerService clientSiteManagerService, ClientDebugManagerService clientDebugManagerService, MessageService messageService, CreateUIService createUIService)
        {
            this.scope = scope;
            myClientSiteManagerService = clientSiteManagerService;
            this.clientDebugManagerService = clientDebugManagerService;
            myMessageService = messageService;
            myCreateUIService = createUIService;
            this.scope.Visible = false;
            scope.Model.Log = new List<string>();

            this.scope.OnReady += () =>
            {
                this.scope.SwingAway(SwingDirection.Right, true, null);
                this.scope.SwingBack(null);
            };

            this.scope.Model.StartGame = StartGameFn;
            this.scope.Model.DestroyGame = DestroyGameFn;

            this.scope.Model.GameRunning = false;



            this.scope.Watch("model.game", () => { this.scope.Model.UpdateStatus = UpdateStatusType.Dirty; }, true);
            myClientSiteManagerService.OnDeveloperUpdateGameReceived += OnDeveloperUpdateGameReceivedFn;
            this.scope.Model.UpdateStatus = UpdateStatusType.Synced;
            this.scope.Model.UpdateGame = UpdateGameFn;


            clientDebugManagerService.OnGetDebugLog += clientDebugManagerService_OnGetDebugLog;
            clientDebugManagerService.OnGameStarted += (user, roomModel) =>
            {
                this.scope.Model.GameRunning = true;
                this.scope.Model.Room = roomModel;
                if (this.scope.Model.CodeEditor != null)
                    this.scope.Model.CodeEditor.Scope.Model.Room = roomModel;
            };

            this.scope.Model.DebugCode = () =>
                                         {
                                             this.scope.Model.CodeEditor = myCreateUIService.CreateSingleton<DebugGameCodeScope>(DebugGameCodeController.View, (innerScope, elem) =>
                                                                                                                                        {
                                                                                                                                            innerScope.Model = new DebugGameCodeScopeModel();
                                                                                                                                            innerScope.Model.Game = this.scope.Model.Game;
                                                                                                                                            innerScope.Model.Selection = this.scope.Model.Selection;
                                                                                                                                        });
                                         };


            /*
                        Window.SetTimeout(() =>
                                          {
                                              StartGameFn();
                                              scope.Minimize();
                                          }, 250);
            */


        }
        public ActiveLobbyController(ActiveLobbyScope scope, ClientManagerService clientManagerService,CreateUIService createUIService)
        {
            myScope = scope;
            this.clientManagerService = clientManagerService; 
            myCreateUIService = createUIService;
            myScope.Model.ChatLines = new List<ChatMessageRoomModel>();
            myScope.Visible = false;
            myScope.Model.WindowClosed += () =>
                                          {
                                              myScope.SwingAway(SwingDirection.BottomRight, false, null);
                                              clientManagerService.ClientSiteManagerService.LeaveRoom(
                                                  new LeaveRoomRequest(myScope.Model.Room));
                                              myCreateUIService.CreateSingleton(HomeController.View);
                                              myScope.DestroyWindow();
                                          };


            myScope.Model.StartGame += () =>
                                       {
                                           clientManagerService.ClientSiteManagerService.StartGame(new StartGameRequest());
                                       };
            clientManagerService.ClientGameManagerService.OnGameStarted += (user, room) =>
            {
                myCreateUIService.Create(GameController.View);
                //UIWindow.Height = 200;
            };


            myScope.Model.SendChatMessage += () =>
                                             {
                                                 if (myScope.Model.CurrentChatMessage.Trim() == string.Empty)
                                                     return;

                                                 clientManagerService.ClientChatManagerService.SendChatMessage(
                                                     new SendChatMessageModel(myScope.Model.CurrentChatMessage.Trim()));

                                                 myScope.Model.CurrentChatMessage = "";
                                             };

            clientManagerService.ClientSiteManagerService.OnGetRoomInfoReceived += GetRoomInfo;
            clientManagerService.ClientChatManagerService.OnGetChatLines += GetChatLines;
            clientManagerService.ClientChatManagerService.OnGetChatInfo += GetChatInfo;
            myScope.OnReady = () =>
                              {
                                  myScope.SwingAway(SwingDirection.BottomRight, true, null);
                                  PopulateGameRoom(myScope.Model.Room);
                                  myScope.SwingBack(null);
                              };
        }
        public GameEffectsEditorController(GameEffectsEditorScope scope, CreateUIService createUIService)
        {
            myScope = scope;
            this.createUIService = createUIService;
            var effectTypes = new List<EffectType>();

            effectTypes.Add(EffectType.Bend);
            effectTypes.Add(EffectType.Highlight);
            effectTypes.Add(EffectType.Rotate);
            effectTypes.Add(EffectType.StyleProperty);
            scope.Visible = true;

            myScope.Model.EffectTypes = effectTypes;
            myScope.Model.NewEffectType = EffectType.Bend;

            myScope.Model.NewEffectName = "";

            myScope.Model.AddEffect = AddEffectFn;
            myScope.Model.RemoveEffect = RemoveEffectFn;

            myScope.Watch("model.selection.selectedEffect", () =>
                                                            {
                                                                if (myScope.Model.Selection.SelectedEffect != null)
                                                                {
                                                                }
                                                            });


            var effectTesterUI = createUIService.CreateSingleton<EffectTesterControllerScope>(EffectTesterController.View,
                (_scope, elem) =>
                {
                    _scope.Model = new EffectTesterControllerScopeModel();
                    _scope.Model.Game = myScope.Model.Game;
                    _scope.Model.Selection = myScope.Model.Selection;
                });
            myScope.OnClose += effectTesterUI.Destroy;
        }
        public GameLayoutEditorController(GameLayoutEditorScope scope,
            ClientSiteManagerService clientSiteManagerService, MessageService messageService,
            CreateUIService createUIService)
        {
            myScope = scope;
            myClientSiteManagerService = clientSiteManagerService;
            myMessageService = messageService;
            myCreateUIService = createUIService;
            myScope.Visible = true;
            myScope.Model.ToggleGrid = ToggleGridFn;
            myScope.Model.ToggleCards = ToggleCardsFn;
            myScope.Model.AddText = AddTextFn;
            myScope.Model.AddArea = AddAreaFn;
            myScope.Model.AddSpace = AddSpaceFn;
            myScope.Model.RemoveArea = RemoveAreaFn;
            myScope.Model.RemoveSpace = RemoveSpaceFn;
            myScope.Model.RemoveText = RemoveTextFn;
            myScope.Model.OpenScenarios = OpenScenariosFn;
            myScope.Model.Selection.SelectedLayoutPiece = SelectedGameLayoutPiece.None;
            myScope.Watch("model.selection.selectedSpace", () =>
                                                           {
                                                               if (myScope.Model.Selection.SelectedSpace == null)
                                                                   return;
                                                               myScope.Model.Selection.SelectedText = null;
                                                               myScope.Model.Selection.SelectedArea = null;
                                                               myScope.Model.Selection.SelectedLayoutPiece = SelectedGameLayoutPiece.Space;
                                                               myScope.Model.Selection.SelectedCard = null;
                                                           });
            myScope.Watch("model.selection.selectedText", () =>
                                                          {
                                                              if (myScope.Model.Selection.SelectedText == null) return;
                                                              myScope.Model.Selection.SelectedSpace = null;
                                                              myScope.Model.Selection.SelectedArea = null;
                                                              myScope.Model.Selection.SelectedLayoutPiece = SelectedGameLayoutPiece.Text;
                                                          });
            myScope.Watch("model.selection.selectedArea", () =>
                                                          {
                                                              if (myScope.Model.Selection.SelectedArea == null) return;
                                                              myScope.Model.Selection.SelectedText = null;
                                                              myScope.Model.Selection.SelectedSpace = null;
                                                              myScope.Model.Selection.SelectedLayoutPiece = SelectedGameLayoutPiece.Area;
                                                          });
            myScope.Watch("model.game", () => { myScope.Model.UpdateStatus = UpdateStatusType.Dirty; }, true);
            myClientSiteManagerService.OnDeveloperUpdateGameReceived += OnDeveloperUpdateGameReceivedFn;
            myScope.Model.UpdateStatus = UpdateStatusType.Synced;
            myScope.Model.UpdateGame = UpdateGameFn;

            var testgame = myCreateUIService.CreateSingleton<TestGameControllerScope>(TestGameController.View, (_scope, elem) =>
                                                                                                            {
                                                                                                                _scope.Model = new TestGameControllerScopeModel();
                                                                                                                _scope.Model.Game = myScope.Model.Game;
                                                                                                                _scope.Model.Selection = myScope.Model.Selection;
                                                                                                            });
            myScope.OnClose += () =>
                               {
                                   testgame.Destroy();
                                   if (scenario != null)
                                   {
                                       scenario.Destroy();
                                   }
                               };

        }
        public GameController(GameControllerScope scope, ClientGameManagerService clientGameManagerService, GameContentManagerService gameContentManagerService, CreateUIService createUIService)
        {
            this.scope = scope;
            myClientGameManagerService = clientGameManagerService;
            myGameContentManagerService = gameContentManagerService;
            this.createUIService = createUIService;
            /* effectManager.Effects =new List<GameEffectModel>();
             effectManager.Effects.Add(GameEffectsEditorController.makeEffect("bend", EffectType.Bend));
              */
            /*     myClientGameManagerService.OnAskQuestion += (user, gameSendAnswerModel) => {
                                                        PageHandler.QuestionUI.Load(gameSendAnswerModel);
                                                        //alert(JSON.stringify(data));
                                                        PageHandler.TimeTracker.EndTime = new DateTime();
                                                        var time = PageHandler.TimeTracker.EndTime - PageHandler.TimeTracker.StartTime;
                                                      PageHandler.  DebugUI.lblHowFast.Text = ( "how long: " + time ); 
                                                    }; */

            myClientGameManagerService.OnAskQuestion+= (user, gameSendAnswerModel) =>
                                                        {
                                                            createUIService.CreateSingleton<QuestionScope>(QuestionController.View,
                                                                (myScope, elem) =>
                                                                {
                                                                    myScope.Model = new QuestionScopeModel();
                                                                    myScope.Model.Question = gameSendAnswerModel.Question;
                                                                    myScope.Model.Answers = gameSendAnswerModel.Answers;
                                                                    myScope.Model.SelectedAnswer = gameSendAnswerModel.Answers[0];
                                                                });
                                                        };

            var addRule = (new Func<Element, Action<string, JsDictionary<string, object>>>(style =>
                                                                                           {
                                                                                               var document = (dynamic)Window.Document;
                                                                                               var sheet = document.head.appendChild(style).sheet;
                                                                                               return (selector, css) =>
                                                                                                      {
                                                                                                          var propText = Keys(css).Map((p) => { return p + ":" + css[p]; }).Join(";");
                                                                                                          sheet.insertRule(selector + "{" + propText + "}", sheet.cssRules.length);
                                                                                                      };
                                                                                           }))(Document.CreateElement("style"));
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 13; j++)
                {
                    addRule(".card" + i+ "-" + j+ "", new JsDictionary<string, object>());
                    addRule(".card" + i+ "-" + j+ "::before", new JsDictionary<string, object>());
                    addRule(".card" + i+ "-" + j+ "::after", new JsDictionary<string, object>());

                }
            }
            addRule(".card" + -1 + "-" + -1 + "", new JsDictionary<string, object>());
            addRule(".card" + -1 + "-" + -1 + "::before", new JsDictionary<string, object>());
            addRule(".card" + -1 + "-" + -1 + "::after", new JsDictionary<string, object>());


            myClientGameManagerService.OnUpdateState += (user, update) =>
                                                        {
                                                            var data =
                                                                Json.Parse<GameCardGame>(
                                                                    new Compressor().DecompressText(update));

                                                            bool create = scope.MainArea == null;

                                                            scope.MainArea = data;


                                                            if (create)
                                                            {
                                                                scope.Scale =
                                                                    new Point(jQuery.Window.GetWidth() / (double)scope.MainArea.Size.Width * .9, ((jQuery.Window.GetHeight()) / (double)scope.MainArea.Size.Height) * .9);

                                                                foreach (var space in scope.MainArea.Spaces)
                                                                {
                                                                    addRule(".space" + space.Name,
                                                                        new JsDictionary<string, object>());
                                                                    addRule(".space" + space.Name + "::before",
                                                                        new JsDictionary<string, object>());
                                                                    addRule(".space" + space.Name + "::after",
                                                                        new JsDictionary<string, object>());


                                                                 }
                                                            }


                                                            scope.Apply();
                                                            myGameContentManagerService.Redraw();
                                                        };

            jQuery.Window.Bind("resize", (a) =>
                                         {
                                             scope.Scale =
                                                 new Point(jQuery.Window.GetWidth() / (double)scope.MainArea.Size.Width * .9, ((jQuery.Window.GetHeight()) / (double)scope.MainArea.Size.Height) * .9);
                                             scope.Apply();
                                         });




            myClientGameManagerService.OnGameOver += (user, room) =>
                                                     {
                                                         //alert(JSON.stringify(data));
                                                     };


            scope.MainArea = null;


            //new Action<string,JsDictionary<string,object>>()


            /* scope.MoveCard = () =>
             {

                 for (var i = 0; i < 1; i++)
                 {
                     CardGameCard card = null;
                     while (card == null)
                     {
                         var pile = scope.MainArea.Spaces.RandomElement().Pile;
                         card = pile.Cards.RandomElement();
                         var _pile = scope.MainArea.Spaces.RandomElement();

                         if (card != null && _pile != null)
                         {
                             card.Appearance.EffectNames.Remove("bend");
                             if (_pile.Name.StartsWith("User"))
                             {

                                 card.Appearance.EffectNames.Add("bend");

                             }


                             pile.Cards.Remove(card);
                             _pile.Pile.Cards.Add(card);
                         }
                     }
                 }
             };

             scope.AnimateCard = () =>
             {

                 for (var i = 0; i < 1; i++)
                 {
                     CardGameCard card = null;
                     while (card == null)
                     {
                         var pile = scope.MainArea.Spaces.RandomElement().Pile;
                         card = pile.Cards.RandomElement();
                         var _pile = scope.MainArea.Spaces.RandomElement();

                         if (card != null && _pile != null)
                         {

                             var css = string.Format(".card{0}-{1}", card.Type, card.Value);
                             var clone = jQueryApi.jQuery.Select(css).FuckingClone();


                             var space = jQuery.Select(string.Format(".space{0}", _pile.Name));
                             var off = space.GetOffset();

                             clone.CSS("z-index", 1000);

                             JsDictionary ops = new JsDictionary();
                             ops["left"] = off.Left + space.GetWidth() / 2 - 71 / 2;
                             ops["top"] = off.Top + space.GetHeight() / 2 - 96 / 2;
                             ops["rotate"] = "0deg";


                             pile.Cards.Remove(card);
                             clone.Animate(ops, 700, (EffectEasing)(dynamic)("easeInOutQuart"), () =>
                             {
                                 card.Appearance.EffectNames.Remove("bend");
                                 if (_pile.Name.StartsWith("User"))
                                 {

                                     card.Appearance.EffectNames.Add("bend");

                                 }

                                 clone.Remove();
                                 _pile.Pile.Cards.Add(card);
                                 scope.Apply();

                             });



                         }
                     }
                 }
             };*/
        }
        public DebugGameController(DebugGameControllerScope scope, ClientDebugManagerService clientDebugManagerService,
            GameContentManagerService gameContentManagerService, CreateUIService createUIService)
        {
            this.scope = scope;

            myClientDebugManagerService = clientDebugManagerService;
            myGameContentManagerService = gameContentManagerService;
            this.createUIService = createUIService;
            scope.GameModel = new DebugGameModel();


            CreatedUI<QuestionScope> lastQuestion = null;

            myClientDebugManagerService.OnAskQuestion += (user, gameSendAnswerModel) =>
                                                         {
                                                             lastQuestion = createUIService.CreateSingleton<QuestionScope>(DebugQuestionController.View,
                                                                 (myScope, elem) =>
                                                                 {
                                                                     myScope.Model = new QuestionScopeModel();
                                                                     myScope.Model.Question = gameSendAnswerModel.Question;
                                                                     myScope.Model.Answers = gameSendAnswerModel.Answers;
                                                                     myScope.Model.SelectedAnswer = gameSendAnswerModel.Answers[0];
                                                                 });
                                                         };
            scope.OnDestroy += () =>
                               {
                                   if (lastQuestion != null)
                                   {
                                       lastQuestion.Destroy();
                                   }
                               };

            /* effectManager.Effects =new List<GameEffectModel>();
             effectManager.Effects.Add(GameEffectsEditorController.makeEffect("bend", EffectType.Bend));
              */
            /*     myClientDebugManagerService.OnAskQuestion += (user, gameSendAnswerModel) => {
                                                        PageHandler.QuestionUI.Load(gameSendAnswerModel);
                                                        //alert(JSON.stringify(data));
                                                        PageHandler.TimeTracker.EndTime = new DateTime();
                                                        var time = PageHandler.TimeTracker.EndTime - PageHandler.TimeTracker.StartTime;
                                                      PageHandler.  DebugUI.lblHowFast.Text = ( "how long: " + time ); 
                                                    }; */


            var sheet = ClientHelpers.CreateCSSSheet();


            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 13; j++)
                {
                    ClientHelpers.AddCSSRule(sheet, ".card" + i + "-" + j + "", new JsDictionary<string, object>());
                    ClientHelpers.AddCSSRule(sheet, ".card" + i + "-" + j + "::before", new JsDictionary<string, object>());
                    ClientHelpers.AddCSSRule(sheet, ".card" + i + "-" + j + "::after", new JsDictionary<string, object>());
                }
            }
            ClientHelpers.AddCSSRule(sheet, ".card" + -1 + "-" + -1 + "", new JsDictionary<string, object>());
            ClientHelpers.AddCSSRule(sheet, ".card" + -1 + "-" + -1 + "::before", new JsDictionary<string, object>());
            ClientHelpers.AddCSSRule(sheet, ".card" + -1 + "-" + -1 + "::after", new JsDictionary<string, object>());

            var spaceLookups = new JsDictionary<string, DebugSpace>();


            myClientDebugManagerService.OnUpdateState += (user, update) =>
                                                         {
                                                             GoodConsole.Time("Render");
                                                             var data = Json.Parse<GameCardGame>(new Compressor().DecompressText(update));

                                                             bool create = scope.GameModel.MainArea == null;

                                                             scope.GameModel.MainArea = data;


                                                             if (create)
                                                             {
                                                                 scope.GameModel.Scale = new Point(jQuery.Window.GetWidth()/(double) scope.GameModel.MainArea.Size.Width*.9, ((jQuery.Window.GetHeight())/(double) scope.GameModel.MainArea.Size.Height)*.9);
                                                                 foreach (var cardGameTableSpace in scope.GameModel.MainArea.Spaces)
                                                                 {
                                                                     ClientHelpers.AddCSSRule(sheet, ".space" + cardGameTableSpace.Name + "", new JsDictionary<string, object>());
                                                                     ClientHelpers.AddCSSRule(sheet, ".space" + cardGameTableSpace.Name + "::before", new JsDictionary<string, object>());
                                                                     ClientHelpers.AddCSSRule(sheet, ".space" + cardGameTableSpace.Name + "::after", new JsDictionary<string, object>());
                                                                 }
                                                             }


                                                             scope.GameModel.Spaces = scope.GameModel.MainArea.Spaces.Map(space =>
                                                                                                                          {
                                                                                                                              DebugSpace debugSpace = spaceLookups[space.Name] ?? (spaceLookups[space.Name] = new DebugSpace());
                                                                                                                              debugSpace.GameSpace = space;
                                                                                                                              return debugSpace;
                                                                                                                          });

                                                             scope.Broadcast("spaceUpdated");
                                                             scope.Apply();
                                                             GoodConsole.TimeEnd("Render");

                                                             //         myGameContentManagerService.Redraw();
                                                         };

            jQuery.Window.Bind("resize", (a) =>
                                         {
                                             scope.GameModel.Scale = new Point(jQuery.Window.GetWidth()/(double) scope.GameModel.MainArea.Size.Width*.9, ((jQuery.Window.GetHeight())/(double) scope.GameModel.MainArea.Size.Height)*.9);
                                             scope.Broadcast("redraw");
                                             scope.Apply();
                                         });


            myClientDebugManagerService.OnGameStarted += (user, room) =>
                                                         {
                                                             //alert(JSON.stringify(data));
                                                         };

            myClientDebugManagerService.OnGameOver += (user, room) =>
                                                      {
                                                          //alert(JSON.stringify(data));
                                                      };


            scope.GameModel.MainArea = null;


            //new Action<string,JsDictionary<string,object>>()


            /* scope.MoveCard = () =>
             {

                 for (var i = 0; i < 1; i++)
                 {
                     CardGameCard card = null;
                     while (card == null)
                     {
                         var pile = scope.MainArea.Spaces.RandomElement().Pile;
                         card = pile.Cards.RandomElement();
                         var _pile = scope.MainArea.Spaces.RandomElement();

                         if (card != null && _pile != null)
                         {
                             card.Appearance.EffectNames.Remove("bend");
                             if (_pile.Name.StartsWith("User"))
                             {

                                 card.Appearance.EffectNames.Add("bend");

                             }


                             pile.Cards.Remove(card);
                             _pile.Pile.Cards.Add(card);
                         }
                     }
                 }
             };

             scope.AnimateCard = () =>
             {

                 for (var i = 0; i < 1; i++)
                 {
                     CardGameCard card = null;
                     while (card == null)
                     {
                         var pile = scope.MainArea.Spaces.RandomElement().Pile;
                         card = pile.Cards.RandomElement();
                         var _pile = scope.MainArea.Spaces.RandomElement();

                         if (card != null && _pile != null)
                         {

                             var css = string.Format(".card{0}-{1}", card.Type, card.Value);
                             var clone = jQueryApi.jQuery.Select(css).FuckingClone();


                             var space = jQuery.Select(string.Format(".space{0}", _pile.Name));
                             var off = space.GetOffset();

                             clone.CSS("z-index", 1000);

                             JsDictionary ops = new JsDictionary();
                             ops["left"] = off.Left + space.GetWidth() / 2 - 71 / 2;
                             ops["top"] = off.Top + space.GetHeight() / 2 - 96 / 2;
                             ops["rotate"] = "0deg";


                             pile.Cards.Remove(card);
                             clone.Animate(ops, 700, (EffectEasing)(dynamic)("easeInOutQuart"), () =>
                             {
                                 card.Appearance.EffectNames.Remove("bend");
                                 if (_pile.Name.StartsWith("User"))
                                 {

                                     card.Appearance.EffectNames.Add("bend");

                                 }

                                 clone.Remove();
                                 _pile.Pile.Cards.Add(card);
                                 scope.Apply();

                             });



                         }
                     }
                 }
             };*/
        }