commit f03360375fc26eab710006810614e76cfaadcf58
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Apr 6 12:17:40 2020 +0100

    Make the Solver state more abstract.

diff --git a/src/main/java/org/distorted/objects/RubikCube.java b/src/main/java/org/distorted/objects/RubikCube.java
index 49dbb066..a07c62a0 100644
--- a/src/main/java/org/distorted/objects/RubikCube.java
+++ b/src/main/java/org/distorted/objects/RubikCube.java
@@ -225,4 +225,35 @@ class RubikCube extends RubikObject
     {
     return 1.0f;
     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public String retString()
+    {
+    String ret="UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB";
+/*
+		int color;
+		int F=retColor(FRONT , 1,1);
+		int B=retColor(BACK  , 1,1);
+		int L=retColor(LEFT  , 1,1);
+		int R=retColor(RIGHT , 1,1);
+		int U=retColor(TOP   , 1,1);
+		int D=retColor(BOTTOM, 1,1);
+
+		for(int face in {TOP,RIGHT,FRONT,BOTTOM,LEFT,BACK} )
+		  for(int row=0; row<mSize; row++)
+			  for(int col=0; col<mSize; col++)
+			    {
+				  color = retColor(TOP,col,row);
+
+				  if(color==F) ret+="F";
+				  if(color==B) ret+="B";
+				  if(color==L) ret+="L";
+				  if(color==R) ret+="R";
+				  if(color==U) ret+="U";
+				  if(color==D) ret+="D";
+			    }
+*/
+    return ret;
+    }
 }
diff --git a/src/main/java/org/distorted/objects/RubikObject.java b/src/main/java/org/distorted/objects/RubikObject.java
index d60825b7..c0ed5bd2 100644
--- a/src/main/java/org/distorted/objects/RubikObject.java
+++ b/src/main/java/org/distorted/objects/RubikObject.java
@@ -567,6 +567,13 @@ public abstract class RubikObject extends DistortedNode
     return mList;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public String retObjectString()
+    {
+    return retString();
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   abstract float getScreenRatio();
@@ -574,6 +581,7 @@ public abstract class RubikObject extends DistortedNode
   abstract Static3D[] getCubitPositions(int size);
   abstract float[] getLegalQuats();
   abstract int getNumFaces();
+  abstract String retString();
   abstract MeshBase createCubitMesh(int cubit, int vertices);
   abstract void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top, int side);
   public abstract Static3D[] getRotationAxis();
diff --git a/src/main/java/org/distorted/objects/RubikPyraminx.java b/src/main/java/org/distorted/objects/RubikPyraminx.java
index 29c21528..1e8d57bc 100644
--- a/src/main/java/org/distorted/objects/RubikPyraminx.java
+++ b/src/main/java/org/distorted/objects/RubikPyraminx.java
@@ -319,4 +319,12 @@ public class RubikPyraminx extends RubikObject
 
     return ((float)size)/(size-row);
     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// TODO
+
+  public String retString()
+    {
+    return "";
+    }
 }
