commit 22fdfc36356db4da0e447c52903e316c48e396a1
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Jan 21 10:53:53 2020 +0000

    RubikCube: major progress with a separate RubikSettingsEnum enum - has been introduced into RubikSettings.

diff --git a/src/main/java/org/distorted/magic/RubikActivity.java b/src/main/java/org/distorted/magic/RubikActivity.java
index d92b18e9..a8470485 100644
--- a/src/main/java/org/distorted/magic/RubikActivity.java
+++ b/src/main/java/org/distorted/magic/RubikActivity.java
@@ -122,12 +122,12 @@ public class RubikActivity extends AppCompatActivity implements RubikSettings.On
       {
       Bundle args = new Bundle();
 
-      args.putInt("sizechangePos" , mSizeChangePos );
-      args.putInt("solvePos"      , mSolvePos      );
-      args.putInt("scramblePos"   , mScramblePos   );
-      args.putInt("sizechangeType", mSizeChangeType);
-      args.putInt("solveType"     , mSolveType     );
-      args.putInt("scrambleType"  , mScrambleType  );
+      args.putInt("SIZECHANGE_Pos" , mSizeChangePos );
+      args.putInt("SOLVE_Pos"      , mSolvePos      );
+      args.putInt("SCRAMBLE_Pos"   , mScramblePos   );
+      args.putInt("SIZECHANGE_Type", mSizeChangeType);
+      args.putInt("SOLVE_Type"     , mSolveType     );
+      args.putInt("SCRAMBLE_Type"  , mScrambleType  );
 
       RubikSettings settings = new RubikSettings();
       settings.setArguments(args);
@@ -162,13 +162,13 @@ public class RubikActivity extends AppCompatActivity implements RubikSettings.On
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void onComplete(int sizeP, int unscP, int scraP, int sizeT, int unscT, int scraT )
+    public void onComplete(int sizeP, int solvP, int scraP, int sizeT, int solvT, int scraT )
       {
       mSizeChangePos = sizeP;
-      mSolvePos      = unscP;
+      mSolvePos      = solvP;
       mScramblePos   = scraP;
       mSizeChangeType= sizeT;
-      mSolveType     = unscT;
+      mSolveType     = solvT;
       mScrambleType  = scraT;
 
       applyPreferences();
@@ -224,13 +224,13 @@ public class RubikActivity extends AppCompatActivity implements RubikSettings.On
      SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
      SharedPreferences.Editor editor = preferences.edit();
 
-     editor.putInt("sizechangePos" , mSizeChangePos );
-     editor.putInt("solvePos"      , mSolvePos      );
-     editor.putInt("scramblePos"   , mScramblePos   );
-     editor.putInt("sizechangeType", mSizeChangeType);
-     editor.putInt("solveType"     , mSolveType     );
-     editor.putInt("scrambleType"  , mScrambleType  );
-     editor.putInt("scramble"      , mPicker.getValue() );
+     editor.putInt("SIZECHANGE_Pos" , mSizeChangePos );
+     editor.putInt("SOLVE_Pos"      , mSolvePos      );
+     editor.putInt("SCRAMBLE_Pos"   , mScramblePos   );
+     editor.putInt("SIZECHANGE_Type", mSizeChangeType);
+     editor.putInt("SOLVE_Type"     , mSolveType     );
+     editor.putInt("SCRAMBLE_Type"  , mScrambleType  );
+     editor.putInt("scramble"       , mPicker.getValue() );
 
      editor.apply();
      }
@@ -241,13 +241,13 @@ public class RubikActivity extends AppCompatActivity implements RubikSettings.On
      {
      SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
 
-     mSizeChangePos = preferences.getInt("sizechangePos" , DEFAULT_SIZECHANGE_POS );
-     mSolvePos      = preferences.getInt("solvePos"      , DEFAULT_SOLVE_POS      );
-     mScramblePos   = preferences.getInt("scramblePos"   , DEFAULT_SCRAMBLE_POS   );
-     mSizeChangeType= preferences.getInt("sizechangeType", DEFAULT_SIZECHANGE_TYPE);
-     mSolveType     = preferences.getInt("solveType"     , DEFAULT_SOLVE_TYPE     );
-     mScrambleType  = preferences.getInt("scrambleType"  , DEFAULT_SCRAMBLE_TYPE  );
-     int scramble   = preferences.getInt("scramble"      , MIN_SCRAMBLE           );
+     mSizeChangePos = preferences.getInt("SIZECHANGE_Pos" , DEFAULT_SIZECHANGE_POS );
+     mSolvePos      = preferences.getInt("SOLVE_Pos"      , DEFAULT_SOLVE_POS      );
+     mScramblePos   = preferences.getInt("SCRAMBLE_Pos"   , DEFAULT_SCRAMBLE_POS   );
+     mSizeChangeType= preferences.getInt("SIZECHANGE_Type", DEFAULT_SIZECHANGE_TYPE);
+     mSolveType     = preferences.getInt("SOLVE_Type"     , DEFAULT_SOLVE_TYPE     );
+     mScrambleType  = preferences.getInt("SCRAMBLE_Type"  , DEFAULT_SCRAMBLE_TYPE  );
+     int scramble   = preferences.getInt("scramble"       , MIN_SCRAMBLE           );
 
      mPicker.setValue(scramble);
      }
diff --git a/src/main/java/org/distorted/magic/RubikSettings.java b/src/main/java/org/distorted/magic/RubikSettings.java
index 9bff4e36..2c9441f4 100644
--- a/src/main/java/org/distorted/magic/RubikSettings.java
+++ b/src/main/java/org/distorted/magic/RubikSettings.java
@@ -28,31 +28,43 @@ import android.support.annotation.Nullable;
 import android.support.v4.app.FragmentActivity;
 import android.support.v7.app.AlertDialog;
 import android.support.v7.app.AppCompatDialogFragment;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
 import android.widget.SeekBar;
 import android.widget.Spinner;
 import android.widget.TextView;
 
-import org.distorted.effect.SizeChangeEffect;
-import org.distorted.effect.SolveEffect;
-import org.distorted.effect.ScrambleEffect;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class RubikSettings extends AppCompatDialogFragment implements SeekBar.OnSeekBarChangeListener, AdapterView.OnItemSelectedListener
   {
   public interface OnCompleteListener
     {
-    void onComplete(int sizeP, int uscrP, int scraP, int sizeT, int unscT, int scraT);
+    void onComplete(int sizeP, int solvP, int scraP, int sizeT, int solvT, int scraT);
     }
 
   private OnCompleteListener mListener;
-  private int mSizeChangePos, mSolvePos, mScramblePos;
-  private int mSizeChangeType, mSolveType, mScrambleType;
-  private TextView mSizeChangeDuration, mSolveDuration, mScrambleDuration;
+
+  private TextView[] mDurationText;
+  private int[] mSeekBarID;
+  private int[] mSpinnerID;
+  private int[] mPos;
+  private int[] mType;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public RubikSettings()
+    {
+    mDurationText = new TextView[RubikSettingsEnum.LENGTH];
+    mSeekBarID    = new int[RubikSettingsEnum.LENGTH];
+    mSpinnerID    = new int[RubikSettingsEnum.LENGTH];
+    mPos          = new int[RubikSettingsEnum.LENGTH];
+    mType         = new int[RubikSettingsEnum.LENGTH];
+    }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -80,23 +92,23 @@ public class RubikSettings extends AppCompatDialogFragment implements SeekBar.On
 
     Bundle args = getArguments();
 
-    try
-      {
-      mSizeChangePos = args.getInt("sizechangePos");
-      mSolvePos      = args.getInt("solvePos");
-      mScramblePos   = args.getInt("scramblePos");
-      mSizeChangeType= args.getInt("sizechangeType");
-      mSolveType     = args.getInt("solveType");
-      mScrambleType  = args.getInt("scrambleType");
-      }
-    catch(NullPointerException ex)
+    String name;
+
+    for (int i=0; i<RubikSettingsEnum.LENGTH; i++)
       {
-      mSizeChangePos = RubikActivity.DEFAULT_SIZECHANGE_POS;
-      mSolvePos      = RubikActivity.DEFAULT_SOLVE_POS;
-      mScramblePos   = RubikActivity.DEFAULT_SCRAMBLE_POS;
-      mSizeChangeType= RubikActivity.DEFAULT_SIZECHANGE_TYPE;
-      mSolveType     = RubikActivity.DEFAULT_SOLVE_TYPE;
-      mScrambleType  = RubikActivity.DEFAULT_SCRAMBLE_TYPE;
+      RubikSettingsEnum rse = RubikSettingsEnum.getEnum(i);
+      name = rse.name();
+
+      try
+        {
+        mPos[i]  = args.getInt(name+"_Pos" );
+        mType[i] = args.getInt(name+"_Type");
+        }
+      catch(NullPointerException ex)
+        {
+        mPos[i]  = rse.getDefaultPos();
+        mType[i] = rse.getDefaultType();
+        }
       }
     }
 
@@ -123,104 +135,180 @@ public class RubikSettings extends AppCompatDialogFragment implements SeekBar.On
     final View view = inflater.inflate(R.layout.settings, null);
     builder.setView(view);
 
-    mSizeChangeDuration = view.findViewById(R.id.sizechangeDurationText);
-    mSolveDuration      = view.findViewById(R.id.solveDurationText);
-    mScrambleDuration   = view.findViewById(R.id.scrambleDurationText);
-
-    /// SIZE CHANGE ///////////////////////////////////////////////////////
-    Spinner sizechangeTypeSpinner  = view.findViewById(R.id.sizechangeType);
+    LinearLayout linearLayout = view.findViewById(R.id.main_settings_layout);
 
-    if( sizechangeTypeSpinner!=null )
+    if( linearLayout!=null )
       {
-      sizechangeTypeSpinner.setOnItemSelectedListener(this);
-      String[] appear = SizeChangeEffect.getNames();
-      ArrayAdapter<String> adapterType = new ArrayAdapter<>(act,android.R.layout.simple_spinner_item, appear);
-      adapterType.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-      sizechangeTypeSpinner.setAdapter(adapterType);
-
-      if(mSizeChangeType>=0 && mSizeChangeType<appear.length)
+      for (int i=0; i<RubikSettingsEnum.LENGTH; i++)
         {
-        sizechangeTypeSpinner.setSelection(mSizeChangeType);
+        createSettingsSection(act,linearLayout,i);
         }
       }
     else
       {
-      android.util.Log.e("dialog", "SIZE CHANGE TYPE SPINNER NULL!!");
+      android.util.Log.e("settings", "linearLayout NULL!");
       }
 
-    SeekBar sizechangeBar = view.findViewById(R.id.sizechangeDuration);
-    sizechangeBar.setOnSeekBarChangeListener(this);
-    sizechangeBar.setProgress(mSizeChangePos);
+    return builder.create();
+    }
 
