commit 2e8ec6278f942f20faa205e93eb839dc11648ebf
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sat Apr 25 23:45:23 2020 +0100

    Fixes for the fact that one could easily cheat - just pause the app while solving and come back to it, the time would reset to 0 and the object to unscrambled :(

diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java b/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
index 2e17755c..447ad08a 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
@@ -159,7 +159,7 @@ public class RubikDialogPatternView extends FrameLayout implements AdapterView.O
           RubikObjectList list = RubikPatternList.getObject(mTab);
           int size             = RubikPatternList.getSize(mTab);
 
-          act.changeObject( list, size, moves);
+          act.setupObject( list, size, moves);
 
           RubikStatePattern state = (RubikStatePattern) RubikState.PATT.getStateClass();
           state.setPattern(act, mTab, category, ii);
diff --git a/src/main/java/org/distorted/main/RubikActivity.java b/src/main/java/org/distorted/main/RubikActivity.java
index 3667768b..0cc1bea9 100644
--- a/src/main/java/org/distorted/main/RubikActivity.java
+++ b/src/main/java/org/distorted/main/RubikActivity.java
@@ -102,7 +102,7 @@ public class RubikActivity extends AppCompatActivity
         if( sizeIndex>=0 && sizeIndex<sizes.length )
           {
           success = true;
-          view.getPostRender().changeObject( obj, size, null );
+          view.getPostRender().changeObject(obj,size);
           }
 
         }
@@ -113,7 +113,7 @@ public class RubikActivity extends AppCompatActivity
         int s = RubikStatePlay.DEF_SIZE;
 
         play.setObjectAndSize(obj,s);
-        view.getPostRender().changeObject(obj,s, null);
+        view.getPostRender().changeObject(obj,s);
         }
       }
     
