commit 3a9d19ed01d151d3c9f409db00fa85e95123d00d
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sat Mar 28 01:05:02 2020 +0000

    Progress with Pretty Patterns.

diff --git a/src/main/java/org/distorted/dialog/RubikDialogPattern.java b/src/main/java/org/distorted/dialog/RubikDialogPattern.java
index 712a57d1..3ae7d4af 100644
--- a/src/main/java/org/distorted/dialog/RubikDialogPattern.java
+++ b/src/main/java/org/distorted/dialog/RubikDialogPattern.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
+// Copyright 2020 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
@@ -21,7 +21,6 @@ package org.distorted.dialog;
 
 import android.app.Dialog;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.v4.app.FragmentActivity;
diff --git a/src/main/java/org/distorted/dialog/RubikDialogPatternPagerAdapter.java b/src/main/java/org/distorted/dialog/RubikDialogPatternPagerAdapter.java
index 91f44ab1..364f4d22 100644
--- a/src/main/java/org/distorted/dialog/RubikDialogPatternPagerAdapter.java
+++ b/src/main/java/org/distorted/dialog/RubikDialogPatternPagerAdapter.java
@@ -37,23 +37,6 @@ class RubikDialogPatternPagerAdapter extends PagerAdapter
   private RubikDialogPattern mDialog;
   private int mNumTabs;
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private String[] createCategories(int pos)
-    {
-    RubikPattern pattern = RubikPattern.getInstance();
-    int numCat = pattern.getNumCategories(pos);
-
-    String[] ret = new String[numCat];
-
-    for(int i=0; i<numCat; i++)
-      {
-      ret[i] = pattern.getCategoryName(pos,i);
-      }
-
-    return ret;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   RubikDialogPatternPagerAdapter(FragmentActivity act, ViewPager viewPager, RubikDialogPattern dialog)
@@ -73,8 +56,7 @@ class RubikDialogPatternPagerAdapter extends PagerAdapter
   @NonNull
   public Object instantiateItem(@NonNull ViewGroup collection, final int position)
     {
-    String[] categories = createCategories(position);
-    mViews[position] = new RubikDialogPatternView(mAct, mDialog, categories);
+    mViews[position] = new RubikDialogPatternView(mAct, mDialog, position);
     collection.addView(mViews[position]);
 
     return mViews[position];
diff --git a/src/main/java/org/distorted/dialog/RubikDialogPatternView.java b/src/main/java/org/distorted/dialog/RubikDialogPatternView.java
index 31914c91..b05e6432 100644
--- a/src/main/java/org/distorted/dialog/RubikDialogPatternView.java
+++ b/src/main/java/org/distorted/dialog/RubikDialogPatternView.java
@@ -24,20 +24,26 @@ import android.support.v4.app.FragmentActivity;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
 import android.widget.Button;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
+import android.widget.Spinner;
 
 import org.distorted.magic.R;
 import org.distorted.magic.RubikActivity;
+import org.distorted.patterns.RubikPattern;
 import org.distorted.uistate.RubikState;
+import org.distorted.uistate.RubikStatePattern;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class RubikDialogPatternView extends FrameLayout
+public class RubikDialogPatternView extends FrameLayout implements AdapterView.OnItemSelectedListener
   {
   private LinearLayout mLayout;
   private RubikDialogPattern mDialog;
+  private int mPosition;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -55,42 +61,94 @@ public class RubikDialogPatternView extends FrameLayout
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public RubikDialogPatternView(FragmentActivity act, RubikDialogPattern dialog, String[] categories)
+  public RubikDialogPatternView(FragmentActivity act, RubikDialogPattern dialog, int position)
     {
     super(act);
 
     mDialog = dialog;
+    mPosition = position;
     View tab = inflate( act, R.layout.dialog_pattern_tab, null);
     mLayout = tab.findViewById(R.id.tabLayout);
-    createSection(act,categories);
+
+    String[] categories = createCategories();
+
+    Spinner spinner = tab.findViewById(R.id.pattern_category_spinner);
+    spinner.setOnItemSelectedListener(this);
+
+    ArrayAdapter<String> adapter = new ArrayAdapter<>(act, android.R.layout.simple_spinner_item, categories);
+    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+    spinner.setAdapter(adapter);
+
+    spinner.setSelection(0);
 
     addView(tab);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void createSection(final FragmentActivity act, final String[] categories)
+  private String[] createCategories()
+    {
+    RubikPattern pattern = RubikPattern.getInstance();
+    int numCat = pattern.getNumCategories(mPosition);
+
+    String[] ret = new String[numCat];
+
+    for(int i=0; i<numCat; i++)
+      {
+      ret[i] = pattern.getCategoryName(mPosition,i);
+      }
+
+    return ret;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private String[] createPatterns(int category)
     {
+    RubikPattern pattern = RubikPattern.getInstance();
+    int numPat = pattern.getNumPatterns(mPosition, category);
+
+    String[] ret = new String[numPat];
+
+    for(int i=0; i<numPat; i++)
+      {
+      ret[i] = pattern.getPatternName(mPosition, category, i);
+      }
+
+    return ret;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void fillPatterns(int category)
+    {
+    final RubikActivity act = (RubikActivity)getContext();
+
     DisplayMetrics metrics = act.getResources().getDisplayMetrics();
     final float scale = metrics.density;
     int margin = (int)(3*scale + 0.5f);
     LinearLayout.LayoutParams bParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
     bParams.setMargins(margin, margin, margin, margin);
 
-    final RubikActivity ract = (RubikActivity)getContext();
+    final String[] patterns = createPatterns(category);
+    int len = patterns.length;
 
-    for(String category: categories)
+    mLayout.removeAllViews();
+
+    for(int i=0; i<len; i++)
       {
+      final int ii = i;
       Button button = new Button(act);
       button.setLayoutParams(bParams);
-      button.setText(category);
+      button.setText(patterns[i]);
 
       button.setOnClickListener( new View.OnClickListener()
         {
         @Override
         public void onClick(View view)
           {
-          RubikState.switchState(ract,RubikState.PATT);
+          RubikStatePattern state = (RubikStatePattern) RubikState.PATT.getStateClass();
+          state.setPatternName(patterns[ii]);
           mDialog.dismiss();
           }
         });
@@ -98,4 +156,23 @@ public class RubikDialogPatternView extends FrameLayout
       mLayout.addView(button);
       }
     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  @Override
+  public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
+    {
+    if( parent.getId() == R.id.pattern_category_spinner )
+      {
+      fillPatterns(pos);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  @Override
+  public void onNothingSelected(AdapterView<?> parent)
+    {
+
+    }
   }
diff --git a/src/main/java/org/distorted/patterns/RubikPattern.java b/src/main/java/org/distorted/patterns/RubikPattern.java
index 78e94214..fd8f7d52 100644
--- a/src/main/java/org/distorted/patterns/RubikPattern.java
+++ b/src/main/java/org/distorted/patterns/RubikPattern.java
@@ -41,80 +41,122 @@ public class RubikPattern
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private class Category
+  private static class Category
     {
     private String name;
-    private int numpatterns;
+    private int numPatterns;
     private Vector<Pattern> patterns;
-    private int curPattern;
+
+  /////////////////////////////////////////////////////////////
 
     Category(String n)
       {
       name=n;
-      curPattern=0;
-      numpatterns=0;
+      numPatterns=0;
       patterns = new Vector<>();
       }
+
+  /////////////////////////////////////////////////////////////
+
     void addPattern(Pattern p)
       {
       patterns.addElement(p);
-      numpatterns++;
+      numPatterns++;
       }
+
+  /////////////////////////////////////////////////////////////
+
     int getNumPatterns()
     {
-    return numpatterns;
+    return numPatterns;
     }
+
+  /////////////////////////////////////////////////////////////
+
     String getName()
     {
     return name;
     }
-    void next()
-      {
-      curPattern++;
-      if( curPattern>=numpatterns )
-        curPattern=0;
-      }
-    void prev()
-      {
-      curPattern--;
-      if( curPattern<0 )
-        curPattern=numpatterns-1;
-      }
-    String getPatternName()
+
+  /////////////////////////////////////////////////////////////
+
+    String getPatternName(int pattern)
       {
-      Pattern p = patterns.elementAt(curPattern);
-      return  p!=null ? p.getName(curPattern+1,numpatterns):null;
+      if( pattern>=0 && pattern<numPatterns )
+        {
+        Pattern p = patterns.elementAt(pattern);
+        return  p!=null ? p.getName():"";
+        }
+      return "";
       }
-    int getPatternCurMove()
+
+  /////////////////////////////////////////////////////////////
+
+    int getPatternCurMove(int pattern)
       {
-      Pattern p = patterns.elementAt(curPattern);
-      return  p!=null ? p.getCurMove():-1;
+      if( pattern>=0 && pattern<numPatterns )
+        {
+        Pattern p = patterns.elementAt(pattern);
+        return  p!=null ? p.getCurMove():-1;
+        }
+      return -1;
       }
-    int getPatternNumMove()
+
+  /////////////////////////////////////////////////////////////
+
+    int getPatternNumMove(int pattern)
       {
-      Pattern p = patterns.elementAt(curPattern);
-      return  p!=null ? p.getNumMove():-1;
+      if( pattern>=0 && pattern<numPatterns )
+        {
+        Pattern p = patterns.elementAt(pattern);
+        return  p!=null ? p.getNumMove():-1;
+        }
+      return -1;
       }
-    void initializeCube()
+
+  /////////////////////////////////////////////////////////////
+
+    String retInitializationString(int pattern)
       {
-      Pattern p = patterns.elementAt(curPattern);
-      if( p!=null ) p.initializeCube();
+      if( pattern>=0 && pattern<numPatterns )
+        {
+        Pattern p = patterns.elementAt(pattern);
+        if( p!=null ) return p.retInitializationString();
+        }
+
+      return "";
       }
-    void makeNextMove()
+
+  /////////////////////////////////////////////////////////////
+
+    String retNextMove(int pattern)
       {
-      Pattern p = patterns.elementAt(curPattern);
-      if( p!=null ) p.makeNextMove();
+      if( pattern>=0 && pattern<numPatterns )
+        {
+        Pattern p = patterns.elementAt(pattern);
+        if( p!=null ) return p.retNextMove();
+        }
+
+      return "";
       }
-    void makePrevMove()
+
+  /////////////////////////////////////////////////////////////
+
+    String retPrevMove(int pattern)
       {
-      Pattern p = patterns.elementAt(curPattern);
-      if( p!=null ) p.makePrevMove();
+      if( pattern>=0 && pattern<numPatterns )
+        {
+        Pattern p = patterns.elementAt(pattern);
+        if( p!=null ) return p.retPrevMove();
+        }
+
+      return "";
       }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private class Pattern
+  private static class Pattern
     {
     private String name;
     private String shortname=null;
@@ -122,6 +164,8 @@ public class RubikPattern
     private int curmove;
     private int nummove;
 
+  /////////////////////////////////////////////////////////////
+
     Pattern(String n, String m)
       {
       name=n;
@@ -129,56 +173,70 @@ public class RubikPattern
       nummove = moves.length()/4;
       curmove=nummove;
       }
-    String getName(int cur,int num)
+
+  /////////////////////////////////////////////////////////////
+
+    String getName()
       {
       if( shortname==null ) shortname=cutPatternName(name);
       return shortname;
       }
+
+  /////////////////////////////////////////////////////////////
+
     int getNumMove()
     {
     return nummove;
     }
+
+  /////////////////////////////////////////////////////////////
+
     int getCurMove()
     {
     return curmove;
     }
-    void makeNextMove()
+
+  /////////////////////////////////////////////////////////////
+
+    String retNextMove()
       {
       curmove++;
+
       if( curmove>nummove)
         {
         curmove= 0;
-        initializeCube();
+        return retInitializationString();
         }
       else
         {
-// TODO
-//        RubikCube cube = world.getCube();
-//        if( cube!=null && !cube.makeMove(moves.substring(4*curmove-4,4*curmove)) )
-          curmove--;
+        curmove--;
+        return moves.substring(4*curmove-4,4*curmove);
         }
       }
-    void makePrevMove()
+
+  /////////////////////////////////////////////////////////////
+
+    String retPrevMove()
       {
       curmove--;
+
       if( curmove<0)
         {
         curmove=nummove;
-        initializeCube();
+        return retInitializationString();
         }
       else
         {
-// TODO
-//        RubikCube cube = world.getCube();
-//        if( cube!=null && !cube.backMove(moves.substring(4*curmove,4*curmove+4)) )
-          curmove++;
+        curmove++;
+        return moves.substring(4*curmove,4*curmove+4);
         }
       }
-    void initializeCube()
+
+  /////////////////////////////////////////////////////////////
+
+    String retInitializationString()
       {
-// TODO
-//	    RubikCube cube = world.getCube();
-//      if( cube!=null ) cube.setupPosition(moves.substring(0,4*curmove));
+      return moves.substring(0,4*curmove);
       }
     }
 
@@ -187,7 +245,7 @@ public class RubikPattern
   private RubikPattern()
     {
     mPaint.setTextSize(24);
-    mWidth = 200;
+    mWidth = 300;
     mCategories = new Vector[NUM_CUBES];
 
     initializeCategories(0, RubikPatternData2.patterns);
@@ -265,6 +323,13 @@ public class RubikPattern
     return mThis;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getNumCategories(int size)
+    {
+    return size>=0 && size<NUM_CUBES ? numCategories[size] : 0;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public String getCategoryName(int size,int num)
@@ -280,12 +345,12 @@ public class RubikPattern
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public String getPatternName(int size,int num)
+  public String getPatternName(int size, int cat, int pat)
     {
-    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
+    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
       {
-      Category c = mCategories[size].elementAt(num);
-      return c!=null ? c.getPatternName() : null;
+      Category c = mCategories[size].elementAt(cat);
+      return c!=null ? c.getPatternName(pat) : null;
       }
 
     return null;
@@ -306,48 +371,12 @@ public class RubikPattern
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void nextPattern(int size, int num )
-    {
-    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
-      {
-      Category c = mCategories[size].elementAt(num);
-
-      if( c!=null )
-        {
-// TODO
-//        RubikMenu.texDirty[0] = true;
-        c.next();
-        c.initializeCube();
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void prevPattern(int size, int num )
-    {
-    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
-      {
-      Category c = mCategories[size].elementAt(num);
-
-      if( c!=null )
-        {
-// TODO
-//        RubikMenu.texDirty[0] = true;
-        c.prev();
-        c.initializeCube();
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getCurrPattern(int size, int num )
+  public int getCurMove(int size, int cat, int pat)
     {
-    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
+    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
       {
-      Category c = mCategories[size].elementAt(num);
-      return c!=null ? c.curPattern:0;
+      Category c = mCategories[size].elementAt(cat);
+      return c!=null ? c.getPatternCurMove(pat):0;
       }
 
     return 0;
@@ -355,12 +384,12 @@ public class RubikPattern
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getCurMove(int size, int num )
+  public int getNumMoves(int size, int cat, int pat)
     {
-    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
+    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
       {
-      Category c = mCategories[size].elementAt(num);
-      return c!=null ? c.getPatternCurMove():0;
+      Category c = mCategories[size].elementAt(cat);
+      return c!=null ? c.getPatternNumMove(pat):0;
       }
 
     return 0;
@@ -368,54 +397,40 @@ public class RubikPattern
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getNumMove(int size, int num )
+  public String retNextMove(int size, int cat, int pat)
     {
-    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
+    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
       {
-      Category c = mCategories[size].elementAt(num);
-      return c!=null ? c.getPatternNumMove():0;
+      Category c = mCategories[size].elementAt(cat);
+      if( c!=null ) return c.retNextMove(pat);
       }
 
-    return 0;
+    return "";
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void makeNextMove(int size, int num)
+  public String retPrevMove(int size, int cat, int pat)
     {
-    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
+    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
       {
-      Category c = mCategories[size].elementAt(num);
-      if( c!=null ) c.makeNextMove();
+      Category c = mCategories[size].elementAt(cat);
+      if( c!=null ) return c.retPrevMove(pat);
       }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void makePrevMove(int size, int num)
-    {
-    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
-      {
-      Category c = mCategories[size].elementAt(num);
-      if( c!=null ) c.makePrevMove();
-      }
+    return "";
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void initializeCube(int size,int num)
+  public String retInitializationString(int size,int cat, int pat)
     {
-    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
+    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
       {
-      Category c = mCategories[size].elementAt(num);
-      if( c!=null ) c.initializeCube();
+      Category c = mCategories[size].elementAt(cat);
+      if( c!=null ) return c.retInitializationString(pat);
       }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getNumCategories(int size)
-    {
-    return size>=0 && size<NUM_CUBES ? numCategories[size] : 0;
+    return "";
     }
 }
diff --git a/src/main/java/org/distorted/uistate/RubikStatePattern.java b/src/main/java/org/distorted/uistate/RubikStatePattern.java
index 545763ac..7942186c 100644
--- a/src/main/java/org/distorted/uistate/RubikStatePattern.java
+++ b/src/main/java/org/distorted/uistate/RubikStatePattern.java
@@ -39,6 +39,7 @@ import org.distorted.patterns.RubikPattern;
 
 public class RubikStatePattern extends RubikStateAbstract
   {
+  private TextView mText;
   private Button mBackButton;
   private int mSize;
 
@@ -92,9 +93,9 @@ public class RubikStatePattern extends RubikStateAbstract
     // TOP ////////////////////////////
     LinearLayout layoutTop = act.findViewById(R.id.mainTitle);
     layoutTop.removeAllViews();
-    TextView text = (TextView)inflater.inflate(R.layout.upper_text, null);
-    text.setText(R.string.patterns);
-    layoutTop.addView(text);
+    mText = (TextView)inflater.inflate(R.layout.upper_text, null);
+    mText.setText(R.string.patterns);
+    layoutTop.addView(mText);
 
     // BOT ////////////////////////////
     DisplayMetrics metrics = act.getResources().getDisplayMetrics();
@@ -154,6 +155,13 @@ public class RubikStatePattern extends RubikStateAbstract
       });
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void setPatternName(String name)
+    {
+    mText.setText(name);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public void savePreferences(SharedPreferences.Editor editor)
diff --git a/src/main/res/layout/dialog_pattern_tab.xml b/src/main/res/layout/dialog_pattern_tab.xml
index 1c67f764..49499866 100644
--- a/src/main/res/layout/dialog_pattern_tab.xml
+++ b/src/main/res/layout/dialog_pattern_tab.xml
@@ -1,17 +1,31 @@
 <?xml version="1.0" encoding="utf-8"?>
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/tabScrollView"
-    android:background="@color/grey"
-    android:paddingBottom="10dp"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <LinearLayout
-        android:id="@+id/tabLayout"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical" >
-    </LinearLayout>
 
-</ScrollView>
+    <Spinner
+        android:id="@+id/pattern_category_spinner"
+        android:layout_marginLeft="20dp"
+        android:layout_marginRight="20dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginBottom="10dp"
+        android:layout_width="match_parent"
+        android:layout_height="50dp"/>
+
+    <ScrollView
+        android:id="@+id/tabScrollView"
+        android:paddingBottom="10dp"
+        android:background="@color/grey"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <LinearLayout
+            android:id="@+id/tabLayout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+        </LinearLayout>
+    </ScrollView>
 
+</LinearLayout>
