commit a7012218bab4757eaf615458fac38868eb4dea20
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed May 15 01:10:42 2019 +0100

    Add Unscramble Effects to the UI.

diff --git a/src/main/java/org/distorted/effect/AppearEffect.java b/src/main/java/org/distorted/effect/AppearEffect.java
index 6c4e00f9..a095306b 100644
--- a/src/main/java/org/distorted/effect/AppearEffect.java
+++ b/src/main/java/org/distorted/effect/AppearEffect.java
@@ -194,7 +194,7 @@ public abstract class AppearEffect implements EffectListener
         }
       catch(NoSuchMethodException ex)
         {
-        android.util.Log.e("transitionEffect", "exception getting method: "+ex.getMessage());
+        android.util.Log.e("AppearEffect", "exception getting method: "+ex.getMessage());
         }
 
       try
@@ -203,7 +203,7 @@ public abstract class AppearEffect implements EffectListener
         }
       catch(Exception ex)
         {
-        android.util.Log.e("transitionEffect", "exception invoking method: "+ex.getMessage());
+        android.util.Log.e("AppearEffect", "exception invoking method: "+ex.getMessage());
         }
       }
     }
diff --git a/src/main/java/org/distorted/effect/DisappearEffect.java b/src/main/java/org/distorted/effect/DisappearEffect.java
index 3d09f315..a5339901 100644
--- a/src/main/java/org/distorted/effect/DisappearEffect.java
+++ b/src/main/java/org/distorted/effect/DisappearEffect.java
@@ -197,7 +197,7 @@ public abstract class DisappearEffect implements EffectListener
         }
       catch(NoSuchMethodException ex)
         {
-        android.util.Log.e("transitionEffect", "exception getting method: "+ex.getMessage());
+        android.util.Log.e("DisappearEffect", "exception getting method: "+ex.getMessage());
         }
 
       try
@@ -206,7 +206,7 @@ public abstract class DisappearEffect implements EffectListener
         }
       catch(Exception ex)
         {
-        android.util.Log.e("transitionEffect", "exception invoking method: "+ex.getMessage());
+        android.util.Log.e("DisappearEffect", "exception invoking method: "+ex.getMessage());
         }
       }
     }
