commit be576d142627018dc13c04a5e0a011d552bd46e4
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Sep 25 09:37:34 2020 +0100

    Rename some classes.

diff --git a/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java b/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
index b16870e8..1ebe8c59 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
@@ -40,7 +40,7 @@ import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
 import org.distorted.objects.ObjectList;
 import org.distorted.scores.RubikScores;
-import org.distorted.states.RubikState;
+import org.distorted.states.StateList;
 import org.distorted.states.RubikStatePlay;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -98,11 +98,11 @@ public class RubikDialogNewRecord extends AppCompatDialogFragment
         RubikScores scores = RubikScores.getInstance();
         String name = scores.getName();
         Bundle bundle = new Bundle();
-        RubikState.switchState(act,RubikState.PLAY);
+        StateList.switchState(act, StateList.PLAY);
 
         if( name.length()>0 )
           {
-          RubikStatePlay play = (RubikStatePlay) RubikState.PLAY.getStateClass();
+          RubikStatePlay play = (RubikStatePlay) StateList.PLAY.getStateClass();
           int object = play.getObject();
           int size   = play.getSize();
           int sizeIndex = ObjectList.getSizeIndex(object,size);
@@ -131,7 +131,7 @@ public class RubikDialogNewRecord extends AppCompatDialogFragment
       public void onClick(DialogInterface dialog, int which)
         {
         RubikActivity act = (RubikActivity)getActivity();
-        RubikState.switchState(act,RubikState.PLAY);
+        StateList.switchState(act, StateList.PLAY);
         }
       });
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java b/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
index da0a4234..4fc2fd48 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
@@ -31,7 +31,7 @@ import org.distorted.main.RubikActivity;
 import org.distorted.objects.ObjectList;
 import org.distorted.patterns.RubikPattern;
 import org.distorted.patterns.RubikPatternList;
-import org.distorted.states.RubikState;
+import org.distorted.states.StateList;
 import org.distorted.states.RubikStatePattern;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -99,7 +99,7 @@ public class RubikDialogPatternView extends FrameLayout
 
         ract.setupObject(list, size, moves);
 
-        RubikStatePattern state = (RubikStatePattern) RubikState.PATT.getStateClass();
+        RubikStatePattern state = (RubikStatePattern) StateList.PATT.getStateClass();
 
         state.setPattern(ract, mTab, groupPosition, childPosition);
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogSetName.java b/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
index 3b37f4cc..51f5d09d 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
@@ -42,7 +42,7 @@ import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
 import org.distorted.objects.ObjectList;
 import org.distorted.scores.RubikScores;
-import org.distorted.states.RubikState;
+import org.distorted.states.StateList;
 import org.distorted.states.RubikStatePlay;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -142,9 +142,9 @@ public class RubikDialogSetName extends AppCompatDialogFragment
             }
 
           RubikActivity act = (RubikActivity)getActivity();
-          RubikState.switchState(act,RubikState.PLAY);
+          StateList.switchState(act, StateList.PLAY);
           RubikScores.getInstance().setName(name);
-          RubikStatePlay play = (RubikStatePlay) RubikState.PLAY.getStateClass();
+          RubikStatePlay play = (RubikStatePlay) StateList.PLAY.getStateClass();
 
           int object = play.getObject();
           int size   = play.getSize();
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogSolved.java b/src/main/java/org/distorted/dialogs/RubikDialogSolved.java
index 15364752..c6a954b7 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogSolved.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogSolved.java
@@ -38,7 +38,7 @@ import android.widget.TextView;
 
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.states.RubikState;
+import org.distorted.states.StateList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -70,7 +70,7 @@ public class RubikDialogSolved extends AppCompatDialogFragment
       public void onClick(DialogInterface dialog, int which)
         {
         RubikActivity act = (RubikActivity)getActivity();
-        RubikState.switchState(act,RubikState.PLAY);
+        StateList.switchState(act, StateList.PLAY);
         }
       });
 
