/SuperMemory/Order/OrderViewModel.cs
C# | 339 lines | 219 code | 81 blank | 39 comment | 22 complexity | 4deb6507b6c42f139567b99615b5f804 MD5 | raw file
- using System;
- using System.Diagnostics.Contracts;
- using System.Linq;
- using System.Reactive;
- using System.Windows;
- using System.Windows.Input;
- using Smart.Classes.Collections;
- using Smart.Classes.Events;
- using Smart.Classes.Extensions;
- using Smart.Classes.Interfaces;
- using Smart.Classes.Subjects;
- using Smart.UI.Classes;
- using Smart.UI.Classes.Animations;
- using Smart.UI.Classes.Events;
- using Smart.UI.Panels;
- using Smart.UI.Widgets.Events;
- using System.Reactive.Linq;
-
- namespace SuperMemory.Order
- {
- public class OrderViewModel:IEventsHolder
- {
-
-
- private readonly FieldMatrix Matrix;
- private readonly PicsManager Imager;
-
- protected StateMachine<String> States;
-
-
- public OrderSettings Settings;
-
-
-
- [Pure]
- public OrderViewModel(OrderSettings settings)
- {
- this.EventManager = new SmartEventManager();
- this.Settings = settings;
- this.Matrix = new FieldMatrix(this.Settings.Cols.Value,this.Settings.Rows.Value);
- this.Imager = new PicsManager();
- }
-
- /// <summary>
- /// Inits main part of application logic
- /// Made public because i want to nake all the binding first
- /// </summary>
- public void Start()
- {
- InitEvents();
- InitStates();
- Contract.Assert(States.Current == OrderStates.ZERO_STATE);
- //Contract.Assert(States.NextPossibleState() == OrderStates.NON_GAME_STATE);
- this.States.GoTo(OrderStates.NON_GAME_STATE);
- }
-
- /// <summary>
- /// Starts play
- /// </summary>
- public void OnButtonClick()
- {
- if(this.States.ActiveTransitionsCount>0)return;
- switch (this.States.TargetState)
- {
- case OrderStates.ZERO_STATE: this.States.GoTo(OrderStates.NON_GAME_STATE); break;
- case OrderStates.NON_GAME_STATE: this.States.GoTo(OrderStates.MEMORIZE_STATE); break;
- case OrderStates.MEMORIZE_STATE: this.States.GoTo(OrderStates.POSITION_STATE); break;
- case OrderStates.POSITION_STATE: this.States.GoTo(OrderStates.GAME_COMPLETED_STATE); break;
- case OrderStates.GAME_COMPLETED_STATE: this.States.GoTo(OrderStates.NON_GAME_STATE); break;
- }
- }
-
- private void InitEvents()
- {
- this.AddEventHandler<String>(OrderEvents.GO_2_STATE, this.GoToState);
- }
-
- private void GoToState(String state)
- {
- this.States.GoTo(state);
- }
-
-
- private void InitStates()
- {
- States = new StateMachine<string> {PossibleStates = OrderStates.PossibleStates };
- States.GoTo(OrderStates.ZERO_STATE);
-
- States.State(OrderStates.POSITION_STATE).DoOnNext += On_Position_State;
-
-
- States.EachTimeTransition = new SimpleSubject<Transition<string>>(EachTimeTransition);
-
- States.TransitionFrom(OrderStates.NON_GAME_STATE).DoOnNext += this.From_NonGame_2_All;
- States.TransitionFrom(OrderStates.POSITION_STATE).DoOnNext += From_Position_2_All;
- States.TransitionFrom(OrderStates.MEMORIZE_STATE).DoOnNext += From_Memorize_2_All;
-
- States.TransitionTo(OrderStates.MEMORIZE_STATE).DoOnNext += From_All_2_Memorize;
- States.TransitionTo(OrderStates.NON_GAME_STATE).DoOnNext += this.From_All_2_NonGame;
- States.TransitionTo(OrderStates.POSITION_STATE).DoOnNext += From_All_2_Position;
-
- States.Transition(OrderStates.ZERO_STATE,OrderStates.NON_GAME_STATE).DoOnNext = Zero_2_NonGame;
- States.Transition(OrderStates.NON_GAME_STATE,OrderStates.MEMORIZE_STATE).DoOnNext += NonGame_2_Memorize;
-
- //States.Transition(OrderStates.MEMORIZE_STATE,OrderStates.POSITION_STATE).DoOnNext += Memorize_2_Position;
- States.TransitionContinuous(OrderStates.MEMORIZE_STATE, OrderStates.POSITION_STATE,false).AddCallback(Memorize_2_Position);
- // States.Transition(OrderStates.POSITION_STATE, OrderStates.NON_GAME_STATE).DoOnNext += Position_2_NonGame;
- States.TransitionContinuous(OrderStates.POSITION_STATE, OrderStates.GAME_COMPLETED_STATE,false).AddCallback(Position_2_GameCompleted);
- States.TransitionContinuous(OrderStates.GAME_COMPLETED_STATE, OrderStates.NON_GAME_STATE,false).AddCallback(GameCompleted_2_NonGame);
- }
-
-
- [ContractInvariantMethod]
- private void ObjectInvariant()
- {
- Contract.Invariant(this.Settings.ShowHints !=(this.States.Current == OrderStates.MEMORIZE_STATE || this.States.Current == OrderStates.POSITION_STATE));
- Contract.Invariant(Settings.ParamsEnabled== (this.States.Current==OrderStates.NON_GAME_STATE));
-
- // Contract.Invariant(this.Settings.SetupMemoAni().I);
- }
-
- #region From_All_2 STATE transitions
-
-
-
- /// <summary>
- /// Works every time the state changes
- /// </summary>
- /// <param name="transition"></param>
- private void EachTimeTransition(Transition<String> transition)
- {
- this.Settings.ButtonName = this.Settings.ButtonNames[transition.To];
- }
-
- private void From_All_2_NonGame(Transition<String> transition)
- {
- this.Settings.ShowHints = true;
- this.Settings.ParamsEnabled = true;
- }
-
- private void From_All_2_Memorize(Transition<String> transition)
- {
- this.Settings.InMemo = true;
- this.Settings.ShowHints = false;
- this.Settings.Results = this.Settings.Results.Add(new Results());
- }
-
- private void From_All_2_Position(Transition<String> transition)
- {
- this.Settings.ShowHints = false;
- }
-
-
- #endregion
-
- #region ACTIONS ON STATES
-
- private void On_Position_State(string state)
- {
- //writing time
- var r = Animator.LatestRender;
- this.States.TransitionFrom(OrderStates.POSITION_STATE).At().DoOnNext +=
- i => this.Settings.WriteTime(TimeSpan.FromMilliseconds(Animator.LatestRender - r));
- }
-
-
-
- #endregion
-
- #region TRANSITIONS BETWEEN STATES
-
- /// <summary>
- /// First transition
- /// </summary>
- /// <param name="transition"></param>
- private void Zero_2_NonGame(Transition<String> transition)
- {
- Contract.Requires(
- States.CurrentTransition.From == OrderStates.ZERO_STATE
- && States.CurrentTransition.To == OrderStates.NON_GAME_STATE
- && States.Current == OrderStates.ZERO_STATE);
- States.PossibleStates.Remove(OrderStates.ZERO_STATE);
- this.Settings.InMemo = false;
- //Imager.Init();
- }
-
-
- /// <summary>
- /// Transition which occurs when the player starts the game and goes to memorizing stage
- /// </summary>
- /// <param name="transition"></param>
- private void NonGame_2_Memorize(Transition<string> transition)
- {
- Contract.Requires(transition.From == OrderStates.NON_GAME_STATE && transition.To == OrderStates.MEMORIZE_STATE);
- // Contract.Ensures(false == (this.Field.DragEnabled && this.Tools.DragEnabled));
-
- Settings.SetupMemoAni().DoOnCompleted = this.States.GoToIfState(
- OrderStates.POSITION_STATE, OrderStates.MEMORIZE_STATE);
-
- Matrix.GenerateMatrix(Imager.CurrentImages, Settings.Icons.Value, Settings.Cols.Value, Settings.Rows.Value);
-
- //var nums = Matrix.Flatten(i => !i.Equals(Num2D.Emtpy)).ToList();
-
- var imgs = Matrix.NonEmptyIndexed()
- .Select(n => new Tuple<FrameworkElement, Point>(
- this.Imager.CurrentImages[n.Value]
- .SetColumn(n.Key.X).SetRow(n.Key.Y),
- new Point(1, 1))).ToList();
-
- var args = new MassiveRelativeResizeEvent(
- OrderEvents.APPEAR, imgs, new TimeSpan(0, 0, 0, 2), Easings.CubicEaseInOut);
-
- this.RunEvent(OrderEvents.APPEAR, args);
- //this.Field.DragEnabled = this.Tools.DragEnabled = false;
- }
-
-
-
- /// <summary>
- /// Transition which occures when the user comes from memorization to remembering and dragging
- /// </summary>
- /// <param name="transition"></param>
- private SimpleSubject<MoveToCellsEvent> Memorize_2_Position(Transition<string> transition)
- {
- Contract.Requires(transition.From == OrderStates.MEMORIZE_STATE && transition.To == OrderStates.POSITION_STATE);
- //Contract.Ensures(this.Field.DragEnabled && this.Tools.DragEnabled);
- var num = Num2D.Emtpy;
- var objects =
- Matrix.Flatten(i => !i.Equals(Num2D.Emtpy))
- .OrderBy(o => o.X).ThenBy(o => o.Y)
- .Select(
- o => new Tuple<FrameworkElement, CellsRegion>(
- this.Imager.CurrentImages[o], new CellsRegion(num.WrapInc(this.Settings.ToolsColsNum)))
- ).ToList();
-
- Contract.Assert(objects.Count == Settings.Icons.Value);
-
- return this.RunEvent(new MoveToCellsEvent(
- OrderEvents.MOVE_TO_INVENTORY, objects, new TimeSpan(0, 0, 0, 3), Easings.CubicEaseInOut));
- }
-
- private SimpleSubject<AnimationEvent<FrameworkElement>> Position_2_GameCompleted(Transition<string> obj)
- {
- this.RunEvent(OrderEvents.DISAPPEAR);
- this.Settings.Results.Head.Failures += this.Matrix.IconsLeft;
- this.Settings.ResultsUpdate();
- return this.RunEvent(new AnimationEvent<FrameworkElement>(OrderEvents.SHOW_POPUP, GameResults.Instance.WithDataContext(this.Settings), new TimeSpan(0, 0, 0, 1)));
- }
-
- private SimpleSubject<AnimationEvent<FrameworkElement>> GameCompleted_2_NonGame(Transition<string> obj)
- {
- return this.RunEvent(new AnimationEvent<FrameworkElement>(
- OrderEvents.HIDE_POPUP, GameResults.Instance, new TimeSpan(0, 0, 0, 1)));
- }
-
-
- #endregion
-
- #region TRANSITIONS like State_2_ALL
-
- private void From_NonGame_2_All(Transition<String> transition)
- {
- this.Settings.ParamsEnabled = false;
- }
-
- private void From_Memorize_2_All(Transition<String> transition)
- {
- this.Settings.InMemo = false;
- }
-
- private void From_Position_2_All(Transition<String> transition)
- {
- this.Settings.InMemo = false;
- this.Settings.ShowHints = true;
- }
-
- #endregion
-
-
-
- /// <summary>
- /// Decides if we should
- /// </summary>
- /// <param name="where"></param>
- /// <param name="what"></param>
- /// <returns></returns>
- public bool MoveElementTo(Num2D where, FrameworkElement what)
- {
- var pos = PicsManager.GetMemoryPosition(what);
- var num = this.Matrix[where];
- var allow = num.Equals(pos);
- if (allow)
- this.Matrix.IconsLeft -= 1;
- else
- this.Settings.Results.Head.Failures += 1;
- if (Matrix.IconsLeft == 0)
- this.States.GoTo(OrderStates.GAME_COMPLETED_STATE);
-
- return allow;
- }
-
- #region EVENT HOLDER IMPLEMENTATION
-
- public SimpleSubject<TEventArgs> RunEvent<TEventArgs>(string name, TEventArgs eventArgs)
- {
- return this.EventManager.RunEvent(name,eventArgs);
- }
-
- public bool HasEvent<TEvenrArgs>(string name)
- {
- return EventManager.HasEvent<TEvenrArgs>(name);
- }
-
-
- public SimpleSubject<TEventArgs> RunEvent<TEventArgs>(TEventArgs eventArgs) where TEventArgs : INamed
- {
- return EventManager.RunEvent(eventArgs);
- }
-
- public SimpleSubject<TEventArgs> RouteEventTo<TEventArgs>(string name, IEventsHolder where)
- {
- return this.EventManager.RouteEventTo<TEventArgs>(name, where);
- }
-
-
- public SimpleSubject<String> RunEvent(string eventArgs)
- {
- return EventManager.RunEvent(eventArgs);
- }
-
- public SmartEventManager EventManager { get; private set; }
-
-
- #endregion
-
-
-
- }
- }