diff --git a/src/main/java/org/distorted/effect/UnscrambleEffect.java b/src/main/java/org/distorted/effect/UnscrambleEffect.java
new file mode 100644
index 00000000..87e57a73
--- /dev/null
+++ b/src/main/java/org/distorted/effect/UnscrambleEffect.java
@@ -0,0 +1,101 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.effect;
+
+import java.lang.reflect.Method;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class UnscrambleEffect
+{
+  public enum Type
+    {
+    NONE  (UnscrambleEffectNone.class ),
+    SPIN  (UnscrambleEffectSpin.class ),
+    ;
+
+    private final Class<? extends UnscrambleEffect> effectClass;
+
+    Type(Class<? extends UnscrambleEffect> effectClass)
+      {
+      this.effectClass = effectClass;
+      }
+    }
+
+  public static final int NUM_EFFECTS = Type.values().length;
+  private static final Type[] types;
+
+  static
+    {
+    int i=0;
+
+    types = new Type[NUM_EFFECTS];
+
+    for(Type type: Type.values())
+      {
+      types[i] = type;
+      i++;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static UnscrambleEffect.Type getType(int ordinal)
+    {
+    return types[ordinal];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static UnscrambleEffect create(Type type) throws InstantiationException, IllegalAccessException
+    {
+    return type.effectClass.newInstance();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void enableEffects()
+    {
+    Method method=null;
+
+    for(Type type: Type.values())
+      {
+      Class<? extends UnscrambleEffect> cls = type.effectClass;
+
+      try
+        {
+        method = cls.getMethod("enable");
+        }
+      catch(NoSuchMethodException ex)
+        {
+        android.util.Log.e("UnscrambleEffect", "exception getting method: "+ex.getMessage());
+        }
+
+      try
+        {
+        method.invoke(null);
+        }
+      catch(Exception ex)
+        {
+        android.util.Log.e("UnscrambleEffect", "exception invoking method: "+ex.getMessage());
+        }
+      }
+    }
+}
diff --git a/src/main/java/org/distorted/effect/UnscrambleEffectNone.java b/src/main/java/org/distorted/effect/UnscrambleEffectNone.java
new file mode 100644
index 00000000..54057a03
--- /dev/null
+++ b/src/main/java/org/distorted/effect/UnscrambleEffectNone.java
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.effect;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class UnscrambleEffectNone extends UnscrambleEffect
+  {
+
+  }
diff --git a/src/main/java/org/distorted/effect/UnscrambleEffectSpin.java b/src/main/java/org/distorted/effect/UnscrambleEffectSpin.java
new file mode 100644
index 00000000..6cc4137d
--- /dev/null
+++ b/src/main/java/org/distorted/effect/UnscrambleEffectSpin.java
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.effect;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class UnscrambleEffectSpin extends UnscrambleEffect
+  {
+
+  }
diff --git a/src/main/java/org/distorted/magic/RubikActivity.java b/src/main/java/org/distorted/magic/RubikActivity.java
index 6ead1ef3..93845c23 100644
--- a/src/main/java/org/distorted/magic/RubikActivity.java
+++ b/src/main/java/org/distorted/magic/RubikActivity.java
@@ -32,6 +32,7 @@ import android.view.View;
 import org.distorted.component.HorizontalNumberPicker;
 import org.distorted.effect.AppearEffect;
 import org.distorted.effect.DisappearEffect;
+import org.distorted.effect.UnscrambleEffect;
 import org.distorted.library.main.DistortedLibrary;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -42,18 +43,20 @@ public class RubikActivity extends AppCompatActivity implements RubikSettings.On
     private static final int SMALLEST_SIZE = 2;
     private static final int[] button_ids  = {R.id.rubikSize2, R.id.rubikSize3, R.id.rubikSize4};
 
-    public static final int DEFAULT_APPEAR_POS     = 10;
-    public static final int DEFAULT_DISAPPEAR_POS  = 10;
+    public static final int DEFAULT_APPEAR_POS     = 20;
+    public static final int DEFAULT_DISAPPEAR_POS  = 20;
+    public static final int DEFAULT_UNSCRAMBLE_POS = 20;
     public static final int DEFAULT_APPEAR_TYPE    = 1;
     public static final int DEFAULT_DISAPPEAR_TYPE = 1;
+    public static final int DEFAULT_UNSCRAMBLE_TYPE= 1;
 
     public static final int MIN_SCRAMBLE =  1;
     public static final int MAX_SCRAMBLE = 10;
 
     private static int mSize = DEFAULT_SIZE;
 
-    private int mAppearPos, mDisappearPos;
-    private int mAppearType, mDisappearType;
+    private int mAppearPos, mDisappearPos, mUnscramblePos;
+    private int mAppearType, mDisappearType, mUnscrambleType;
 
     private HorizontalNumberPicker mPicker;
 
@@ -119,10 +122,12 @@ public class RubikActivity extends AppCompatActivity implements RubikSettings.On
       {
       Bundle args = new Bundle();
 
-      args.putInt("appearPos"    , mAppearPos    );
-      args.putInt("disappearPos" , mDisappearPos );
-      args.putInt("appearType"   , mAppearType   );
-      args.putInt("disappearType", mDisappearType);
+      args.putInt("appearPos"     , mAppearPos     );
+      args.putInt("disappearPos"  , mDisappearPos  );
+      args.putInt("unscramblePos" , mUnscramblePos );
+      args.putInt("appearType"    , mAppearType    );
+      args.putInt("disappearType" , mDisappearType );
+      args.putInt("unscrambleType", mUnscrambleType);
 
       RubikSettings settings = new RubikSettings();
       settings.setArguments(args);
@@ -157,12 +162,14 @@ public class RubikActivity extends AppCompatActivity implements RubikSettings.On
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void onComplete(int aP, int dP, int aT, int dT)
+    public void onComplete(int aP, int dP, int uP, int aT, int dT, int uT )
       {
-      mAppearPos    = aP;
-      mDisappearPos = dP;
-      mAppearType   = aT;
-      mDisappearType= dT;
+      mAppearPos     = aP;
+      mDisappearPos  = dP;
+      mUnscramblePos = uP;
+      mAppearType    = aT;
+      mDisappearType = dT;
+      mUnscrambleType= uT;
 
       applyPreferences();
       }
@@ -217,10 +224,12 @@ public class RubikActivity extends AppCompatActivity implements RubikSettings.On
      SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
      SharedPreferences.Editor editor = preferences.edit();
 
-     editor.putInt("appearPos"    , mAppearPos    );
-     editor.putInt("disappearPos" , mDisappearPos );
-     editor.putInt("appearType"   , mAppearType   );
-     editor.putInt("disappearType", mDisappearType);
+     editor.putInt("appearPos"     , mAppearPos     );
+     editor.putInt("disappearPos"  , mDisappearPos  );
+     editor.putInt("unscramblePos" , mUnscramblePos );
+     editor.putInt("appearType"    , mAppearType    );
+     editor.putInt("disappearType" , mDisappearType );
+     editor.putInt("unscrambleType", mUnscrambleType);
      editor.putInt("scramble"     , mPicker.getValue() );
 
      editor.apply();
@@ -232,11 +241,13 @@ public class RubikActivity extends AppCompatActivity implements RubikSettings.On
      {
      SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
 
-     mAppearPos     = preferences.getInt("appearPos"    , DEFAULT_APPEAR_POS    );
-     mDisappearPos  = preferences.getInt("disappearPos" , DEFAULT_DISAPPEAR_POS );
-     mAppearType    = preferences.getInt("appearType"   , DEFAULT_APPEAR_TYPE   );
-     mDisappearType = preferences.getInt("disappearType", DEFAULT_DISAPPEAR_TYPE);
-     int scramble   = preferences.getInt("scramble"     , MIN_SCRAMBLE          );
+     mAppearPos     = preferences.getInt("appearPos"     , DEFAULT_APPEAR_POS     );
+     mDisappearPos  = preferences.getInt("disappearPos"  , DEFAULT_DISAPPEAR_POS  );
+     mUnscramblePos = preferences.getInt("unscramblePos" , DEFAULT_UNSCRAMBLE_POS );
+     mAppearType    = preferences.getInt("appearType"    , DEFAULT_APPEAR_TYPE    );
+     mDisappearType = preferences.getInt("disappearType" , DEFAULT_DISAPPEAR_TYPE );
+     mUnscrambleType= preferences.getInt("unscrambleType", DEFAULT_UNSCRAMBLE_TYPE);
+     int scramble   = preferences.getInt("scramble"      , MIN_SCRAMBLE           );
 
      mPicker.setValue(scramble);
      }
@@ -250,8 +261,10 @@ public class RubikActivity extends AppCompatActivity implements RubikSettings.On
 
      renderer.setAppearDuration(translateDuration(mAppearPos)+1);
      renderer.setDisappearDuration(translateDuration(mDisappearPos) +1);
+     renderer.setUnscrambleDuration(translateDuration(mUnscramblePos) +1);
      renderer.setAppearType(AppearEffect.getType(mAppearType));
      renderer.setDisappearType(DisappearEffect.getType(mDisappearType));
+     renderer.setUnscrambleType(UnscrambleEffect.getType(mUnscrambleType));
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/magic/RubikRenderer.java b/src/main/java/org/distorted/magic/RubikRenderer.java
index 60dcaf14..00d6f249 100644
--- a/src/main/java/org/distorted/magic/RubikRenderer.java
+++ b/src/main/java/org/distorted/magic/RubikRenderer.java
@@ -23,6 +23,7 @@ import android.opengl.GLSurfaceView;
 
 import org.distorted.effect.AppearEffect;
 import org.distorted.effect.DisappearEffect;
+import org.distorted.effect.UnscrambleEffect;
 import org.distorted.library.effect.VertexEffectSink;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedLibrary;
@@ -57,7 +58,8 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
     private MeshFlat mMesh;
     private AppearEffect.Type mAppearType;
     private DisappearEffect.Type mDisappearType;
-    private int mAppearDuration, mDisappearDuration;
+    private UnscrambleEffect.Type mUnscrambleType;
+    private int mAppearDuration, mDisappearDuration, mUnscrambleDuration;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -171,6 +173,7 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
       VertexEffectSink.enable();
       AppearEffect.enableEffects();
       DisappearEffect.enableEffects();
+      UnscrambleEffect.enableEffects();
 
       try
         {
@@ -265,6 +268,13 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
      mDisappearDuration = duration;
      }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   void setUnscrambleDuration(int duration)
+     {
+     mUnscrambleDuration = duration;
+     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    void setAppearType(AppearEffect.Type type)
@@ -279,6 +289,13 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
      mDisappearType = type;
      }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   void setUnscrambleType(UnscrambleEffect.Type type)
+     {
+     mUnscrambleType = type;
+     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    boolean createCube(int newSize)
diff --git a/src/main/java/org/distorted/magic/RubikSettings.java b/src/main/java/org/distorted/magic/RubikSettings.java
index dcebeac9..10bdf7b6 100644
--- a/src/main/java/org/distorted/magic/RubikSettings.java
+++ b/src/main/java/org/distorted/magic/RubikSettings.java
@@ -38,6 +38,7 @@ import android.widget.TextView;
 
 import org.distorted.effect.AppearEffect;
 import org.distorted.effect.DisappearEffect;
+import org.distorted.effect.UnscrambleEffect;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -45,15 +46,15 @@ public class RubikSettings extends AppCompatDialogFragment implements SeekBar.On
   {
   public interface OnCompleteListener
     {
-    void onComplete(int aP, int dP, int aT, int dT);
+    void onComplete(int aP, int dP, int uP, int aT, int dT, int uT);
     }
 
   private OnCompleteListener mListener;
 
-  private int mAppearPos, mDisappearPos;
-  private int mAppearType, mDisappearType;
+  private int mAppearPos, mDisappearPos, mUnscramblePos;
+  private int mAppearType, mDisappearType, mUnscrambleType;
 
-  private TextView mAppearDuration, mDisappearDuration;
+  private TextView mAppearDuration, mDisappearDuration, mUnscrambleDuration;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -85,15 +86,19 @@ public class RubikSettings extends AppCompatDialogFragment implements SeekBar.On
       {
       mAppearPos     = args.getInt("appearPos");
       mDisappearPos  = args.getInt("disappearPos");
+      mUnscramblePos = args.getInt("unscramblePos");
       mAppearType    = args.getInt("appearType");
       mDisappearType = args.getInt("disappearType");
+      mUnscrambleType= args.getInt("unscrambleType");
       }
     catch(NullPointerException ex)
       {
       mAppearPos     = RubikActivity.DEFAULT_APPEAR_POS;
       mDisappearPos  = RubikActivity.DEFAULT_DISAPPEAR_POS;
+      mUnscramblePos = RubikActivity.DEFAULT_UNSCRAMBLE_POS;
       mAppearType    = RubikActivity.DEFAULT_APPEAR_TYPE;
       mDisappearType = RubikActivity.DEFAULT_DISAPPEAR_TYPE;
+      mUnscrambleType= RubikActivity.DEFAULT_UNSCRAMBLE_TYPE;
       }
     }
 
@@ -122,6 +127,7 @@ public class RubikSettings extends AppCompatDialogFragment implements SeekBar.On
 
     mAppearDuration    = view.findViewById(R.id.appearDurationText);
     mDisappearDuration = view.findViewById(R.id.disappearDurationText);
+    mUnscrambleDuration = view.findViewById(R.id.unscrambleDurationText);
 
     Spinner appearTypeSpinner  = view.findViewById(R.id.appearType);
 
@@ -171,6 +177,30 @@ public class RubikSettings extends AppCompatDialogFragment implements SeekBar.On
     disappearBar.setOnSeekBarChangeListener(this);
     disappearBar.setProgress(mDisappearPos);
 
+    Spinner unscrambleTypeSpinner  = view.findViewById(R.id.unscrambleType);
+
+    if( unscrambleTypeSpinner!=null )
+      {
+      unscrambleTypeSpinner.setOnItemSelectedListener(this);
+      String[] unscramble = getUnscrambleEffectNames();
+      ArrayAdapter<String> adapterType = new ArrayAdapter<>(act,android.R.layout.simple_spinner_item, unscramble);
+      adapterType.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+      unscrambleTypeSpinner.setAdapter(adapterType);
+
+      if(mUnscrambleType>=0 && mUnscrambleType<unscramble.length)
+        {
+        unscrambleTypeSpinner.setSelection(mUnscrambleType);
+        }
+      }
+    else
+      {
+      android.util.Log.e("dialog", "UNSCRAMBLE TYPE SPINNER NULL!!");
+      }
+
+    SeekBar unscrambleBar = view.findViewById(R.id.unscrambleDuration);
+    unscrambleBar.setOnSeekBarChangeListener(this);
+    unscrambleBar.setProgress(mUnscramblePos);
+
     return builder.create();
     }
 
@@ -206,11 +236,27 @@ public class RubikSettings extends AppCompatDialogFragment implements SeekBar.On
       return names;
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private String[] getUnscrambleEffectNames()
+      {
+      int length = UnscrambleEffect.NUM_EFFECTS;
+      UnscrambleEffect.Type[] types = UnscrambleEffect.Type.values();
+      String[] names = new String[length];
+
+      for( int i=0; i<length; i++)
+        {
+        names[i] = types[i].name();
+        }
+
+      return names;
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     private void saveOptions()
       {
-      mListener.onComplete(mAppearPos, mDisappearPos, mAppearType, mDisappearType);
+      mListener.onComplete(mAppearPos, mDisappearPos, mUnscramblePos, mAppearType, mDisappearType, mUnscrambleType);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -219,8 +265,9 @@ public class RubikSettings extends AppCompatDialogFragment implements SeekBar.On
       {
       switch(parent.getId())
         {
-        case R.id.appearType   : mAppearType   = pos; break;
-        case R.id.disappearType: mDisappearType= pos; break;
+        case R.id.appearType    : mAppearType    = pos; break;
+        case R.id.disappearType : mDisappearType = pos; break;
+        case R.id.unscrambleType: mUnscrambleType= pos; break;
         }
       }
 
@@ -230,14 +277,18 @@ public class RubikSettings extends AppCompatDialogFragment implements SeekBar.On
       {
       switch (bar.getId())
         {
-        case R.id.appearDuration   : mAppearPos   = progress;
-                                     int appear_ms= RubikActivity.translateDuration(mAppearPos);
-                                     mAppearDuration.setText(getString(R.string.ms_placeholder,appear_ms));
-                                     break;
-        case R.id.disappearDuration: mDisappearPos= progress;
-                                     int disappear_ms= RubikActivity.translateDuration(mDisappearPos);
-                                     mDisappearDuration.setText(getString(R.string.ms_placeholder,disappear_ms));
-                                     break;
+        case R.id.appearDuration    : mAppearPos   = progress;
+                                      int appear_ms= RubikActivity.translateDuration(mAppearPos);
+                                      mAppearDuration.setText(getString(R.string.ms_placeholder,appear_ms));
+                                      break;
+        case R.id.disappearDuration : mDisappearPos= progress;
+                                      int disappear_ms= RubikActivity.translateDuration(mDisappearPos);
+                                      mDisappearDuration.setText(getString(R.string.ms_placeholder,disappear_ms));
+                                      break;
+        case R.id.unscrambleDuration: mUnscramblePos= progress;
+                                      int unscramble_ms= RubikActivity.translateDuration(mUnscramblePos);
+                                      mUnscrambleDuration.setText(getString(R.string.ms_placeholder,unscramble_ms));
+                                      break;
         }
       }
 
diff --git a/src/main/res/layout/settings.xml b/src/main/res/layout/settings.xml
index c98b1d4d..d57e73f4 100644
--- a/src/main/res/layout/settings.xml
+++ b/src/main/res/layout/settings.xml
@@ -11,7 +11,7 @@
         android:paddingStart="15dp"
         android:paddingEnd="15dp"
         android:gravity="start|center"
-        android:text="@string/disappear"
+        android:text="@string/disappear_effect"
         android:textAppearance="?android:attr/textAppearanceMedium" />
 
     <LinearLayout
@@ -94,7 +94,7 @@
         android:paddingStart="15dp"
         android:paddingEnd="15dp"
         android:gravity="start|center"
-        android:text="@string/appear"
+        android:text="@string/appear_effect"
         android:textAppearance="?android:attr/textAppearanceMedium" />
 
     <LinearLayout
@@ -172,4 +172,87 @@
         </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: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/unscrambleDurationText"
+                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/unscrambleDuration"
+                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/unscrambleType"
+                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 0030c8cd..a5b1674f 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -8,8 +8,9 @@
     <string name="about">About</string>
     <string name="save">SAVE</string>
     <string name="ok">OK</string>
-    <string name="appear">New Cube Appear Effect:</string>
-    <string name="disappear">Old Cube Disappear Effect:</string>
+    <string name="appear_effect">New Cube Appear Effect:</string>
+    <string name="disappear_effect">Old Cube Disappear Effect:</string>
+    <string name="unscramble_effect">Cube Unscramble 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>
