commit c86f9f1f122259b0481fd50a645f11aa124222cb
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Mar 13 17:43:17 2020 +0000

    Make the records independent of arrangement of Objects and their sizes in RubikObjectList.

diff --git a/src/main/java/org/distorted/object/RubikObjectList.java b/src/main/java/org/distorted/object/RubikObjectList.java
index e1a40c9e..6c012c2b 100644
--- a/src/main/java/org/distorted/object/RubikObjectList.java
+++ b/src/main/java/org/distorted/object/RubikObjectList.java
@@ -120,6 +120,33 @@ public enum RubikObjectList
     return mNumAll;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static int getOrdinal(String name)
+    {
+    for(int i=0; i<NUM_OBJECTS; i++)
+      {
+      if(objects[i].name().equals(name)) return i;
+      }
+
+    return -1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static int getSize(int ordinal, int size)
+    {
+    int[] sizes = objects[ordinal].getSizes();
+    int len = sizes.length;
+
+    for(int i=0; i<len; i++)
+      {
+      if( sizes[i]==size ) return i;
+      }
+
+    return -1;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   RubikObjectList(int[] sizes, int[] iconIDs, RubikObjectMovement movement)
diff --git a/src/main/java/org/distorted/uistate/RubikStateSolving.java b/src/main/java/org/distorted/uistate/RubikStateSolving.java
index ca3a560c..38440287 100644
--- a/src/main/java/org/distorted/uistate/RubikStateSolving.java
+++ b/src/main/java/org/distorted/uistate/RubikStateSolving.java
@@ -118,27 +118,78 @@ public class RubikStateSolving extends RubikStateAbstract
 
   public void savePreferences(SharedPreferences.Editor editor)
     {
-    for(int i=0; i<NUM_OBJECTS; i++)
-      for(int j=0; j<MAX_SIZE; j++)
-        for(int k=0; k<MAX_SCRAMBLE; k++)
+    StringBuilder builder = new StringBuilder();
+    RubikObjectList list;
+    int[] sizes;
+    int length;
+
+    for(int scramble=0; scramble<MAX_SCRAMBLE; scramble++)
+      {
+      builder.setLength(0);
+
+      for(int object=0; object<NUM_OBJECTS; object++)
+        {
+        list = RubikObjectList.getObject(object);
+        sizes = list.getSizes();
+        length = sizes.length;
+
+        for(int size=0; size<length; size++)
           {
-          if( mRecords[i][j][k]!=NO_RECORD)
-            {
-            editor.putLong("record_"+i+"_"+j+"_"+k, mRecords[i][j][k]);
-            }
+          builder.append(list.name());
+          builder.append("_");
+          builder.append(sizes[size]);
+          builder.append("=");
+          builder.append(mRecords[object][size][scramble]);
+          builder.append(" ");
           }
+        }
+
+      editor.putString("record"+scramble, builder.toString());
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public void restorePreferences(SharedPreferences preferences)
     {
-    for(int i=0; i<NUM_OBJECTS; i++)
-      for(int j=0; j<MAX_SIZE; j++)
-        for(int k=0; k<MAX_SCRAMBLE; k++)
+    String recordStr, subStr, nameStr, sizeStr, timeStr;
+    int start, end, equals, underscore;
+    int object, size, time;
+
+    for(int scramble=0; scramble<MAX_SCRAMBLE; scramble++)
+      {
+      start = end = 0;
+      recordStr = preferences.getString("record"+scramble, "");
+
+      //android.util.Log.e("solving", scramble+" record string: "+recordStr);
+
+      while( end!=-1 )
+        {
+        end = recordStr.indexOf(" ", start);
+
+        if( end==-1 ) subStr = recordStr.substring(start);
+        else          subStr = recordStr.substring(start,end);
+
+        start = end+1;
+
+        underscore = subStr.indexOf("_");
+        equals = subStr.indexOf("=");
+
+        if( underscore>=0 && equals>=0 )
           {
-          mRecords[i][j][k] = preferences.getLong("record_"+i+"_"+j+"_"+k, NO_RECORD );
+          nameStr = subStr.substring(0,underscore);
+          sizeStr = subStr.substring(underscore+1, equals);
+          timeStr = subStr.substring(equals+1);
+
+          object = RubikObjectList.getOrdinal(nameStr);
+          size   = RubikObjectList.getSize(object,Integer.parseInt(sizeStr));
+          time   = Integer.parseInt(timeStr);
+
+          //android.util.Log.e("solving", "parsed: nameStr="+nameStr+" sizeStr="+sizeStr+" timeStr="+timeStr);
+          mRecords[object][size][scramble] = time;
           }
+        }
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -191,11 +242,11 @@ public class RubikStateSolving extends RubikStateAbstract
       int scramble= play.getPicker();
       int maxsize = RubikObjectList.getObject(object).getSizes().length;
 
-      if( object>=0 && object< NUM_OBJECTS && size>=0 && size<maxsize && scramble>=0 && scramble<MAX_SCRAMBLE )
+      if( object>=0 && object< NUM_OBJECTS && size>=0 && size<maxsize && scramble>=1 && scramble<=MAX_SCRAMBLE )
         {
-        if( mRecords[object][size][scramble]> timeTaken )
+        if( mRecords[object][size][scramble-1]> timeTaken )
           {
-          mRecords[object][size][scramble] = timeTaken;
+          mRecords[object][size][scramble-1] = timeTaken;
           android.util.Log.e("solv","new record!");
           }
         }