@@ -193,11 +193,20 @@ public class RubikActivity extends AppCompatActivity
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void changeObject(RubikObjectList object, int size, int[][] moves)
+    public void changeObject(RubikObjectList object, int size)
       {
       RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
       RubikPostRender post = view.getPostRender();
-      post.changeObject(object,size,moves);
+      post.changeObject(object,size);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void setupObject(RubikObjectList object, int size, int[][] moves)
+      {
+      RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
+      RubikPostRender post = view.getPostRender();
+      post.setupObject(object,size,moves);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/main/RubikPostRender.java b/src/main/java/org/distorted/main/RubikPostRender.java
index d2aeb580..cd2161a0 100644
--- a/src/main/java/org/distorted/main/RubikPostRender.java
+++ b/src/main/java/org/distorted/main/RubikPostRender.java
@@ -43,7 +43,7 @@ public class RubikPostRender implements EffectListener
 
   private RubikSurfaceView mView;
   private boolean mFinishRotation, mRemoveRotation, mRemovePatternRotation, mAddRotation,
-                  mSetQuatCurrent, mSetQuatAccumulated, mChangeObject, mSolveObject,
+                  mSetQuatCurrent, mSetQuatAccumulated, mChangeObject, mSetupObject, mSolveObject,
                   mScrambleObject, mInitializeObject, mSetTextureMap, mResetAllTextureMaps;
   private boolean mCanRotate, mCanPlay;
   private boolean mIsSolved;
@@ -77,6 +77,7 @@ public class RubikPostRender implements EffectListener
     mSetQuatCurrent       = false;
     mSetQuatAccumulated   = false;
     mChangeObject         = false;
+    mSetupObject          = false;
     mSolveObject          = false;
     mScrambleObject       = false;
 
@@ -233,6 +234,21 @@ public class RubikPostRender implements EffectListener
     {
     mChangeObject = false;
 
+    if ( mNewObject==null || mNewObject.getObjectList()!=mNextObject || mNewObject.getSize()!=mNextSize)
+      {
+      mCanRotate= false;
+      mCanPlay  = false;
+      createObjectNow(mNextObject, mNextSize, null);
+      doEffectNow( BaseEffect.Type.SIZECHANGE );
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void setupObjectNow()
+    {
+    mSetupObject = false;
+
     if ( mNewObject==null || mNewObject.getObjectList()!=mNextObject || mNewObject.getSize()!=mNextSize)
       {
       mCanRotate= false;
@@ -352,13 +368,25 @@ public class RubikPostRender implements EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void changeObject(RubikObjectList object, int size, int[][] moves)
+  void changeObject(RubikObjectList object, int size)
     {
     if( size>0 )
       {
       mChangeObject = true;
       mNextObject = object;
       mNextSize   = size;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void setupObject(RubikObjectList object, int size, int[][] moves)
+    {
+    if( size>0 )
+      {
+      mSetupObject= true;
+      mNextObject = object;
+      mNextSize   = size;
       mNextMoves  = moves;
       }
     }
@@ -412,6 +440,7 @@ public class RubikPostRender implements EffectListener
     if( mRemoveRotation        ) removeRotationNow();
     if( mRemovePatternRotation ) removePatternRotationNow();
     if( mChangeObject          ) changeObjectNow();
+    if( mSetupObject           ) setupObjectNow();
     if( mSolveObject           ) solveObjectNow();
     if( mScrambleObject        ) scrambleObjectNow();
     if( mAddRotation           ) addRotationNow();
diff --git a/src/main/java/org/distorted/main/RubikSurfaceView.java b/src/main/java/org/distorted/main/RubikSurfaceView.java
index 90b6b9d7..34005df6 100644
--- a/src/main/java/org/distorted/main/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/main/RubikSurfaceView.java
@@ -375,6 +375,9 @@ public class RubikSurfaceView extends GLSurfaceView
 
                                            if( RubikState.getCurrentState()==RubikState.READ )
                                              {
+                                             RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
+                                             solving.resetElapsed();
+
                                              final RubikActivity act = (RubikActivity)getContext();
 
                                              act.runOnUiThread(new Runnable()
@@ -385,9 +388,6 @@ public class RubikSurfaceView extends GLSurfaceView
                                                  RubikState.switchState( act, RubikState.SOLV);
                                                  }
                                                });
-
-                                             RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
-                                             solving.startCounting( (RubikActivity)getContext() );
                                              }
 
                                            mBeginningRotation = false;
diff --git a/src/main/java/org/distorted/states/RubikStatePattern.java b/src/main/java/org/distorted/states/RubikStatePattern.java
index c4b58e64..4228346c 100644
--- a/src/main/java/org/distorted/states/RubikStatePattern.java
+++ b/src/main/java/org/distorted/states/RubikStatePattern.java
@@ -71,7 +71,7 @@ public class RubikStatePattern extends RubikStateAbstract
       int objectPlay= play.getObject();
       int sizePlay  = play.getSize();
 
-      act.changeObject(RubikObjectList.getObject(objectPlay),sizePlay,null);
+      act.changeObject(RubikObjectList.getObject(objectPlay),sizePlay);
       }
     }
 
diff --git a/src/main/java/org/distorted/states/RubikStatePlay.java b/src/main/java/org/distorted/states/RubikStatePlay.java
index ed470183..94c2209d 100644
--- a/src/main/java/org/distorted/states/RubikStatePlay.java
+++ b/src/main/java/org/distorted/states/RubikStatePlay.java
@@ -280,7 +280,7 @@ public class RubikStatePlay extends RubikStateAbstract implements AdapterView.On
               {
               mObject = obj;
               mSize   = sizes[size];
-              act.changeObject(list,sizes[size],null);
+              act.changeObject(list,sizes[size]);
 
               int sizeIndex = RubikObjectList.getSizeIndex(mObject,mSize);
               int maxLevel  = RubikObjectList.getMaxLevel(mObject, sizeIndex);
diff --git a/src/main/java/org/distorted/states/RubikStateSolver.java b/src/main/java/org/distorted/states/RubikStateSolver.java
index 1ec031b6..95aaff2b 100644
--- a/src/main/java/org/distorted/states/RubikStateSolver.java
+++ b/src/main/java/org/distorted/states/RubikStateSolver.java
@@ -81,7 +81,7 @@ public class RubikStateSolver extends RubikStateAbstract
     mCurrentObject     = ImplementedSolversList.getObject(0);
     mCurrentObjectSize = ImplementedSolversList.getObjectSize(0);
 
-    act.changeObject(mCurrentObject, mCurrentObjectSize, null);
+    act.setupObject(mCurrentObject, mCurrentObjectSize, null);
     RubikStatePlay play = (RubikStatePlay)RubikState.PLAY.getStateClass();
     play.setObjectAndSize(mCurrentObject, mCurrentObjectSize);
 
diff --git a/src/main/java/org/distorted/states/RubikStateSolving.java b/src/main/java/org/distorted/states/RubikStateSolving.java
index ffaab1e8..a99e8cbe 100644
--- a/src/main/java/org/distorted/states/RubikStateSolving.java
+++ b/src/main/java/org/distorted/states/RubikStateSolving.java
@@ -53,6 +53,7 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPostRe
   private ImageButton mPrevButton;
   private boolean mCanPrevMove;
   private ArrayList<Move> mMoves;
+  private long mElapsed;
 
   private static class Move
     {
@@ -86,6 +87,8 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPostRe
     {
     mCanPrevMove = true;
 
+    startCounting(act);
+
     if( mMoves==null ) mMoves = new ArrayList<>();
     else               mMoves.clear();
 
@@ -97,7 +100,8 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPostRe
     LinearLayout layoutTop = act.findViewById(R.id.upperBar);
     layoutTop.removeAllViews();
     mTime = (TextView)inflater.inflate(R.layout.upper_text, null);
-    mTime.setText(act.getString(R.string.tm_placeholder,0,0));
+    int elapsed = (int)mElapsed/1000;
+    mTime.setText(act.getString(R.string.tm_placeholder,elapsed/60,elapsed%60));
     layoutTop.addView(mTime);
 
     // BOT ////////////////////////////
@@ -212,7 +216,8 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPostRe
     {
     mPrevButton = null;
 
-    editor.putLong("stateSolving_startTime" , mStartTime);
+    mElapsed = System.currentTimeMillis()-mStartTime;
+    editor.putLong("stateSolving_elapsed" , mElapsed);
     mScores.savePreferences(editor);
     }
 
@@ -220,18 +225,18 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPostRe
 
   public void restorePreferences(SharedPreferences preferences)
     {
-    mStartTime = preferences.getLong("stateSolving_startTime" , 0 );
+    mElapsed = preferences.getLong("stateSolving_elapsed" , 0 );
     mScores.restorePreferences(preferences);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void startCounting(final RubikActivity act)
+  private void startCounting(final RubikActivity act)
     {
     if( !mRunning )
       {
       mRunning = true;
-      mStartTime = System.currentTimeMillis();
+      mStartTime = System.currentTimeMillis() - mElapsed;
       mTimer = new Timer();
 
       mTimer.scheduleAtFixedRate(new TimerTask()
@@ -266,7 +271,7 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPostRe
         }
       mRunning = false;
 
-      long timeTaken = System.currentTimeMillis()-mStartTime;
+      mElapsed = System.currentTimeMillis()-mStartTime;
 
       RubikStatePlay play = (RubikStatePlay)RubikState.PLAY.getStateClass();
       int object  = play.getObject();
@@ -274,14 +279,21 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPostRe
       int level   = play.getLevel();
       int realSize= RubikObjectList.getSizeIndex(object,size);
 
-      boolean isNew = mScores.setRecord(object, realSize, level, timeTaken);
+      boolean isNew = mScores.setRecord(object, realSize, level, mElapsed);
 
-      return isNew ? timeTaken : -timeTaken;
+      return isNew ? mElapsed : -mElapsed;
       }
 
     return 0;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void resetElapsed()
+    {
+    mElapsed = 0;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public void onActionFinished(final long effectID)