-    /// SOLVE /////////////////////////////////////////////////////////////
-    Spinner solveTypeSpinner  = view.findViewById(R.id.solveType);
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    if( solveTypeSpinner!=null )
+    private void createSettingsSection(FragmentActivity act, LinearLayout layout, int index)
       {
-      solveTypeSpinner.setOnItemSelectedListener(this);
-      String[] solve = SolveEffect.getNames();
-      ArrayAdapter<String> adapterType = new ArrayAdapter<>(act,android.R.layout.simple_spinner_item, solve);
+      RubikSettingsEnum rsEnum = RubikSettingsEnum.getEnum(index);
+      float scale = act.getResources().getDisplayMetrics().density;
+
+      ///// TEXT ///////////////////////////////////////////////////////////////////////////
+
+      int layoutHeight = (int)(scale*48 + 0.5f);
+      int padding      = (int)(scale*15 + 0.5f);
+
+      LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,layoutHeight);
+
+      TextView textView = new TextView(act);
+      textView.setText(rsEnum.getText());
+      textView.setLayoutParams(textParams);
+      textView.setGravity(Gravity.START|Gravity.CENTER);
+      textView.setPadding(padding,0,padding,0);
+      textView.setTextAppearance(android.R.style.TextAppearance_Medium);
+      layout.addView(textView);
+
+      ///// OUTER LAYOUT ///////////////////////////////////////////////////////////////////
+
+      int margin = (int)(scale*10 + 0.5f);
+      int color  = act.getResources().getColor(R.color.grey);
+      LinearLayout outerLayout = new LinearLayout(act);
+      LinearLayout.LayoutParams outerLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 0.5f);
+      outerLayoutParams.bottomMargin = margin;
+      outerLayoutParams.leftMargin   = margin;
+      outerLayoutParams.rightMargin  = margin;
+
+      outerLayout.setLayoutParams(outerLayoutParams);
+      outerLayout.setGravity(Gravity.CENTER|Gravity.FILL_HORIZONTAL);
+      outerLayout.setBackgroundColor(color);
+      outerLayout.setOrientation(LinearLayout.VERTICAL);
+      layout.addView(outerLayout);
+
+      ///// INNER LAYOUT1 //////////////////////////////////////////////////////////////////
+
+      int innerLayout1Height = (int)(scale*36 + 0.5f);
+      LinearLayout innerLayout1 = new LinearLayout(act);
+      LinearLayout.LayoutParams innerLayout1Params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,innerLayout1Height);
+
+      innerLayout1.setLayoutParams(innerLayout1Params);
+      innerLayout1.setGravity(Gravity.CENTER|Gravity.FILL_HORIZONTAL);
+      innerLayout1.setOrientation(LinearLayout.HORIZONTAL);
+      outerLayout.addView(innerLayout1);
+
+      ///// STUFF INSIDE INNER LAYOUT1 /////////////////////////////////////////////////////
+
+      int text1Padding = (int)(scale*5 + 0.5f);
+      LinearLayout.LayoutParams text1LayoutParams = new LinearLayout.LayoutParams(0,layoutHeight,0.2f);
+
+      TextView text1View = new TextView(act);
+      text1View.setText(R.string.duration);
+      text1View.setLayoutParams(text1LayoutParams);
+      text1View.setGravity(Gravity.START|Gravity.CENTER);
+      text1View.setPadding(text1Padding,0,text1Padding,0);
+      text1View.setTextAppearance(android.R.style.TextAppearance_Small);
+      innerLayout1.addView(text1View);
+      //////////////////////////////////////////////////////////////////
+      int text2Padding = (int)(scale*5 + 0.5f);
+      LinearLayout.LayoutParams text2LayoutParams = new LinearLayout.LayoutParams(0,layoutHeight,0.2f);
+
+      mDurationText[index] = new TextView(act);
+      mDurationText[index].setLayoutParams(text2LayoutParams);
+      mDurationText[index].setGravity(Gravity.END|Gravity.CENTER);
+      mDurationText[index].setPadding(text2Padding,0,text2Padding,0);
+      mDurationText[index].setTextAppearance(android.R.style.TextAppearance_Small);
+      innerLayout1.addView(mDurationText[index]);
+      //////////////////////////////////////////////////////////////////
+      int seekPadding = (int)(scale*10 + 0.5f);
+      LinearLayout.LayoutParams seekLayoutParams = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,0.6f);
+
+      SeekBar seekBar = new SeekBar(act);
+      seekBar.setLayoutParams(seekLayoutParams);
+      seekBar.setPadding(seekPadding,0,seekPadding,0);
+      seekBar.setId(index);
+      innerLayout1.addView(seekBar);
+
+      mSeekBarID[index] = seekBar.getId();
+
+      seekBar.setOnSeekBarChangeListener(this);
+      seekBar.setProgress(mPos[index]);
+
+      ///// INNER LAYOUT2 //////////////////////////////////////////////////////////////////
+
+      int innerLayout2Height = (int)(scale*36 + 0.5f);
+      LinearLayout innerLayout2 = new LinearLayout(act);
+      LinearLayout.LayoutParams innerLayout2Params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,innerLayout2Height);
+
+      innerLayout2.setLayoutParams(innerLayout2Params);
+      innerLayout2.setGravity(Gravity.CENTER|Gravity.FILL_HORIZONTAL);
+      innerLayout2.setOrientation(LinearLayout.HORIZONTAL);
+      outerLayout.addView(innerLayout2);
+
+      ///// STUFF INSIDE INNER LAYOUT2 /////////////////////////////////////////////////////
+
+      int text3Padding = (int)(scale*5 + 0.5f);
+      LinearLayout.LayoutParams text3LayoutParams = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,0.4f);
+
+      TextView text3View = new TextView(act);
+      text3View.setText(R.string.type);
+      text3View.setLayoutParams(text3LayoutParams);
+      text3View.setGravity(Gravity.START|Gravity.CENTER);
+      text3View.setPadding(text3Padding,0,text3Padding,0);
+      text3View.setTextAppearance(android.R.style.TextAppearance_Small);
+      innerLayout2.addView(text3View);
+      //////////////////////////////////////////////////////////////////
+      int spinnerPadding = (int)(scale*10 + 0.5f);
+      LinearLayout.LayoutParams spinnerLayoutParams = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,0.6f);
+
+      Spinner spinner = new Spinner(act);
+      spinner.setLayoutParams(spinnerLayoutParams);
+      spinner.setPadding(spinnerPadding,0,spinnerPadding,0);
+      spinner.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+      spinner.setId(index);
+      innerLayout2.addView(spinner);
+
+      mSpinnerID[index] = spinner.getId();
+
+      spinner.setOnItemSelectedListener(this);
+      String[] appear = RubikSettingsEnum.getNames(index);
+      ArrayAdapter<String> adapterType = new ArrayAdapter<>(act,android.R.layout.simple_spinner_item, appear);
       adapterType.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-      solveTypeSpinner.setAdapter(adapterType);
