PageRenderTime 46ms CodeModel.GetById 18ms app.highlight 21ms RepoModel.GetById 2ms app.codeStats 0ms

/SuperMemory/Order/OrderViewModel.cs

https://github.com/antonkulaga/SuperMemory
C# | 339 lines | 219 code | 81 blank | 39 comment | 22 complexity | 4deb6507b6c42f139567b99615b5f804 MD5 | raw file
  1using System;
  2using System.Diagnostics.Contracts;
  3using System.Linq;
  4using System.Reactive;
  5using System.Windows;
  6using System.Windows.Input;
  7using Smart.Classes.Collections;
  8using Smart.Classes.Events;
  9using Smart.Classes.Extensions;
 10using Smart.Classes.Interfaces;
 11using Smart.Classes.Subjects;
 12using Smart.UI.Classes;
 13using Smart.UI.Classes.Animations;
 14using Smart.UI.Classes.Events;
 15using Smart.UI.Panels;
 16using Smart.UI.Widgets.Events;
 17using System.Reactive.Linq;
 18
 19namespace SuperMemory.Order
 20{
 21    public class OrderViewModel:IEventsHolder
 22    {
 23
 24
 25        private readonly FieldMatrix Matrix;
 26        private readonly PicsManager Imager;
 27                
 28        protected StateMachine<String> States;
 29
 30       
 31        public OrderSettings Settings;
 32        
 33        
 34        
 35        [Pure]
 36        public OrderViewModel(OrderSettings settings)
 37        {            
 38            this.EventManager = new SmartEventManager();     
 39            this.Settings = settings;           
 40            this.Matrix = new FieldMatrix(this.Settings.Cols.Value,this.Settings.Rows.Value);            
 41            this.Imager = new PicsManager();      
 42        }
 43
 44        /// <summary>
 45        /// Inits main part of application logic
 46        /// Made public because i want to nake all the binding first
 47        /// </summary>
 48        public void Start()
 49        {  
 50            InitEvents();
 51            InitStates();
 52            Contract.Assert(States.Current == OrderStates.ZERO_STATE);
 53            //Contract.Assert(States.NextPossibleState() == OrderStates.NON_GAME_STATE);
 54            this.States.GoTo(OrderStates.NON_GAME_STATE);
 55        }
 56
 57          /// <summary>
 58        /// Starts play
 59        /// </summary>
 60        public void OnButtonClick()
 61        {
 62            if(this.States.ActiveTransitionsCount>0)return;
 63              switch (this.States.TargetState)
 64              {
 65                  case OrderStates.ZERO_STATE: this.States.GoTo(OrderStates.NON_GAME_STATE); break;
 66                  case OrderStates.NON_GAME_STATE: this.States.GoTo(OrderStates.MEMORIZE_STATE); break;
 67                  case OrderStates.MEMORIZE_STATE: this.States.GoTo(OrderStates.POSITION_STATE); break;
 68                  case OrderStates.POSITION_STATE: this.States.GoTo(OrderStates.GAME_COMPLETED_STATE); break;
 69                  case OrderStates.GAME_COMPLETED_STATE: this.States.GoTo(OrderStates.NON_GAME_STATE); break;
 70              }
 71        }
 72
 73        private void InitEvents()
 74        {
 75            this.AddEventHandler<String>(OrderEvents.GO_2_STATE, this.GoToState);
 76        }
 77
 78        private void GoToState(String state)
 79        {
 80            this.States.GoTo(state);
 81        }
 82
 83
 84        private void InitStates()
 85        {
 86            States = new StateMachine<string> {PossibleStates = OrderStates.PossibleStates };
 87            States.GoTo(OrderStates.ZERO_STATE);
 88
 89            States.State(OrderStates.POSITION_STATE).DoOnNext += On_Position_State;
 90
 91              
 92            States.EachTimeTransition = new SimpleSubject<Transition<string>>(EachTimeTransition);
 93
 94            States.TransitionFrom(OrderStates.NON_GAME_STATE).DoOnNext += this.From_NonGame_2_All;
 95            States.TransitionFrom(OrderStates.POSITION_STATE).DoOnNext += From_Position_2_All;            
 96            States.TransitionFrom(OrderStates.MEMORIZE_STATE).DoOnNext += From_Memorize_2_All;
 97
 98            States.TransitionTo(OrderStates.MEMORIZE_STATE).DoOnNext += From_All_2_Memorize;
 99            States.TransitionTo(OrderStates.NON_GAME_STATE).DoOnNext += this.From_All_2_NonGame;
100            States.TransitionTo(OrderStates.POSITION_STATE).DoOnNext += From_All_2_Position;
101      
102            States.Transition(OrderStates.ZERO_STATE,OrderStates.NON_GAME_STATE).DoOnNext = Zero_2_NonGame;
103            States.Transition(OrderStates.NON_GAME_STATE,OrderStates.MEMORIZE_STATE).DoOnNext += NonGame_2_Memorize;
104            
105            //States.Transition(OrderStates.MEMORIZE_STATE,OrderStates.POSITION_STATE).DoOnNext += Memorize_2_Position;
106            States.TransitionContinuous(OrderStates.MEMORIZE_STATE, OrderStates.POSITION_STATE,false).AddCallback(Memorize_2_Position);
107         //   States.Transition(OrderStates.POSITION_STATE, OrderStates.NON_GAME_STATE).DoOnNext += Position_2_NonGame;
108            States.TransitionContinuous(OrderStates.POSITION_STATE, OrderStates.GAME_COMPLETED_STATE,false).AddCallback(Position_2_GameCompleted);
109            States.TransitionContinuous(OrderStates.GAME_COMPLETED_STATE, OrderStates.NON_GAME_STATE,false).AddCallback(GameCompleted_2_NonGame);
110        }
111
112     
113        [ContractInvariantMethod]
114        private void ObjectInvariant()
115        {
116            Contract.Invariant(this.Settings.ShowHints !=(this.States.Current == OrderStates.MEMORIZE_STATE || this.States.Current == OrderStates.POSITION_STATE));
117            Contract.Invariant(Settings.ParamsEnabled== (this.States.Current==OrderStates.NON_GAME_STATE));
118            
119//            Contract.Invariant(this.Settings.SetupMemoAni().I);
120        }       
121
122    #region From_All_2 STATE transitions
123
124
125        
126        /// <summary>
127        /// Works every time the state changes
128        /// </summary>
129        /// <param name="transition"></param>
130        private void EachTimeTransition(Transition<String> transition)
131        {
132            this.Settings.ButtonName = this.Settings.ButtonNames[transition.To];
133        }
134
135        private void From_All_2_NonGame(Transition<String> transition)
136        {
137            this.Settings.ShowHints = true;
138            this.Settings.ParamsEnabled = true;
139        }
140
141        private void From_All_2_Memorize(Transition<String> transition)
142        {
143            this.Settings.InMemo = true;
144            this.Settings.ShowHints = false;
145            this.Settings.Results = this.Settings.Results.Add(new Results());
146        }
147
148        private void From_All_2_Position(Transition<String> transition)
149        {
150            this.Settings.ShowHints = false;
151        }
152
153      
154    #endregion
155
156    #region ACTIONS ON STATES
157
158        private void On_Position_State(string state)
159        {
160            //writing time
161            var r = Animator.LatestRender;
162            this.States.TransitionFrom(OrderStates.POSITION_STATE).At().DoOnNext +=
163                i => this.Settings.WriteTime(TimeSpan.FromMilliseconds(Animator.LatestRender - r));
164        }
165
166
167
168        #endregion
169
170    #region TRANSITIONS BETWEEN STATES
171
172        /// <summary>
173        /// First transition
174        /// </summary>
175        /// <param name="transition"></param>
176        private void Zero_2_NonGame(Transition<String> transition)
177        {
178            Contract.Requires(
179                States.CurrentTransition.From == OrderStates.ZERO_STATE
180                && States.CurrentTransition.To == OrderStates.NON_GAME_STATE
181                && States.Current == OrderStates.ZERO_STATE);
182            States.PossibleStates.Remove(OrderStates.ZERO_STATE);
183            this.Settings.InMemo = false;
184            //Imager.Init();
185        }
186
187
188        /// <summary>
189        /// Transition which occurs when the player starts the game and goes to memorizing stage
190        /// </summary>
191        /// <param name="transition"></param>
192        private void NonGame_2_Memorize(Transition<string> transition)
193        {
194            Contract.Requires(transition.From == OrderStates.NON_GAME_STATE && transition.To == OrderStates.MEMORIZE_STATE);
195            //  Contract.Ensures(false == (this.Field.DragEnabled && this.Tools.DragEnabled));         
196
197            Settings.SetupMemoAni().DoOnCompleted = this.States.GoToIfState(
198                OrderStates.POSITION_STATE, OrderStates.MEMORIZE_STATE);
199
200            Matrix.GenerateMatrix(Imager.CurrentImages, Settings.Icons.Value, Settings.Cols.Value, Settings.Rows.Value);
201
202            //var nums = Matrix.Flatten(i => !i.Equals(Num2D.Emtpy)).ToList();
203
204            var imgs = Matrix.NonEmptyIndexed()
205                .Select(n => new Tuple<FrameworkElement, Point>(
206                    this.Imager.CurrentImages[n.Value]
207                    .SetColumn(n.Key.X).SetRow(n.Key.Y),
208                    new Point(1, 1))).ToList();
209
210            var args = new MassiveRelativeResizeEvent(
211                OrderEvents.APPEAR, imgs, new TimeSpan(0, 0, 0, 2), Easings.CubicEaseInOut);
212
213            this.RunEvent(OrderEvents.APPEAR, args);
214            //this.Field.DragEnabled = this.Tools.DragEnabled = false;
215        }
216
217
218
219        /// <summary>
220        /// Transition which occures when  the user comes from memorization to remembering and dragging
221        /// </summary>
222        /// <param name="transition"></param>
223        private SimpleSubject<MoveToCellsEvent> Memorize_2_Position(Transition<string> transition)
224        {
225            Contract.Requires(transition.From == OrderStates.MEMORIZE_STATE && transition.To == OrderStates.POSITION_STATE);
226            //Contract.Ensures(this.Field.DragEnabled && this.Tools.DragEnabled);
227            var num = Num2D.Emtpy;
228            var objects =
229               Matrix.Flatten(i => !i.Equals(Num2D.Emtpy))
230                   .OrderBy(o => o.X).ThenBy(o => o.Y)
231                   .Select(
232                       o => new Tuple<FrameworkElement, CellsRegion>(
233                           this.Imager.CurrentImages[o], new CellsRegion(num.WrapInc(this.Settings.ToolsColsNum)))
234                   ).ToList();
235
236            Contract.Assert(objects.Count == Settings.Icons.Value);
237
238            return this.RunEvent(new MoveToCellsEvent(
239                OrderEvents.MOVE_TO_INVENTORY, objects, new TimeSpan(0, 0, 0, 3), Easings.CubicEaseInOut));
240        }
241
242        private SimpleSubject<AnimationEvent<FrameworkElement>> Position_2_GameCompleted(Transition<string> obj)
243        {           
244            this.RunEvent(OrderEvents.DISAPPEAR);
245            this.Settings.Results.Head.Failures += this.Matrix.IconsLeft;
246            this.Settings.ResultsUpdate();
247            return this.RunEvent(new AnimationEvent<FrameworkElement>(OrderEvents.SHOW_POPUP, GameResults.Instance.WithDataContext(this.Settings), new TimeSpan(0, 0, 0, 1)));
248        }
249
250        private SimpleSubject<AnimationEvent<FrameworkElement>> GameCompleted_2_NonGame(Transition<string> obj)
251        {
252            return this.RunEvent(new AnimationEvent<FrameworkElement>(
253                OrderEvents.HIDE_POPUP, GameResults.Instance, new TimeSpan(0, 0, 0, 1)));
254        }
255
256
257    #endregion
258
259    #region TRANSITIONS like State_2_ALL
260
261        private void From_NonGame_2_All(Transition<String> transition)
262        {
263            this.Settings.ParamsEnabled = false;
264        }
265
266        private void From_Memorize_2_All(Transition<String> transition)
267        {
268            this.Settings.InMemo = false;
269        }
270
271        private void From_Position_2_All(Transition<String> transition)
272        {
273            this.Settings.InMemo = false;
274            this.Settings.ShowHints = true;
275        }
276
277    #endregion
278
279
280
281        /// <summary>
282        /// Decides if we should 
283        /// </summary>
284        /// <param name="where"></param>
285        /// <param name="what"></param>
286        /// <returns></returns>
287        public bool MoveElementTo(Num2D where, FrameworkElement what)
288        {
289            var pos = PicsManager.GetMemoryPosition(what);
290            var num = this.Matrix[where];
291            var allow = num.Equals(pos);
292            if (allow) 
293                this.Matrix.IconsLeft -= 1;
294            else 
295                this.Settings.Results.Head.Failures += 1;
296            if (Matrix.IconsLeft == 0) 
297                this.States.GoTo(OrderStates.GAME_COMPLETED_STATE);
298
299            return allow;
300        }
301
302    #region EVENT HOLDER IMPLEMENTATION
303
304        public SimpleSubject<TEventArgs> RunEvent<TEventArgs>(string name, TEventArgs eventArgs)
305        {
306           return this.EventManager.RunEvent(name,eventArgs);
307        }
308
309        public bool HasEvent<TEvenrArgs>(string name)
310        {
311            return EventManager.HasEvent<TEvenrArgs>(name);
312        }
313
314        
315        public SimpleSubject<TEventArgs> RunEvent<TEventArgs>(TEventArgs eventArgs) where TEventArgs : INamed
316        {
317           return EventManager.RunEvent(eventArgs);
318        }
319
320        public SimpleSubject<TEventArgs> RouteEventTo<TEventArgs>(string name, IEventsHolder where)
321        {
322            return this.EventManager.RouteEventTo<TEventArgs>(name, where);
323        }
324
325
326        public SimpleSubject<String> RunEvent(string eventArgs)
327        {
328            return EventManager.RunEvent(eventArgs);
329        }
330
331        public SmartEventManager EventManager { get; private set; }
332
333
334    #endregion
335
336    
337
338    }
339}