commit f5da732a3452d30e6e5206a71927c43b3efd4a93
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue May 4 00:52:30 2021 +0200

    Cube Control: step 2.

diff --git a/src/main/java/org/distorted/control/RubikControl.java b/src/main/java/org/distorted/control/RubikControl.java
new file mode 100644
index 00000000..e9b9f7bd
--- /dev/null
+++ b/src/main/java/org/distorted/control/RubikControl.java
@@ -0,0 +1,183 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2021 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.control;
+
+import org.distorted.library.message.EffectListener;
+import org.distorted.main.RubikActivity;
+
+import java.lang.ref.WeakReference;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class RubikControl implements EffectListener, Runnable
+  {
+  WeakReference<RubikActivity> mRefAct;
+  long mWholeID, mRotateID;
+  boolean mWholeReturned, mRotateReturned;
+
+long mRetID;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void addWholeObjects()
+    {
+    mWholeID = 0;
+
+    mRetID = mWholeID;
+
+    Thread networkThrd = new Thread(this);
+    networkThrd.start();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void addWholeEffects()
+    {
+
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void removeWholeObjects()
+    {
+
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void addRotateObjects()
+    {
+    mRotateID = 1;
+
+    mRetID = mRotateID;
+
+    Thread networkThrd = new Thread(this);
+    networkThrd.start();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void addRotateEffects()
+    {
+
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void removeRotateObjects()
+    {
+
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void animateCubeWhole()
+    {
+    addWholeObjects();
+    addWholeEffects();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void finishWhole()
+    {
+    removeWholeObjects();
+
+    mWholeReturned = true;
+
+    if( !mRotateReturned ) animateCubeRotate();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void animateCubeRotate()
+    {
+    addRotateObjects();
+    addRotateEffects();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void finishRotate()
+    {
+    removeRotateObjects();
+
+    mRotateReturned= true;
+
+    RubikActivity act = mRefAct.get();
+    if( act!=null ) act.unblockEverything();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC
+
+  @Override
+  public void run()
+    {
+    android.util.Log.e("D", "running...");
+
+    try
+      {
+      Thread.sleep(4000);
+      }
+    catch(InterruptedException ex)
+      {
+      // ignore
+      }
+
+    android.util.Log.e("D", "end running...");
+
+    effectFinished(mRetID);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void effectFinished(long effectID)
+    {
+    if( effectID==mWholeID  ) finishWhole();
+    if( effectID==mRotateID ) finishRotate();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void animateAll(RubikActivity act)
+    {
+    act.blockEverything();
+    mRefAct = new WeakReference<>(act);
+
+    mWholeReturned = false;
+    mRotateReturned= false;
+
+    animateCubeWhole();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void animateRotate(RubikActivity act)
+    {
+    act.blockEverything();
+    mRefAct = new WeakReference<>(act);
+
+    mWholeReturned = true;
+    mRotateReturned= false;
+
+    animateCubeRotate();
+    }
+  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java b/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
index 0382595f..517867ef 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
@@ -75,11 +75,11 @@ public class RubikDialogNewRecord extends AppCompatDialogFragment
         RubikScores scores = RubikScores.getInstance();
         String name = scores.getName();
         Bundle bundle = new Bundle();
-        ScreenList.switchState(act, ScreenList.PLAY);
+        ScreenList.switchScreen(act, ScreenList.PLAY);
 
         if( name.length()>0 )
           {
-          RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+          RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
           int object = play.getObject();
           int size   = play.getSize();
           int sizeIndex = ObjectList.getSizeIndex(object,size);
@@ -108,7 +108,7 @@ public class RubikDialogNewRecord extends AppCompatDialogFragment
       public void onClick(DialogInterface dialog, int which)
         {
         RubikActivity act = (RubikActivity)getActivity();
-        ScreenList.switchState(act, ScreenList.PLAY);
+        ScreenList.switchScreen(act, ScreenList.PLAY);
         }
       });
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java b/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
index b93adeff..3cfe697a 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
@@ -98,8 +98,8 @@ public class RubikDialogPatternView extends FrameLayout
 
         ract.setupObject(list, size, moves);
 
-        ScreenList.switchState(ract, ScreenList.PATT);
-        RubikScreenPattern state = (RubikScreenPattern) ScreenList.PATT.getStateClass();
+        ScreenList.switchScreen(ract, ScreenList.PATT);
+        RubikScreenPattern state = (RubikScreenPattern) ScreenList.PATT.getScreenClass();
         state.setPattern(ract, mTab, groupPosition, childPosition);
 
         mDialog.rememberState();
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogSetName.java b/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
index 91d3b181..6b0b1e77 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
@@ -144,9 +144,9 @@ public class RubikDialogSetName extends AppCompatDialogFragment
           name = name.replace(' ', '_');
 
           RubikActivity act = (RubikActivity)getActivity();
-          ScreenList.switchState(act, ScreenList.PLAY);
+          ScreenList.switchScreen(act, ScreenList.PLAY);
           RubikScores.getInstance().setName(name);
-          RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+          RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
 
           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 abccb696..73f9f934 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogSolved.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogSolved.java
@@ -69,7 +69,7 @@ public class RubikDialogSolved extends AppCompatDialogFragment
       public void onClick(DialogInterface dialog, int which)
         {
         RubikActivity act = (RubikActivity)getActivity();
-        ScreenList.switchState(act, ScreenList.PLAY);
+        ScreenList.switchScreen(act, ScreenList.PLAY);
         }
       });
 
diff --git a/src/main/java/org/distorted/main/RubikActivity.java b/src/main/java/org/distorted/main/RubikActivity.java
index ca9aba3b..79e7e694 100644
--- a/src/main/java/org/distorted/main/RubikActivity.java
+++ b/src/main/java/org/distorted/main/RubikActivity.java
@@ -87,7 +87,7 @@ public class RubikActivity extends AppCompatActivity
     private static int mScreenWidth, mScreenHeight;
     private boolean mPolicyAccepted, mIsChinese;
     private int mCurrentApiVersion;
-    private boolean mIsLocked;
+    private boolean mIsLocked, mRemLocked;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -242,7 +242,7 @@ public class RubikActivity extends AppCompatActivity
       view.onResume();
       view.initialize();
       restorePreferences();
-      ScreenList.setState(this);
+      ScreenList.setScreen(this);
 
       if( mJustStarted )
         {
@@ -253,7 +253,7 @@ public class RubikActivity extends AppCompatActivity
         }
 
       boolean success = false;
-      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
       int object = play.getObject();
       int size   = play.getSize();
 
@@ -307,7 +307,7 @@ public class RubikActivity extends AppCompatActivity
 
       for (int i = 0; i< ScreenList.LENGTH; i++)
         {
-        ScreenList.getState(i).getStateClass().savePreferences(editor);
+        ScreenList.getScreen(i).getScreenClass().savePreferences(editor);
         }
 
       ScreenList.savePreferences(editor);
@@ -332,7 +332,7 @@ public class RubikActivity extends AppCompatActivity
 
       for (int i = 0; i< ScreenList.LENGTH; i++)
         {
-        ScreenList.getState(i).getStateClass().restorePreferences(preferences);
+        ScreenList.getScreen(i).getScreenClass().restorePreferences(preferences);
         }
 
       ScreenList.restorePreferences(preferences);
@@ -545,7 +545,7 @@ public class RubikActivity extends AppCompatActivity
 
     public boolean isLocked()
       {
-      ScreenList state = ScreenList.getCurrentState();
+      ScreenList state = ScreenList.getCurrentScreen();
 
       if( state== ScreenList.PLAY || state== ScreenList.READ || state== ScreenList.SOLV )
         {
@@ -555,6 +555,27 @@ public class RubikActivity extends AppCompatActivity
       return false;
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void blockEverything()
+      {
+      mRemLocked = mIsLocked;
+      mIsLocked = true;
+
+      RubikPreRender pre = getPreRender();
+      pre.blockEverything();
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void unblockEverything()
+      {
+      mIsLocked = mRemLocked;
+
+      RubikPreRender pre = getPreRender();
+      pre.unblockEverything();
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     public boolean retLocked()
diff --git a/src/main/java/org/distorted/main/RubikPreRender.java b/src/main/java/org/distorted/main/RubikPreRender.java
index ec198622..2ca08ce5 100644
--- a/src/main/java/org/distorted/main/RubikPreRender.java
+++ b/src/main/java/org/distorted/main/RubikPreRender.java
@@ -172,9 +172,9 @@ public class RubikPreRender implements EffectController
 
     if( solved && !mIsSolved )
       {
-      if( ScreenList.getCurrentState()== ScreenList.SOLV )
+      if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
         {
-        RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getStateClass();
+        RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
         mNewRecord = solving.getRecord();
 
         if( mNewRecord< 0 )
@@ -349,7 +349,7 @@ public class RubikPreRender implements EffectController
 
   private void reportRecord()
     {
-    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
     RubikScores scores = RubikScores.getInstance();
 
     int object      = play.getObject();
@@ -556,6 +556,22 @@ public class RubikPreRender implements EffectController
     return mCanPlay;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void blockEverything()
+    {
+    mCanRotate = false;
+    mCanPlay   = false;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void unblockEverything()
+    {
+    mCanRotate = true;
+    mCanPlay   = true;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   void setQuatOnNextRender()
@@ -693,14 +709,14 @@ public class RubikPreRender implements EffectController
               @Override
               public void run()
                 {
-                ScreenList.switchState( act, ScreenList.READ);
+                ScreenList.switchScreen( act, ScreenList.READ);
                 }
               });
             }
 
           if( i==BaseEffect.Type.WIN.ordinal() )
             {
-            if( ScreenList.getCurrentState()== ScreenList.SOLV )
+            if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
               {
               final RubikActivity act = (RubikActivity)mView.getContext();
               Bundle bundle = new Bundle();
@@ -727,7 +743,7 @@ public class RubikPreRender implements EffectController
                 @Override
                 public void run()
                   {
-                  ScreenList.switchState( act, ScreenList.DONE);
+                  ScreenList.switchScreen( act, ScreenList.DONE);
                   }
                 });
               }
diff --git a/src/main/java/org/distorted/main/RubikSurfaceView.java b/src/main/java/org/distorted/main/RubikSurfaceView.java
index 60197f92..6c683369 100644
--- a/src/main/java/org/distorted/main/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/main/RubikSurfaceView.java
@@ -327,7 +327,7 @@ public class RubikSurfaceView extends GLSurfaceView
 
             if( down )
               {
-              RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getStateClass();
+              RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
               mLastCubitFace = mMovement.getTouchedFace();
               float[] point = mMovement.getTouchedPoint3D();
               int color = solver.getCurrentColor();
@@ -416,14 +416,14 @@ public class RubikSurfaceView extends GLSurfaceView
 
       if( angle!=0 )
         {
-        if( ScreenList.getCurrentState()== ScreenList.SOLV )
+        if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
           {
-          RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getStateClass();
+          RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
           solving.addMove(mCurrentAxis, mCurrentRow, angle);
           }
-        if( ScreenList.getCurrentState()== ScreenList.PLAY )
+        if( ScreenList.getCurrentScreen()== ScreenList.PLAY )
           {
-          RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+          RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
           play.addMove(mCurrentAxis, mCurrentRow, angle);
           }
         }
@@ -477,9 +477,9 @@ public class RubikSurfaceView extends GLSurfaceView
 
       object.beginNewRotation( mCurrentAxis, mCurrentRow );
 
-      if( ScreenList.getCurrentState()== ScreenList.READ )
+      if( ScreenList.getCurrentScreen()== ScreenList.READ )
         {
-        RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getStateClass();
+        RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
         solving.resetElapsed();
 
         final RubikActivity act = (RubikActivity)getContext();
@@ -489,7 +489,7 @@ public class RubikSurfaceView extends GLSurfaceView
           @Override
           public void run()
             {
-            ScreenList.switchState( act, ScreenList.SOLV);
+            ScreenList.switchScreen( act, ScreenList.SOLV);
             }
           });
         }
diff --git a/src/main/java/org/distorted/screens/RubikScreenAbstract.java b/src/main/java/org/distorted/screens/RubikScreenAbstract.java
index 73b4f480..81b20bfe 100644
--- a/src/main/java/org/distorted/screens/RubikScreenAbstract.java
+++ b/src/main/java/org/distorted/screens/RubikScreenAbstract.java
@@ -32,7 +32,7 @@ public abstract class RubikScreenAbstract
   {
   int getPatternOrdinal()
     {
-    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
     int obj  = play.getObject();
     int size = play.getSize();
     int ret = RubikPatternList.getOrdinal(obj,size);
@@ -49,7 +49,7 @@ public abstract class RubikScreenAbstract
 
   int getTutorialOrdinal()
     {
-    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
     int obj  = play.getObject();
     int size = play.getSize();
 
@@ -65,8 +65,8 @@ public abstract class RubikScreenAbstract
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  abstract void enterState(RubikActivity act);
-  abstract void leaveState(RubikActivity act);
+  abstract void enterScreen(RubikActivity act);
+  abstract void leaveScreen(RubikActivity act);
   public abstract void savePreferences(SharedPreferences.Editor editor);
   public abstract void restorePreferences(SharedPreferences preferences);
   }
diff --git a/src/main/java/org/distorted/screens/RubikScreenDone.java b/src/main/java/org/distorted/screens/RubikScreenDone.java
index df515a3c..e1c838f4 100644
--- a/src/main/java/org/distorted/screens/RubikScreenDone.java
+++ b/src/main/java/org/distorted/screens/RubikScreenDone.java
@@ -42,14 +42,14 @@ public class RubikScreenDone extends RubikScreenAbstract
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void leaveState(RubikActivity act)
+  void leaveScreen(RubikActivity act)
     {
 
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void enterState(final RubikActivity act)
+  void enterScreen(final RubikActivity act)
     {
     float width = act.getScreenWidthInPixels();
     float titleSize = width*RubikActivity.TITLE_TEXT_SIZE;
diff --git a/src/main/java/org/distorted/screens/RubikScreenPattern.java b/src/main/java/org/distorted/screens/RubikScreenPattern.java
index a13d2d6f..8475757b 100644
--- a/src/main/java/org/distorted/screens/RubikScreenPattern.java
+++ b/src/main/java/org/distorted/screens/RubikScreenPattern.java
@@ -58,9 +58,9 @@ public class RubikScreenPattern extends RubikScreenAbstract
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void leaveState(RubikActivity act)
+  void leaveScreen(RubikActivity act)
     {
-    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
 
     ObjectList object = RubikPatternList.getObject(mPatternOrdinal);
     int size = RubikPatternList.getSize(mPatternOrdinal);
@@ -76,7 +76,7 @@ public class RubikScreenPattern extends RubikScreenAbstract
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void enterState(final RubikActivity act)
+  void enterScreen(final RubikActivity act)
     {
     float width = act.getScreenWidthInPixels();
     mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
diff --git a/src/main/java/org/distorted/screens/RubikScreenPlay.java b/src/main/java/org/distorted/screens/RubikScreenPlay.java
index e1e2e9d3..fecf5623 100644
--- a/src/main/java/org/distorted/screens/RubikScreenPlay.java
+++ b/src/main/java/org/distorted/screens/RubikScreenPlay.java
@@ -33,6 +33,7 @@ import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.PopupWindow;
 
+import org.distorted.control.RubikControl;
 import org.distorted.dialogs.RubikDialogAbout;
 import org.distorted.dialogs.RubikDialogPattern;
 import org.distorted.dialogs.RubikDialogScores;
@@ -71,17 +72,18 @@ public class RubikScreenPlay extends RubikScreenBase
   private float mButtonSize, mMenuItemSize, mMenuTextSize;
   private int mColCount, mRowCount;
   private LinearLayout mPlayLayout;
+  private RubikControl mControlWhole;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void leaveState(RubikActivity act)
+  void leaveScreen(RubikActivity act)
     {
 
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void enterState(final RubikActivity act)
+  void enterScreen(final RubikActivity act)
     {
     float width = act.getScreenWidthInPixels();
 
@@ -285,7 +287,7 @@ public class RubikScreenPlay extends RubikScreenBase
           @Override
           public void onClick(View v)
             {
-            if( act.getPreRender().canPlay() && ScreenList.getCurrentState()== ScreenList.PLAY )
+            if( act.getPreRender().canPlay() && ScreenList.getCurrentScreen()== ScreenList.PLAY )
               {
               mObject = obj;
               mSize   = sizes[index];
@@ -369,20 +371,13 @@ public class RubikScreenPlay extends RubikScreenBase
     adjustLevels(act);
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void controlTheCube()
-    {
-    android.util.Log.e("D", "Control");
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private void MenuAction(RubikActivity act, int button)
     {
     switch(button)
       {
-      case 0: RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+      case 0: RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
               int object = play.getObject();
               int size   = play.getSize();
               int sizeIndex = ObjectList.getSizeIndex(object,size);
@@ -400,9 +395,10 @@ public class RubikScreenPlay extends RubikScreenBase
               pDiag.setArguments(pBundle);
               pDiag.show( act.getSupportFragmentManager(), RubikDialogPattern.getDialogTag() );
               break;
-      case 2: controlTheCube();
+      case 2: if( mControlWhole==null ) mControlWhole = new RubikControl();
+              mControlWhole.animateAll(act);
               break;
-      case 3: ScreenList.switchState(act, ScreenList.SVER);
+      case 3: ScreenList.switchScreen(act, ScreenList.SVER);
               break;
       case 4: RubikDialogTutorial tDiag = new RubikDialogTutorial();
               Bundle tBundle = new Bundle();
diff --git a/src/main/java/org/distorted/screens/RubikScreenReady.java b/src/main/java/org/distorted/screens/RubikScreenReady.java
index f06780a7..61fa1c06 100644
--- a/src/main/java/org/distorted/screens/RubikScreenReady.java
+++ b/src/main/java/org/distorted/screens/RubikScreenReady.java
@@ -38,14 +38,14 @@ public class RubikScreenReady extends RubikScreenBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void leaveState(RubikActivity act)
+  void leaveScreen(RubikActivity act)
     {
 
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void enterState(final RubikActivity act)
+  void enterScreen(final RubikActivity act)
     {
     float width = act.getScreenWidthInPixels();
     float titleSize = width*RubikActivity.TITLE_TEXT_SIZE;
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolution.java b/src/main/java/org/distorted/screens/RubikScreenSolution.java
index ee61fe8b..28375489 100644
--- a/src/main/java/org/distorted/screens/RubikScreenSolution.java
+++ b/src/main/java/org/distorted/screens/RubikScreenSolution.java
@@ -49,7 +49,7 @@ public class RubikScreenSolution extends RubikScreenAbstract implements RubikPre
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void leaveState(RubikActivity act)
+  void leaveScreen(RubikActivity act)
     {
     TwistyObject object = act.getObject();
     object.solve();
@@ -57,7 +57,7 @@ public class RubikScreenSolution extends RubikScreenAbstract implements RubikPre
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void enterState(final RubikActivity act)
+  void enterScreen(final RubikActivity act)
     {
     float width = act.getScreenWidthInPixels();
     mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolver.java b/src/main/java/org/distorted/screens/RubikScreenSolver.java
index 4bc19d5e..8ebb101d 100644
--- a/src/main/java/org/distorted/screens/RubikScreenSolver.java
+++ b/src/main/java/org/distorted/screens/RubikScreenSolver.java
@@ -62,14 +62,14 @@ public class RubikScreenSolver extends RubikScreenAbstract
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void leaveState(RubikActivity act)
+  void leaveScreen(RubikActivity act)
     {
 
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void enterState(final RubikActivity act)
+  void enterScreen(final RubikActivity act)
     {
     float width = act.getScreenWidthInPixels();
     float heigh = act.getScreenHeightInPixels();
@@ -87,7 +87,7 @@ public class RubikScreenSolver extends RubikScreenAbstract
     mCurrentObjectSize = ImplementedSolversList.getObjectSize(0);
 
     act.setupObject(mCurrentObject, mCurrentObjectSize, null);
-    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
     play.setObjectAndSize(act, mCurrentObject, mCurrentObjectSize);
 
     mFaceColors = ObjectList.retFaceColors(mCurrentObject);
@@ -292,8 +292,8 @@ public class RubikScreenSolver extends RubikScreenAbstract
         @Override
         public void run()
           {
-          ScreenList.switchState(act, ScreenList.SOLU);
-          RubikScreenSolution solution = (RubikScreenSolution) ScreenList.SOLU.getStateClass();
+          ScreenList.switchScreen(act, ScreenList.SOLU);
+          RubikScreenSolution solution = (RubikScreenSolution) ScreenList.SOLU.getScreenClass();
           solution.setupMoves(act, moves);
           }
         });
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolving.java b/src/main/java/org/distorted/screens/RubikScreenSolving.java
index 89b58ba5..07df9282 100644
--- a/src/main/java/org/distorted/screens/RubikScreenSolving.java
+++ b/src/main/java/org/distorted/screens/RubikScreenSolving.java
@@ -56,14 +56,14 @@ public class RubikScreenSolving extends RubikScreenBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void leaveState(RubikActivity act)
+  void leaveScreen(RubikActivity act)
     {
     stopCounting();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void enterState(final RubikActivity act)
+  void enterScreen(final RubikActivity act)
     {
     float width = act.getScreenWidthInPixels();
     float titleSize  = width*RubikActivity.TITLE_TEXT_SIZE;
@@ -171,7 +171,7 @@ public class RubikScreenSolving extends RubikScreenBase
 
       mElapsed = System.currentTimeMillis()-mStartTime;
 
-      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
       int object  = play.getObject();
       int size    = play.getSize();
       int level   = play.getLevel();
diff --git a/src/main/java/org/distorted/screens/ScreenList.java b/src/main/java/org/distorted/screens/ScreenList.java
index c30db604..b53fb2b8 100644
--- a/src/main/java/org/distorted/screens/ScreenList.java
+++ b/src/main/java/org/distorted/screens/ScreenList.java
@@ -41,41 +41,36 @@ public enum ScreenList
   ;
 
   public static final int LENGTH = values().length;
+  private static final ScreenList[] screens;
   private final ScreenList mBack;
-  private int mMode;
+  private final int mMode;
   private final RubikScreenAbstract mClass;
-  private static final ScreenList[] states;
 
-  private static ScreenList mCurrState;
+  private static ScreenList mCurrScreen;
 
   static
     {
     int i = 0;
-    states = new ScreenList[LENGTH];
-
-    for(ScreenList state: ScreenList.values())
-      {
-      states[i] = state;
-      i++;
-      }
+    screens = new ScreenList[LENGTH];
+    for(ScreenList state: ScreenList.values()) screens[i++] = state;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public static ScreenList getState(int ordinal)
+  public static ScreenList getScreen(int ordinal)
     {
-    return ordinal>=0 && ordinal<LENGTH ?  states[ordinal] : PLAY;
+    return ordinal>=0 && ordinal<LENGTH ?  screens[ordinal] : PLAY;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public static ScreenList getStateFromName(String name)
+  public static ScreenList getScreenFromName(String name)
     {
     for(int i=0; i<LENGTH; i++)
       {
-      if( name.equals(states[i].name()) )
+      if( name.equals(screens[i].name()) )
         {
-        return states[i];
+        return screens[i];
         }
       }
 
@@ -84,50 +79,50 @@ public enum ScreenList
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public static ScreenList getCurrentState()
+  public static ScreenList getCurrentScreen()
     {
-    return mCurrState;
+    return mCurrScreen;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public static int getMode()
     {
-    return mCurrState.mMode;
+    return mCurrScreen.mMode;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public static void savePreferences(SharedPreferences.Editor editor)
     {
-    editor.putString("curr_state_name", mCurrState.name() );
+    editor.putString("curr_state_name", mCurrScreen.name() );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public static void restorePreferences(SharedPreferences preferences)
     {
-    String currStateName = preferences.getString("curr_state_name", ScreenList.PLAY.name() );
-    mCurrState = getStateFromName(currStateName);
+    String currScreenName = preferences.getString("curr_state_name", ScreenList.PLAY.name() );
+    mCurrScreen = getScreenFromName(currScreenName);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public static void goBack(RubikActivity act)
     {
-    switchState(act, mCurrState.mBack );
+    switchScreen(act, mCurrScreen.mBack );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public static void setState(RubikActivity act)
+  public static void setScreen(RubikActivity act)
     {
-    mCurrState.enterState(act);
+    mCurrScreen.enterScreen(act);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public static void switchState(RubikActivity act, ScreenList next)
+  public static void switchScreen(RubikActivity act, ScreenList next)
     {
     if( next!=null )
       {
@@ -140,9 +135,9 @@ public enum ScreenList
         analytics.logEvent(FirebaseAnalytics.Event.LEVEL_START, bundle);
         }
 
-      if( mCurrState!=null ) mCurrState.leaveState(act);
-      next.enterState(act);
-      mCurrState = next;
+      if( mCurrScreen !=null ) mCurrScreen.leaveScreen(act);
+      next.enterScreen(act);
+      mCurrScreen = next;
       }
     else
       {
@@ -161,22 +156,22 @@ public enum ScreenList
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public RubikScreenAbstract getStateClass()
+  public RubikScreenAbstract getScreenClass()
     {
     return mClass;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void leaveState(RubikActivity act)
+  public void leaveScreen(RubikActivity act)
     {
-    mClass.leaveState(act);
+    mClass.leaveScreen(act);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void enterState(RubikActivity act)
+  public void enterScreen(RubikActivity act)
     {
-    mClass.enterState(act);
+    mClass.enterScreen(act);
     }
   }
\ No newline at end of file
diff --git a/src/main/java/org/distorted/solvers/SolverMain.java b/src/main/java/org/distorted/solvers/SolverMain.java
index af625b61..2f614065 100644
--- a/src/main/java/org/distorted/solvers/SolverMain.java
+++ b/src/main/java/org/distorted/solvers/SolverMain.java
@@ -119,7 +119,7 @@ public class SolverMain implements Runnable
 
   public void run()
     {
-    RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getStateClass();
+    RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
 
     if( mObject == ObjectList.CUBE && mSize == 3)
       {
diff --git a/src/main/java/org/distorted/tutorials/TutorialActivity.java b/src/main/java/org/distorted/tutorials/TutorialActivity.java
index 87f94f40..57409e3c 100644
--- a/src/main/java/org/distorted/tutorials/TutorialActivity.java
+++ b/src/main/java/org/distorted/tutorials/TutorialActivity.java
@@ -339,7 +339,7 @@ public class TutorialActivity extends AppCompatActivity
 
     public boolean isLocked()
       {
-      ScreenList state = ScreenList.getCurrentState();
+      ScreenList state = ScreenList.getCurrentScreen();
 
       if( state== ScreenList.PLAY || state== ScreenList.READ || state== ScreenList.SOLV )
         {
diff --git a/src/main/java/org/distorted/tutorials/TutorialState.java b/src/main/java/org/distorted/tutorials/TutorialState.java
index 4b9c063d..11c19b9c 100644
--- a/src/main/java/org/distorted/tutorials/TutorialState.java
+++ b/src/main/java/org/distorted/tutorials/TutorialState.java
@@ -176,7 +176,7 @@ public class TutorialState implements RubikPreRender.ActionFinishedListener
       @Override
       public void onClick(View v)
         {
-        RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getStateClass();
+        RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
         int size = play.getSize();
         int object= play.getObject();
         int sizeIndex = ObjectList.getSizeIndex(object,size);