+      spinner.setAdapter(adapterType);
 
-      if(mSolveType>=0 && mSolveType<solve.length)
-        {
-        solveTypeSpinner.setSelection(mSolveType);
-        }
-      }
-    else
-      {
-      android.util.Log.e("dialog", "SOLVE TYPE SPINNER NULL!!");
-      }
-
-    SeekBar solveBar = view.findViewById(R.id.solveDuration);
-    solveBar.setOnSeekBarChangeListener(this);
-    solveBar.setProgress(mSolvePos);
+      int type = mType[index];
 
-    /// SCRAMBLE //////////////////////////////////////////////////////////
-    Spinner scrambleTypeSpinner  = view.findViewById(R.id.scrambleType);
-
-    if( scrambleTypeSpinner!=null )
-      {
-      scrambleTypeSpinner.setOnItemSelectedListener(this);
-      String[] scramble = ScrambleEffect.getNames();
-      ArrayAdapter<String> adapterType = new ArrayAdapter<>(act,android.R.layout.simple_spinner_item, scramble);
-      adapterType.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-      scrambleTypeSpinner.setAdapter(adapterType);
-
-      if(mScrambleType>=0 && mScrambleType<scramble.length)
+      if(type>=0 && type<appear.length)
         {
-        scrambleTypeSpinner.setSelection(mScrambleType);
+        spinner.setSelection(type);
         }
       }