diff --git a/src/main/java/org/distorted/solvers/Solver.java b/src/main/java/org/distorted/solvers/Solver.java
new file mode 100644
index 00000000..f85dbd62
--- /dev/null
+++ b/src/main/java/org/distorted/solvers/Solver.java
@@ -0,0 +1,95 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.solvers;
+
+import android.content.res.Resources;
+
+import org.distorted.main.R;
+import org.distorted.main.RubikActivity;
+import org.distorted.states.RubikState;
+import org.distorted.states.RubikStateSolver;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class Solver implements Runnable
+{
+  private String mObjectPosition;
+  private RubikActivity mAct;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public Solver(RubikActivity act, String position )
+    {
+    mObjectPosition = position;
+    mAct            = act;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void start()
+    {
+    Thread thr = new Thread(this);
+    thr.start();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void interrupt()
+    {
+    org.distorted.solvers.cube3.Search.interrupt();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void run()
+    {
+    Resources res = mAct.getResources();
+    RubikStateSolver solver = (RubikStateSolver) RubikState.SVER.getStateClass();
+    String result;
+
+    if( !org.distorted.solvers.cube3.Search.prepare(res) )
+      result= "Error 9";
+    else
+      result = org.distorted.solvers.cube3.Search.solution(mObjectPosition, 24, 20);
+
+    if (result.contains("Error"))
+      {
+      switch (result.charAt(result.length() - 1))
+        {
+        case '1': result = res.getString(R.string.error1); break;
+        case '2': result = res.getString(R.string.error2); break;
+        case '3': result = res.getString(R.string.error3); break;
+        case '4': result = res.getString(R.string.error4); break;
+        case '5': result = res.getString(R.string.error5); break;
+        case '6': result = res.getString(R.string.error6); break;
+        case '7': result = res.getString(R.string.error7); break;
+        case '8': result = res.getString(R.string.error8); break;
+        case '9': result = res.getString(R.string.error9); break;
+        }
+
+      solver.displayErrorDialog(mAct,result);
+      }
+    else
+      {
+      solver.setSolved( mAct, org.distorted.solvers.cube3.Search.numMoves(), result);
+      }
+    }
+}  
+
diff --git a/src/main/java/org/distorted/states/RubikStateSolver.java b/src/main/java/org/distorted/states/RubikStateSolver.java
index e7edde07..d678b8c7 100644
--- a/src/main/java/org/distorted/states/RubikStateSolver.java
+++ b/src/main/java/org/distorted/states/RubikStateSolver.java
@@ -20,7 +20,6 @@
 package org.distorted.states;
 
 import android.content.SharedPreferences;
-import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
@@ -38,7 +37,9 @@ import org.distorted.dialogs.RubikDialogSolverError;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
 import org.distorted.main.RubikPostRender;
+import org.distorted.objects.RubikObject;
 import org.distorted.objects.RubikObjectList;
+import org.distorted.solvers.Solver;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -60,76 +61,6 @@ public class RubikStateSolver extends RubikStateAbstract
   private boolean mSolving;
   private int mCurrentColor;
 
-  private class Solver implements Runnable
-    {
-    private String mCubeString;
-    private RubikActivity mAct;
-
-    ///////////////////////////////////////////////////
-
-    Solver(String str, RubikActivity act)
-      {
-      mCubeString = str;
-      mAct        = act;
-      }
-
-    ///////////////////////////////////////////////////
-
-    public void start()
-      {
-      Thread thr = new Thread(this);
-      thr.start();
-      }
-
-    ///////////////////////////////////////////////////
-
-    public void interrupt()
-      {
-      org.distorted.solvers.cube3.Search.interrupt();
-      }
-
-    ///////////////////////////////////////////////////
-
-    public void run()
-      {
-      Resources res = mAct.getResources();
-      String result;
-
-      if( !org.distorted.solvers.cube3.Search.prepare(res) )
-        result= "Error 9";
-      else
-        result = org.distorted.solvers.cube3.Search.solution(mCubeString, 24, 20);
-
-      mSolving = false;
-
-      if (result.contains("Error"))
-        {
-        switch (result.charAt(result.length() - 1))
-          {
-          case '1': result = res.getString(R.string.error1); break;
-          case '2': result = res.getString(R.string.error2); break;
-          case '3': result = res.getString(R.string.error3); break;
-          case '4': result = res.getString(R.string.error4); break;
-          case '5': result = res.getString(R.string.error5); break;
-          case '6': result = res.getString(R.string.error6); break;
-          case '7': result = res.getString(R.string.error7); break;
-          case '8': result = res.getString(R.string.error8); break;
-          case '9': result = res.getString(R.string.error9); break;
-          }
-
-        RubikDialogSolverError dialog = new RubikDialogSolverError();
-        Bundle bundle = new Bundle();
-        bundle.putString("error", result );
-        dialog.setArguments(bundle);
-        dialog.show( mAct.getSupportFragmentManager(), null);
-        }
-      else
-        {
-        setSolved( mAct, org.distorted.solvers.cube3.Search.numMoves(), result);
-        }
-      }
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   void leaveState(RubikActivity act)
@@ -175,22 +106,6 @@ public class RubikStateSolver extends RubikStateAbstract
     layoutRight.addView(mBackButton);
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setSolved( final RubikActivity act, final int numMoves, final String moves)
-    {
-    act.runOnUiThread(new Runnable()
-      {
-      @Override
-      public void run()
-        {
-        RubikState.switchState(act,RubikState.SOLU);
-        RubikStateSolution solution = (RubikStateSolution) RubikState.SOLU.getStateClass();
-        solution.setupMoves(act, numMoves, moves);
-        }
-      });
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private void setupBitmaps(float scale)
@@ -268,10 +183,11 @@ public class RubikStateSolver extends RubikStateAbstract
         {
         if( !mSolving )
           {
-          String cubeString = retCubeString();
-          Solver solver = new Solver(cubeString, act );
-          solver.start();
           mSolving = true;
+          RubikObject object = act.getObject();
+          String objectString = object.retObjectString();
+          Solver solver = new Solver( act, objectString );
+          solver.start();
           }
         }
       });
@@ -319,38 +235,6 @@ public class RubikStateSolver extends RubikStateAbstract
       }
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO
-
-  private String retCubeString()
-    {
-    String ret="UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB";
-/*
-		int color;
-		int F=retColor(FRONT , 1,1);
-		int B=retColor(BACK  , 1,1);
-		int L=retColor(LEFT  , 1,1);
-		int R=retColor(RIGHT , 1,1);
-		int U=retColor(TOP   , 1,1);
-		int D=retColor(BOTTOM, 1,1);
-
-		for(int face in {TOP,RIGHT,FRONT,BOTTOM,LEFT,BACK} )
-		  for(int row=0; row<mSize; row++)
-			  for(int col=0; col<mSize; col++)
-			    {
-				  color = retColor(TOP,col,row);
-
-				  if(color==F) ret+="F";
-				  if(color==B) ret+="B";
-				  if(color==L) ret+="L";
-				  if(color==R) ret+="R";
-				  if(color==U) ret+="U";
-				  if(color==D) ret+="D";
-			    }
-*/
-    return ret;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public void savePreferences(SharedPreferences.Editor editor)
@@ -375,4 +259,35 @@ public class RubikStateSolver extends RubikStateAbstract
     {
     return mCurrentColor;
     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void setSolved( final RubikActivity act, final int numMoves, final String moves)
+    {
+    mSolving = false;
+
+    act.runOnUiThread(new Runnable()
+      {
+      @Override
+      public void run()
+        {
+        RubikState.switchState(act,RubikState.SOLU);
+        RubikStateSolution solution = (RubikStateSolution) RubikState.SOLU.getStateClass();
+        solution.setupMoves(act, numMoves, moves);
+        }
+      });
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void displayErrorDialog( final RubikActivity act, String message)
+    {
+    mSolving = false;
+
+    RubikDialogSolverError dialog = new RubikDialogSolverError();
+    Bundle bundle = new Bundle();
+    bundle.putString("error", message );
+    dialog.setArguments(bundle);
+    dialog.show( act.getSupportFragmentManager(), null);
+    }
   }