diff --git a/src/main/java/org/distorted/main/RubikActivity.java b/src/main/java/org/distorted/main/RubikActivity.java
index 01034c09..25dbe72c 100644
--- a/src/main/java/org/distorted/main/RubikActivity.java
+++ b/src/main/java/org/distorted/main/RubikActivity.java
@@ -41,7 +41,7 @@ import org.distorted.objects.TwistyObject;
 import org.distorted.scores.RubikScores;
 import org.distorted.scores.RubikScoresDownloader;
 import org.distorted.objects.ObjectList;
-import org.distorted.states.RubikState;
+import org.distorted.states.StateList;
 import org.distorted.states.RubikStatePlay;
 
 import java.util.Locale;
@@ -204,7 +204,7 @@ public class RubikActivity extends AppCompatActivity
       view.onResume();
       view.initialize();
       restorePreferences();
-      RubikState.setState(this);
+      StateList.setState(this);
 
       if( mJustStarted )
         {
@@ -215,7 +215,7 @@ public class RubikActivity extends AppCompatActivity
         }
 
       boolean success = false;
-      RubikStatePlay play = (RubikStatePlay)RubikState.PLAY.getStateClass();
+      RubikStatePlay play = (RubikStatePlay) StateList.PLAY.getStateClass();
       int object = play.getObject();
       int size   = play.getSize();
 
@@ -267,12 +267,12 @@ public class RubikActivity extends AppCompatActivity
         BaseEffect.Type.getType(i).savePreferences(editor);
         }
 
-      for (int i=0; i<RubikState.LENGTH; i++)
+      for (int i = 0; i< StateList.LENGTH; i++)
         {
-        RubikState.getState(i).getStateClass().savePreferences(editor);
+        StateList.getState(i).getStateClass().savePreferences(editor);
         }
 
-      RubikState.savePreferences(editor);
+      StateList.savePreferences(editor);
       RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
       view.getPreRender().savePreferences(editor);
 
@@ -292,12 +292,12 @@ public class RubikActivity extends AppCompatActivity
         BaseEffect.Type.getType(i).restorePreferences(preferences);
         }
 
-      for (int i=0; i< RubikState.LENGTH; i++)
+      for (int i = 0; i< StateList.LENGTH; i++)
         {
-        RubikState.getState(i).getStateClass().restorePreferences(preferences);
+        StateList.getState(i).getStateClass().restorePreferences(preferences);
         }
 
-      RubikState.restorePreferences(preferences);
+      StateList.restorePreferences(preferences);
 
       RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
       view.getPreRender().restorePreferences(preferences);
@@ -503,9 +503,9 @@ public class RubikActivity extends AppCompatActivity
 
     public boolean isLocked()
       {
-      RubikState state = RubikState.getCurrentState();
+      StateList state = StateList.getCurrentState();
 
-      if( state==RubikState.PLAY || state==RubikState.READ || state==RubikState.SOLV )
+      if( state== StateList.PLAY || state== StateList.READ || state== StateList.SOLV )
         {
         return mIsLocked;
         }
diff --git a/src/main/java/org/distorted/main/RubikPreRender.java b/src/main/java/org/distorted/main/RubikPreRender.java
index 32b9e183..3e759218 100644
--- a/src/main/java/org/distorted/main/RubikPreRender.java
+++ b/src/main/java/org/distorted/main/RubikPreRender.java
@@ -31,7 +31,7 @@ import org.distorted.library.message.EffectListener;
 import org.distorted.objects.TwistyObject;
 import org.distorted.objects.ObjectList;
 import org.distorted.scores.RubikScores;
-import org.distorted.states.RubikState;
+import org.distorted.states.StateList;
 import org.distorted.states.RubikStateSolving;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -156,9 +156,9 @@ public class RubikPreRender implements EffectListener
 
     if( solved && !mIsSolved )
       {
-      if( RubikState.getCurrentState()==RubikState.SOLV )
+      if( StateList.getCurrentState()== StateList.SOLV )
         {
-        RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
+        RubikStateSolving solving = (RubikStateSolving) StateList.SOLV.getStateClass();
         mNewRecord = solving.getRecord();
 
         if( mNewRecord< 0 )
@@ -544,14 +544,14 @@ public class RubikPreRender implements EffectListener
               @Override
               public void run()
                 {
-                RubikState.switchState( act, RubikState.READ);
+                StateList.switchState( act, StateList.READ);
                 }
               });
             }
 
           if( i==BaseEffect.Type.WIN.ordinal() )
             {
-            if( RubikState.getCurrentState()==RubikState.SOLV )
+            if( StateList.getCurrentState()== StateList.SOLV )
               {
               final RubikActivity act = (RubikActivity)mView.getContext();
               Bundle bundle = new Bundle();
@@ -575,7 +575,7 @@ public class RubikPreRender implements EffectListener
                 @Override
                 public void run()
                   {
-                  RubikState.switchState( act, RubikState.DONE);
+                  StateList.switchState( act, StateList.DONE);
                   }
                 });
               }