-    else
-      {
-      android.util.Log.e("dialog", "SCRAMBLE TYPE SPINNER NULL!!");
-      }
 
-    SeekBar scrambleBar = view.findViewById(R.id.scrambleDuration);
-    scrambleBar.setOnSeekBarChangeListener(this);
-    scrambleBar.setProgress(mScramblePos);
-
-    return builder.create();
-    }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     private void saveOptions()
       {
-      mListener.onComplete(mSizeChangePos, mSolvePos, mScramblePos, mSizeChangeType, mSolveType, mScrambleType);
+      mListener.onComplete(mPos[0], mPos[1], mPos[2], mType[0], mType[1], mType[2]);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
       {
-      switch(parent.getId())
+      int parentID = parent.getId();
+
+      for (int i=0; i<RubikSettingsEnum.LENGTH; i++)
         {
-        case R.id.sizechangeType: mSizeChangeType= pos; break;
-        case R.id.solveType     : mSolveType     = pos; break;
-        case R.id.scrambleType  : mScrambleType  = pos; break;
+        if( mSpinnerID[i] == parentID )
+          {
+          mType[i] = pos;
+          break;
+          }
         }
       }
 
@@ -228,20 +316,17 @@ public class RubikSettings extends AppCompatDialogFragment implements SeekBar.On
 
     public void onProgressChanged(SeekBar bar, int progress, boolean fromUser)
       {
-      switch (bar.getId())
+      int barID = bar.getId();
+
+      for (int i=0; i<RubikSettingsEnum.LENGTH; i++)
         {
-        case R.id.sizechangeDuration: mSizeChangePos= progress;
-                                      int sizechange_ms= RubikActivity.translateDuration(mSizeChangePos);
-                                      mSizeChangeDuration.setText(getString(R.string.ms_placeholder,sizechange_ms));
-                                      break;
-        case R.id.solveDuration     : mSolvePos= progress;
-                                      int solve_ms= RubikActivity.translateDuration(mSolvePos);
-                                      mSolveDuration.setText(getString(R.string.ms_placeholder,solve_ms));
-                                      break;
-        case R.id.scrambleDuration  : mScramblePos= progress;
-                                      int scramble_ms= RubikActivity.translateDuration(mScramblePos);
-                                      mScrambleDuration.setText(getString(R.string.ms_placeholder,scramble_ms));
-                                      break;
+        if( mSeekBarID[i] == barID )
+          {
+          mPos[i] = progress;
+          int ms = RubikActivity.translateDuration(mPos[i]);
+          mDurationText[i].setText(getString(R.string.ms_placeholder,ms));
+          break;
+          }
         }
       }
 
diff --git a/src/main/java/org/distorted/magic/RubikSettingsEnum.java b/src/main/java/org/distorted/magic/RubikSettingsEnum.java
new file mode 100644
index 00000000..2c727f43
--- /dev/null
+++ b/src/main/java/org/distorted/magic/RubikSettingsEnum.java
@@ -0,0 +1,103 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2020 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted 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.                                                           //
+//                                                                                               //
+// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.magic;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+import org.distorted.effect.ScrambleEffect;
+import org.distorted.effect.SizeChangeEffect;
+import org.distorted.effect.SolveEffect;
+
+enum RubikSettingsEnum
+  {
+  SIZECHANGE  (  20, 1, R.string.sizechange_effect ),
+  SOLVE       (  20, 1, R.string.solve_effect      ),
+  SCRAMBLE    ( 100, 0, R.string.scramble_effect   );
+
+  public static final int LENGTH = values().length;
+  private int mDefaultPos, mDefaultType;
+  private int mText;
+
+  private static final RubikSettingsEnum[] enums;  // copy the values() to a local variable so that we
+                                                   // don't have to keep recreating the array every time
+  static
+    {
+    int i=0;
+
+    enums= new RubikSettingsEnum[LENGTH];
+
+    for(RubikSettingsEnum name: RubikSettingsEnum.values())
+      {
+      enums[i] = name;
+      i++;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  RubikSettingsEnum( int dPos, int dType, int text )
+    {
+    mDefaultPos  = dPos;
+    mDefaultType = dType;
+    mText        = text;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getDefaultPos()
+    {
+    return mDefaultPos;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getDefaultType()
+    {
+    return mDefaultType;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getText()
+    {
+    return mText;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static RubikSettingsEnum getEnum(int ordinal)
+    {
+    return enums[ordinal];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static String[] getNames(int ordinal)
+    {
+    switch(ordinal)
+      {
+      case 0: return SizeChangeEffect.getNames();
+      case 1: return SolveEffect.getNames();
+      case 2: return ScrambleEffect.getNames();
+      }
+
+    return null;
+    }
+  }
diff --git a/src/main/res/layout/settings.xml b/src/main/res/layout/settings.xml
index 42d37fe3..6ff21232 100644
--- a/src/main/res/layout/settings.xml
+++ b/src/main/res/layout/settings.xml
@@ -2,257 +2,8 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:id="@+id/main_settings_layout"
     android:gravity="center_horizontal"
     android:orientation="vertical">
 
-    <TextView
-        android:layout_width="fill_parent"
-        android:layout_height="48dp"
-        android:paddingStart="15dp"
-        android:paddingEnd="15dp"
-        android:gravity="start|center"
-        android:text="@string/sizechange_effect"
-        android:textAppearance="?android:attr/textAppearanceMedium" />
-
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:layout_weight="0.5"
-        android:gravity="center|fill_horizontal"
-        android:layout_marginLeft="10dp"
-        android:layout_marginRight="10dp"
-        android:layout_marginBottom="10dp"
-        android:background="@color/grey"
-        android:orientation="vertical">
-
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="36dp"
-            android:gravity="center|fill_horizontal"
-            android:orientation="horizontal">
-
-            <TextView
-                android:layout_weight="0.2"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingStart="5dp"
-                android:paddingEnd="5dp"
-                android:gravity="start|center"
-                android:text="@string/duration"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
-
-            <TextView
-                android:id="@+id/sizechangeDurationText"
-                android:layout_weight="0.2"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingStart="5dp"
-                android:paddingEnd="5dp"
-                android:gravity="end|center"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
-
-            <SeekBar
-                android:id="@+id/sizechangeDuration"
-                android:layout_weight="0.6"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingLeft="10dp"
-                android:paddingRight="10dp" />
-
-        </LinearLayout>
-
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="36dp"
-            android:gravity="center|fill_horizontal"
-            android:orientation="horizontal">
-
-            <TextView
-                android:layout_weight="0.4"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingStart="5dp"
-                android:paddingEnd="5dp"
-                android:gravity="start|center"
-                android:text="@string/type"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
-
-            <Spinner
-                android:id="@+id/sizechangeType"
-                android:layout_weight="0.6"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:textAlignment="center"
-                android:paddingLeft="10dp"
-                android:paddingRight="10dp" />
-
-        </LinearLayout>
-    </LinearLayout>
-
-    <TextView
-        android:layout_width="fill_parent"
-        android:layout_height="48dp"
-        android:paddingStart="15dp"
-        android:paddingEnd="15dp"
-        android:gravity="start|center"
-        android:text="@string/unscramble_effect"
-        android:textAppearance="?android:attr/textAppearanceMedium" />
-
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:layout_weight="0.5"
-        android:gravity="center|fill_horizontal"
-        android:layout_marginLeft="10dp"
-        android:layout_marginRight="10dp"
-        android:layout_marginBottom="10dp"
-        android:background="@color/grey"
-        android:orientation="vertical">
-
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="36dp"
-            android:gravity="center|fill_horizontal"
-            android:orientation="horizontal">
-
-            <TextView
-                android:layout_weight="0.2"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingStart="5dp"
-                android:paddingEnd="5dp"
-                android:gravity="start|center"
-                android:text="@string/duration"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
-
-            <TextView
-                android:id="@+id/solveDurationText"
-                android:layout_weight="0.2"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingStart="5dp"
-                android:paddingEnd="5dp"
-                android:gravity="end|center"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
-
-            <SeekBar
-                android:id="@+id/solveDuration"
-                android:layout_weight="0.6"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingLeft="10dp"
-                android:paddingRight="10dp" />
-
-        </LinearLayout>
-
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="36dp"
-            android:gravity="center|fill_horizontal"
-            android:orientation="horizontal">
-
-            <TextView
-                android:layout_weight="0.4"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingStart="5dp"
-                android:paddingEnd="5dp"
-                android:gravity="start|center"
-                android:text="@string/type"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
-
-            <Spinner
-                android:id="@+id/solveType"
-                android:layout_weight="0.6"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:textAlignment="center"
-                android:paddingLeft="10dp"
-                android:paddingRight="10dp" />
-
-        </LinearLayout>
-    </LinearLayout>
-
-    <TextView
-        android:layout_width="fill_parent"
-        android:layout_height="48dp"
-        android:paddingStart="15dp"
-        android:paddingEnd="15dp"
-        android:gravity="start|center"
-        android:text="@string/scramble_effect"
-        android:textAppearance="?android:attr/textAppearanceMedium" />
-
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:layout_weight="0.5"
-        android:gravity="center|fill_horizontal"
-        android:layout_marginLeft="10dp"
-        android:layout_marginRight="10dp"
-        android:background="@color/grey"
-        android:orientation="vertical">
-
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="36dp"
-            android:gravity="center|fill_horizontal"
-            android:orientation="horizontal">
-
-            <TextView
-                android:layout_weight="0.2"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingStart="5dp"
-                android:paddingEnd="5dp"
-                android:gravity="start|center"
-                android:text="@string/duration"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
-
-            <TextView
-                android:id="@+id/scrambleDurationText"
-                android:layout_weight="0.2"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingStart="5dp"
-                android:paddingEnd="5dp"
-                android:gravity="end|center"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
-
-            <SeekBar
-                android:id="@+id/scrambleDuration"
-                android:layout_weight="0.6"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingLeft="10dp"
-                android:paddingRight="10dp" />
-
-        </LinearLayout>
-
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="36dp"
-            android:gravity="center|fill_horizontal"
-            android:orientation="horizontal">
-
-            <TextView
-                android:layout_weight="0.4"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:paddingStart="5dp"
-                android:paddingEnd="5dp"
-                android:gravity="start|center"
-                android:text="@string/type"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
-
-            <Spinner
-                android:id="@+id/scrambleType"
-                android:layout_weight="0.6"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:textAlignment="center"
-                android:paddingLeft="10dp"
-                android:paddingRight="10dp" />
-
-        </LinearLayout>
-    </LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index e5c658cd..414ec4d9 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -8,12 +8,13 @@
     <string name="about">About</string>
     <string name="save">SAVE</string>
     <string name="ok">OK</string>
-    <string name="sizechange_effect">Cube Size Change Effect:</string>
-    <string name="unscramble_effect">Cube Unscramble Effect:</string>
-    <string name="scramble_effect">Cube Scramble Effect:</string>
+    <string name="sizechange_effect">Size Change Effect:</string>
+    <string name="solve_effect">Solve Effect:</string>
+    <string name="scramble_effect">Scramble Effect:</string>
     <string name="duration">Duration:</string>
     <string name="type">Type:</string>
     <string name="credits1">Open Source app developed using the Distorted graphics library. </string>
     <string name="credits2">Code, tutorials, learn how to write your own graphics effect: <a href="http://www.distorted.org/cube">Distorted.org</a></string>
+
     <string name="ms_placeholder">%1$d ms</string>
 </resources>