diff --git a/src/main/java/org/distorted/main/RubikSurfaceView.java b/src/main/java/org/distorted/main/RubikSurfaceView.java
index 375d50b9..66347bdf 100644
--- a/src/main/java/org/distorted/main/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/main/RubikSurfaceView.java
@@ -35,7 +35,7 @@ import org.distorted.library.type.Static4D;
 import org.distorted.objects.TwistyObject;
 import org.distorted.objects.Movement;
 import org.distorted.solvers.SolverMain;
-import org.distorted.states.RubikState;
+import org.distorted.states.StateList;
 import org.distorted.states.RubikStatePlay;
 import org.distorted.states.RubikStateSolver;
 import org.distorted.states.RubikStateSolving;
@@ -295,7 +295,7 @@ public class RubikSurfaceView extends GLSurfaceView
 
     private void setUpDragOrRotate(boolean down, float x, float y)
       {
-      int mode = RubikState.getMode();
+      int mode = StateList.getMode();
 
       if( mode==MODE_DRAG )
         {
@@ -324,7 +324,7 @@ public class RubikSurfaceView extends GLSurfaceView
 
             if( down )
               {
-              RubikStateSolver solver = (RubikStateSolver) RubikState.SVER.getStateClass();
+              RubikStateSolver solver = (RubikStateSolver) StateList.SVER.getStateClass();
               mLastCubitFace = mMovement.getTouchedFace();
               float[] point = mMovement.getTouchedPoint3D();
               int color = solver.getCurrentColor();
@@ -413,14 +413,14 @@ public class RubikSurfaceView extends GLSurfaceView
 
       if( angle!=0 )
         {
-        if( RubikState.getCurrentState()==RubikState.SOLV )
+        if( StateList.getCurrentState()== StateList.SOLV )
           {
-          RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
+          RubikStateSolving solving = (RubikStateSolving) StateList.SOLV.getStateClass();
           solving.addMove(mCurrentAxis, mCurrentRow, angle);
           }
-        if( RubikState.getCurrentState()==RubikState.PLAY )
+        if( StateList.getCurrentState()== StateList.PLAY )
           {
-          RubikStatePlay play = (RubikStatePlay)RubikState.PLAY.getStateClass();
+          RubikStatePlay play = (RubikStatePlay) StateList.PLAY.getStateClass();
           play.addMove(mCurrentAxis, mCurrentRow, angle);
           }
         }
@@ -474,9 +474,9 @@ public class RubikSurfaceView extends GLSurfaceView
 
       object.beginNewRotation( mCurrentAxis, mCurrentRow );
 
-      if( RubikState.getCurrentState()==RubikState.READ )
+      if( StateList.getCurrentState()== StateList.READ )
         {
-        RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
+        RubikStateSolving solving = (RubikStateSolving) StateList.SOLV.getStateClass();
         solving.resetElapsed();
 
         final RubikActivity act = (RubikActivity)getContext();
@@ -486,7 +486,7 @@ public class RubikSurfaceView extends GLSurfaceView
           @Override
           public void run()
             {
-            RubikState.switchState( act, RubikState.SOLV);
+            StateList.switchState( act, StateList.SOLV);
             }
           });
         }
diff --git a/src/main/java/org/distorted/solvers/SolverMain.java b/src/main/java/org/distorted/solvers/SolverMain.java
index b6ab9433..85cd4b0d 100644
--- a/src/main/java/org/distorted/solvers/SolverMain.java
+++ b/src/main/java/org/distorted/solvers/SolverMain.java
@@ -23,7 +23,7 @@ import android.content.res.Resources;
 
 import org.distorted.main.R;
 import org.distorted.objects.ObjectList;
-import org.distorted.states.RubikState;
+import org.distorted.states.StateList;
 import org.distorted.states.RubikStateSolver;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -119,7 +119,7 @@ public class SolverMain implements Runnable
 
   public void run()
     {
-    RubikStateSolver solver = (RubikStateSolver) RubikState.SVER.getStateClass();
+    RubikStateSolver solver = (RubikStateSolver) StateList.SVER.getStateClass();
 
     if( mObject == ObjectList.CUBE && mSize == 3)
       {
diff --git a/src/main/java/org/distorted/states/RubikState.java b/src/main/java/org/distorted/states/RubikState.java
deleted file mode 100644
index f98b44ac..00000000
--- a/src/main/java/org/distorted/states/RubikState.java
+++ /dev/null
@@ -1,182 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.states;
-
-import android.content.SharedPreferences;
-import android.os.Bundle;
-
-import com.google.firebase.analytics.FirebaseAnalytics;
-
-import org.distorted.main.RubikActivity;
-import static org.distorted.main.RubikSurfaceView.*;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public enum RubikState
-  {
-  PLAY ( null , MODE_ROTATE , new RubikStatePlay()     ),
-  SOLV ( PLAY , MODE_ROTATE , new RubikStateSolving()  ),
-  PATT ( PLAY , MODE_DRAG   , new RubikStatePattern()  ),
-  SVER ( PLAY , MODE_REPLACE, new RubikStateSolver()   ),
-  SOLU ( SVER , MODE_DRAG   , new RubikStateSolution() ),
-  READ ( PLAY , MODE_ROTATE , new RubikStateReady()    ),
-  DONE ( PLAY , MODE_DRAG   , new RubikStateDone()     ),
-  ;
-
-  public static final int LENGTH = values().length;
-  private final RubikState mBack;
-  private int mMode;
-  private final RubikStateAbstract mClass;
-  private static final RubikState[] states;
-
-  private static RubikState mCurrState;
-
-  static
-    {
-    int i = 0;
-    states = new RubikState[LENGTH];
-
-    for(RubikState state: RubikState.values())
-      {
-      states[i] = state;
-      i++;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static RubikState getState(int ordinal)
-    {
-    return ordinal>=0 && ordinal<LENGTH ?  states[ordinal] : PLAY;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static RubikState getStateFromName(String name)
-    {
-    for(int i=0; i<LENGTH; i++)
-      {
-      if( name.equals(states[i].name()) )
-        {
-        return states[i];
-        }
-      }
-
-    return PLAY;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static RubikState getCurrentState()
-    {
-    return mCurrState;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int getMode()
-    {
-    return mCurrState.mMode;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void savePreferences(SharedPreferences.Editor editor)
-    {
-    editor.putString("curr_state_name", mCurrState.name() );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void restorePreferences(SharedPreferences preferences)
-    {
-    String currStateName = preferences.getString("curr_state_name", RubikState.PLAY.name() );
-    mCurrState = getStateFromName(currStateName);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void goBack(RubikActivity act)
-    {
-    switchState(act, mCurrState.mBack );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void setState(RubikActivity act)
-    {
-    mCurrState.enterState(act);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void switchState(RubikActivity act, RubikState next)
-    {
-    if( next!=null )
-      {
-      FirebaseAnalytics analytics = act.getAnalytics();
-
-      if( analytics!=null )
-        {
-        Bundle bundle = new Bundle();
-        bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, next.toString());
-        analytics.logEvent(FirebaseAnalytics.Event.LEVEL_START, bundle);
-        }
-
-      if( mCurrState!=null ) mCurrState.leaveState(act);
-      next.enterState(act);
-      mCurrState = next;
-      }
-    else
-      {
-      act.finish();
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  RubikState(RubikState back, int mode, RubikStateAbstract clazz)
-    {
-    mBack = back;
-    mMode = mode;
-    mClass= clazz;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public RubikStateAbstract getStateClass()
-    {
-    return mClass;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void leaveState(RubikActivity act)
-    {
-    mClass.leaveState(act);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void enterState(RubikActivity act)
-    {
-    mClass.enterState(act);
-    }
-  }
\ No newline at end of file
diff --git a/src/main/java/org/distorted/states/RubikStateDone.java b/src/main/java/org/distorted/states/RubikStateDone.java
index 3f44ff20..ea2163be 100644
--- a/src/main/java/org/distorted/states/RubikStateDone.java
+++ b/src/main/java/org/distorted/states/RubikStateDone.java
@@ -90,7 +90,7 @@ public class RubikStateDone extends RubikStateAbstract
       @Override
       public void onClick(View v)
         {
-        RubikState.goBack(act);
+        StateList.goBack(act);
         }
       });
 
diff --git a/src/main/java/org/distorted/states/RubikStatePattern.java b/src/main/java/org/distorted/states/RubikStatePattern.java
index 7f9c0e33..5abbd2b6 100644
--- a/src/main/java/org/distorted/states/RubikStatePattern.java
+++ b/src/main/java/org/distorted/states/RubikStatePattern.java
@@ -60,7 +60,7 @@ public class RubikStatePattern extends RubikStateAbstract
 
   void leaveState(RubikActivity act)
     {
-    RubikStatePlay play = (RubikStatePlay)RubikState.PLAY.getStateClass();
+    RubikStatePlay play = (RubikStatePlay) StateList.PLAY.getStateClass();
 
     ObjectList object = RubikPatternList.getObject(mPatternOrdinal);
     int size = RubikPatternList.getSize(mPatternOrdinal);
@@ -82,7 +82,7 @@ public class RubikStatePattern extends RubikStateAbstract
     mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
     mTitleSize  = width*RubikActivity.TITLE_TEXT_SIZE;
 
-    RubikStatePlay play = (RubikStatePlay)RubikState.PLAY.getStateClass();
+    RubikStatePlay play = (RubikStatePlay) StateList.PLAY.getStateClass();
     int obj  = play.getObject();
     int size = play.getSize();
 
@@ -201,7 +201,7 @@ public class RubikStatePattern extends RubikStateAbstract
           {
           diag.rememberState();
           diag.dismiss();
-          RubikState.goBack(act);
+          StateList.goBack(act);
           }
         }
       });
diff --git a/src/main/java/org/distorted/states/RubikStatePlay.java b/src/main/java/org/distorted/states/RubikStatePlay.java
index 06768889..f1692766 100644
--- a/src/main/java/org/distorted/states/RubikStatePlay.java
+++ b/src/main/java/org/distorted/states/RubikStatePlay.java
@@ -420,7 +420,7 @@ public class RubikStatePlay extends RubikStateAbstract implements RubikPreRender
           @Override
           public void onClick(View v)
             {
-            if( act.getPreRender().canPlay() && RubikState.getCurrentState()==RubikState.PLAY )
+            if( act.getPreRender().canPlay() && StateList.getCurrentState()== StateList.PLAY )
               {
               mObject = obj;
               mSize   = sizes[index];
@@ -546,7 +546,7 @@ public class RubikStatePlay extends RubikStateAbstract implements RubikPreRender
     {
     switch(button)
       {
-      case 0: RubikStatePlay play = (RubikStatePlay) RubikState.PLAY.getStateClass();
+      case 0: RubikStatePlay play = (RubikStatePlay) StateList.PLAY.getStateClass();
               int object = play.getObject();
               int size   = play.getSize();
               int sizeIndex = ObjectList.getSizeIndex(object,size);
@@ -559,9 +559,9 @@ public class RubikStatePlay extends RubikStateAbstract implements RubikPreRender
               scores.setArguments(bundle);
               scores.show(act.getSupportFragmentManager(), null);
               break;
-      case 1: RubikState.switchState(act,RubikState.PATT);
+      case 1: StateList.switchState(act, StateList.PATT);
               break;
-      case 2: RubikState.switchState(act,RubikState.SVER);
+      case 2: StateList.switchState(act, StateList.SVER);
               break;
       case 3: RubikDialogAbout diag = new RubikDialogAbout();
               diag.show(act.getSupportFragmentManager(), null);
diff --git a/src/main/java/org/distorted/states/RubikStateReady.java b/src/main/java/org/distorted/states/RubikStateReady.java
index 2cd38f20..bdf64cb2 100644
--- a/src/main/java/org/distorted/states/RubikStateReady.java
+++ b/src/main/java/org/distorted/states/RubikStateReady.java
@@ -109,7 +109,7 @@ public class RubikStateReady extends RubikStateAbstract
       @Override
       public void onClick(View v)
         {
-        RubikState.goBack(act);
+        StateList.goBack(act);
         }
       });
     }
diff --git a/src/main/java/org/distorted/states/RubikStateSolution.java b/src/main/java/org/distorted/states/RubikStateSolution.java
index d254f650..0d96d8c5 100644
--- a/src/main/java/org/distorted/states/RubikStateSolution.java
+++ b/src/main/java/org/distorted/states/RubikStateSolution.java
@@ -213,7 +213,7 @@ public class RubikStateSolution extends RubikStateAbstract implements RubikPreRe
       @Override
       public void onClick(View v)
         {
-        RubikState.goBack(act);
+        StateList.goBack(act);
         }
       });
     }
diff --git a/src/main/java/org/distorted/states/RubikStateSolver.java b/src/main/java/org/distorted/states/RubikStateSolver.java
index bff415bd..847cdcc8 100644
--- a/src/main/java/org/distorted/states/RubikStateSolver.java
+++ b/src/main/java/org/distorted/states/RubikStateSolver.java
@@ -87,7 +87,7 @@ public class RubikStateSolver extends RubikStateAbstract
     mCurrentObjectSize = ImplementedSolversList.getObjectSize(0);
 
     act.setupObject(mCurrentObject, mCurrentObjectSize, null);
-    RubikStatePlay play = (RubikStatePlay)RubikState.PLAY.getStateClass();
+    RubikStatePlay play = (RubikStatePlay) StateList.PLAY.getStateClass();
     play.setObjectAndSize(act, mCurrentObject, mCurrentObjectSize);
 
     mFaceColors = ObjectList.retFaceColors(mCurrentObject);
@@ -257,7 +257,7 @@ public class RubikStateSolver extends RubikStateAbstract
         {
         RubikPreRender pre = act.getPreRender();
         pre.resetAllTextureMaps();
-        RubikState.goBack(act);
+        StateList.goBack(act);
         }
       });
     }
@@ -316,8 +316,8 @@ public class RubikStateSolver extends RubikStateAbstract
         @Override
         public void run()
           {
-          RubikState.switchState(act,RubikState.SOLU);
-          RubikStateSolution solution = (RubikStateSolution) RubikState.SOLU.getStateClass();
+          StateList.switchState(act, StateList.SOLU);
+          RubikStateSolution solution = (RubikStateSolution) StateList.SOLU.getStateClass();
           solution.setupMoves(act, moves);
           }
         });
diff --git a/src/main/java/org/distorted/states/RubikStateSolving.java b/src/main/java/org/distorted/states/RubikStateSolving.java
index b6339499..793253ab 100644
--- a/src/main/java/org/distorted/states/RubikStateSolving.java
+++ b/src/main/java/org/distorted/states/RubikStateSolving.java
@@ -155,7 +155,7 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPreRen
       @Override
       public void onClick(View v)
         {
-        RubikState.goBack(act);
+        StateList.goBack(act);
         }
       });
     }
@@ -347,7 +347,7 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPreRen
 
       mElapsed = System.currentTimeMillis()-mStartTime;
 
-      RubikStatePlay play = (RubikStatePlay)RubikState.PLAY.getStateClass();
+      RubikStatePlay play = (RubikStatePlay) StateList.PLAY.getStateClass();
       int object  = play.getObject();
       int size    = play.getSize();
       int level   = play.getLevel();
diff --git a/src/main/java/org/distorted/states/StateList.java b/src/main/java/org/distorted/states/StateList.java
new file mode 100644
index 00000000..a869cfb9
--- /dev/null
+++ b/src/main/java/org/distorted/states/StateList.java
@@ -0,0 +1,182 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2020 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is free software: you can redistribute it and/or modify                            //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Magic Cube is distributed in the hope that it will be useful,                                 //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.states;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+import com.google.firebase.analytics.FirebaseAnalytics;
+
+import org.distorted.main.RubikActivity;
+import static org.distorted.main.RubikSurfaceView.*;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public enum StateList
+  {
+  PLAY ( null , MODE_ROTATE , new RubikStatePlay()     ),
+  SOLV ( PLAY , MODE_ROTATE , new RubikStateSolving()  ),
+  PATT ( PLAY , MODE_DRAG   , new RubikStatePattern()  ),
+  SVER ( PLAY , MODE_REPLACE, new RubikStateSolver()   ),
+  SOLU ( SVER , MODE_DRAG   , new RubikStateSolution() ),
+  READ ( PLAY , MODE_ROTATE , new RubikStateReady()    ),
+  DONE ( PLAY , MODE_DRAG   , new RubikStateDone()     ),
+  ;
+
+  public static final int LENGTH = values().length;
+  private final StateList mBack;
+  private int mMode;
+  private final RubikStateAbstract mClass;
+  private static final StateList[] states;
+
+  private static StateList mCurrState;
+
+  static
+    {
+    int i = 0;
+    states = new StateList[LENGTH];
+
+    for(StateList state: StateList.values())
+      {
+      states[i] = state;
+      i++;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static StateList getState(int ordinal)
+    {
+    return ordinal>=0 && ordinal<LENGTH ?  states[ordinal] : PLAY;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static StateList getStateFromName(String name)
+    {
+    for(int i=0; i<LENGTH; i++)
+      {
+      if( name.equals(states[i].name()) )
+        {
+        return states[i];
+        }
+      }
+
+    return PLAY;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static StateList getCurrentState()
+    {
+    return mCurrState;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static int getMode()
+    {
+    return mCurrState.mMode;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void savePreferences(SharedPreferences.Editor editor)
+    {
+    editor.putString("curr_state_name", mCurrState.name() );
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void restorePreferences(SharedPreferences preferences)
+    {
+    String currStateName = preferences.getString("curr_state_name", StateList.PLAY.name() );
+    mCurrState = getStateFromName(currStateName);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void goBack(RubikActivity act)
+    {
+    switchState(act, mCurrState.mBack );
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void setState(RubikActivity act)
+    {
+    mCurrState.enterState(act);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void switchState(RubikActivity act, StateList next)
+    {
+    if( next!=null )
+      {
+      FirebaseAnalytics analytics = act.getAnalytics();
+
+      if( analytics!=null )
+        {
+        Bundle bundle = new Bundle();
+        bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, next.toString());
+        analytics.logEvent(FirebaseAnalytics.Event.LEVEL_START, bundle);
+        }
+
+      if( mCurrState!=null ) mCurrState.leaveState(act);
+      next.enterState(act);
+      mCurrState = next;
+      }
+    else
+      {
+      act.finish();
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  StateList(StateList back, int mode, RubikStateAbstract clazz)
+    {
+    mBack = back;
+    mMode = mode;
+    mClass= clazz;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public RubikStateAbstract getStateClass()
+    {
+    return mClass;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void leaveState(RubikActivity act)
+    {
+    mClass.leaveState(act);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void enterState(RubikActivity act)
+    {
+    mClass.enterState(act);
+    }
+  }
\ No newline at end of file
