commit 7bb30586b20385ccb5e5e37b7e8680f293e4b456
Author: leszek <leszek@koltunski.pl>
Date:   Wed Nov 15 15:28:48 2023 +0100

    Remove all old UI 1.0 classes

diff --git a/src/main/java/org/distorted/bandaged/BandagedActivity.java b/src/main/java/org/distorted/bandaged/BandagedActivity.java
index 64cf9422..8f6e7607 100644
--- a/src/main/java/org/distorted/bandaged/BandagedActivity.java
+++ b/src/main/java/org/distorted/bandaged/BandagedActivity.java
@@ -43,13 +43,14 @@ import org.distorted.playui.PlayActivity;
 
 public class BandagedActivity extends AppCompatActivity
 {
+    public static final float SPINNER_TEXT_SIZE = 0.03f;
+    public static final float PADDING           = 0.010f;
+    public static final int FLAGS               = MainActivity.FLAGS;
+    public static final float RATIO_SCROLL      = 0.30f;
+
     private static final int ACTIVITY_NUMBER    = 2;
     private static final float RATIO_BAR        = MainActivity.RATIO_BAR;
     private static final float RATIO_BUT        = 0.07f;
-    static final float RATIO_SCROLL             = 0.30f;
-    public static final float SPINNER_TEXT_SIZE = 0.03f;
-    private static final float PADDING          = 0.010f;
-    public static final int FLAGS               = MainActivity.FLAGS;
     private static final int NUM_SCRAMBLES      = 300;
 
     private static int mScreenWidth, mScreenHeight;
@@ -312,6 +313,7 @@ public class BandagedActivity extends AppCompatActivity
     public void playObject(String name)
       {
       Intent intent = new Intent(this, PlayActivity.class);
+      intent.putExtra("level", 0);
       intent.putExtra("name", name);
       intent.putExtra("scrambles", NUM_SCRAMBLES);
       intent.putExtra("local", true);
diff --git a/src/main/java/org/distorted/bandaged/BandagedScreen.java b/src/main/java/org/distorted/bandaged/BandagedScreen.java
index 4d9859b6..966545f2 100644
--- a/src/main/java/org/distorted/bandaged/BandagedScreen.java
+++ b/src/main/java/org/distorted/bandaged/BandagedScreen.java
@@ -29,7 +29,6 @@ import android.widget.TextView;
 import org.distorted.external.RubikFiles;
 import org.distorted.helpers.TransparentImageButton;
 import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
 import org.distorted.objectlib.bandaged.LocallyBandagedList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -151,7 +150,7 @@ public class BandagedScreen implements AdapterView.OnItemSelectedListener
 
     int width  = act.getScreenWidthInPixels();
     int height = act.getScreenHeightInPixels();
-    int padding= (int)(height*RubikActivity.PADDING/3);
+    int padding= (int)(height*BandagedActivity.PADDING/3);
 
     LinearLayout.LayoutParams paramsL = new LinearLayout.LayoutParams(width/4, LinearLayout.LayoutParams.MATCH_PARENT);
     LinearLayout.LayoutParams paramsM = new LinearLayout.LayoutParams(width/2, LinearLayout.LayoutParams.MATCH_PARENT);
diff --git a/src/main/java/org/distorted/config/ConfigActivity.java b/src/main/java/org/distorted/config/ConfigActivity.java
index 6870ad87..d52b4cc5 100644
--- a/src/main/java/org/distorted/config/ConfigActivity.java
+++ b/src/main/java/org/distorted/config/ConfigActivity.java
@@ -22,7 +22,6 @@ import androidx.appcompat.app.AppCompatActivity;
 
 import org.distorted.library.main.DistortedLibrary;
 import org.distorted.main.MainActivity;
-import org.distorted.main_old.RubikActivity;
 import org.distorted.objectlib.main.InitAssets;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.main.R;
@@ -37,7 +36,7 @@ public class ConfigActivity extends AppCompatActivity
 {
     private static final int ACTIVITY_NUMBER = 1;
     private static final float RATIO_BAR  = MainActivity.RATIO_BAR;
-    public static final int FLAGS = RubikActivity.FLAGS;
+    public static final int FLAGS = MainActivity.FLAGS;
 
     private static int mScreenWidth, mScreenHeight;
     private int mCurrentApiVersion;
diff --git a/src/main/java/org/distorted/config/ConfigScreen.java b/src/main/java/org/distorted/config/ConfigScreen.java
index 8d69f260..19a21a78 100644
--- a/src/main/java/org/distorted/config/ConfigScreen.java
+++ b/src/main/java/org/distorted/config/ConfigScreen.java
@@ -23,8 +23,8 @@ import android.widget.TextView;
 import org.distorted.helpers.PopupCreator;
 
 import org.distorted.helpers.TransparentImageButton;
+import org.distorted.main.MainActivity;
 import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
 import org.distorted.objects.RubikObject;
 import org.distorted.objects.RubikObjectList;
 
@@ -39,6 +39,8 @@ public class ConfigScreen
   private static final float MARGIN    = 0.0024f;
   private static final int NUM_COLUMNS = 5;
   private static final int[] mLocation = new int[2];
+  private static final float POPUP_PADDING = 0.028f;
+  private static final float POPUP_MARGIN  = 0.016f;
 
   private TransparentImageButton mBackButton, mObjectButton, mPrevButton, mNextButton;
   private TextView mMovesText;
@@ -59,8 +61,8 @@ public class ConfigScreen
     mColCount = NUM_COLUMNS;
 
     int cubeSize  = (int)( (Math.min(width,(int)(height*0.7f))) / 9 );
-    int margin    = (int)(height*RubikActivity.POPUP_MARGIN);
-    int padding   = (int)(height*RubikActivity.POPUP_PADDING);
+    int margin    = (int)(height*POPUP_MARGIN);
+    int padding   = (int)(height*POPUP_PADDING);
     mObjectSize   = (int)(cubeSize + 2*margin + 0.5f);
     mMaxRowCount  = (int)((height-mBarHeight)/mObjectSize);
 
@@ -136,7 +138,7 @@ public class ConfigScreen
 
         int rowCount = Math.min(mMaxRowCount,mRowCount);
         View popupView = mObjectPopup.getContentView();
-        popupView.setSystemUiVisibility(RubikActivity.FLAGS);
+        popupView.setSystemUiVisibility(MainActivity.FLAGS);
         displayPopup(act,view,mObjectPopup,mObjectSize*mColCount,mObjectSize*rowCount+5*margin,margin,margin);
         }
       });
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogAbandon.java b/src/main/java/org/distorted/dialogs/RubikDialogAbandon.java
index 7a94d836..e13e5dcb 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogAbandon.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogAbandon.java
@@ -15,8 +15,8 @@ import android.view.View;
 import androidx.fragment.app.FragmentActivity;
 
 import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.screens.ScreenList;
+import org.distorted.playui.PlayActivity;
+import org.distorted.playui.ScreenList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -27,26 +27,14 @@ public class RubikDialogAbandon extends RubikDialogAbstract
   public boolean hasArgument()  { return false; }
   public int getPositive()      { return R.string.yes; }
   public int getNegative()      { return R.string.no; }
+  public void negativeAction()  { }
+  public void prepareBody(Dialog dialog, View view, FragmentActivity act, float size) { }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public void positiveAction()
     {
-    final RubikActivity ract = (RubikActivity)getContext();
-    ScreenList.goBack(ract);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void negativeAction()
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void prepareBody(Dialog dialog, View view, FragmentActivity act, float size)
-    {
-
+    final PlayActivity act = (PlayActivity)getContext();
+    ScreenList.goBack(act);
     }
   }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogAbstract.java b/src/main/java/org/distorted/dialogs/RubikDialogAbstract.java
index 5349d3b2..c4493b5f 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogAbstract.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogAbstract.java
@@ -25,8 +25,8 @@ import androidx.appcompat.app.AlertDialog;
 import androidx.appcompat.app.AppCompatDialogFragment;
 import androidx.fragment.app.FragmentActivity;
 
+import org.distorted.main.MainActivity;
 import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -147,7 +147,7 @@ abstract public class RubikDialogAbstract extends AppCompatDialogFragment
 
     if( window!=null )
       {
-      window.getDecorView().setSystemUiVisibility(RubikActivity.FLAGS);
+      window.getDecorView().setSystemUiVisibility(MainActivity.FLAGS);
       }
 
     dialog.setOnShowListener(new DialogInterface.OnShowListener()
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java b/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
index f7904624..93ac47fa 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
@@ -56,8 +56,6 @@ public class RubikDialogNewRecord extends RubikDialogAbstract
         nameDiag.setArguments(bundle);
         nameDiag.show(act.getSupportFragmentManager(), null);
         }
-
-      act.finish();
       }
     }
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPattern.java b/src/main/java/org/distorted/dialogs/RubikDialogPattern.java
deleted file mode 100644
index 883b8782..00000000
--- a/src/main/java/org/distorted/dialogs/RubikDialogPattern.java
+++ /dev/null
@@ -1,107 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.dialogs;
-
-import android.app.Dialog;
-import androidx.fragment.app.FragmentActivity;
-import androidx.viewpager.widget.ViewPager;
-import com.google.android.material.tabs.TabLayout;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.ImageView;
-
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.objects.RubikObject;
-import org.distorted.objects.RubikObjectList;
-import org.distorted.objectlib.patterns.RubikPatternList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikDialogPattern extends RubikDialogAbstract
-  {
-  private RubikDialogPatternPagerAdapter mPagerAdapter;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public void onResume()
-    {
-    super.onResume();
-
-    Window window = getDialog().getWindow();
-
-    if( window!=null )
-      {
-      WindowManager.LayoutParams params = window.getAttributes();
-      params.width  = (int)Math.min( mHeight*0.65f,mWidth*0.98f );
-      params.height = (int)Math.min( mHeight*0.85f,mWidth*1.30f );
-      window.setAttributes(params);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getResource()      { return R.layout.dialog_tabbed; }
-  public int getTitleResource() { return R.string.choose_pattern; }
-  public boolean hasArgument()  { return false; }
-  public int getPositive()      { return R.string.ok; }
-  public int getNegative()      { return -1; }
-  public void positiveAction()  { }
-  public void negativeAction()  { }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void prepareBody(Dialog dialog, View view, FragmentActivity act, float size)
-    {
-    final int tabHeight= (int)(mHeight*RubikActivity.TAB_HEIGHT);
-    final int tabWidth = (int)(mHeight*RubikActivity.TAB_WIDTH);
-
-    ViewPager viewPager = view.findViewById(R.id.viewpager);
-    TabLayout tabLayout = view.findViewById(R.id.sliding_tabs);
-    mPagerAdapter = new RubikDialogPatternPagerAdapter(act, viewPager, this);
-    tabLayout.setupWithViewPager(viewPager);
-
-    int obj = RubikObjectList.getCurrObject();
-    int ord = RubikPatternList.getOrdinal(obj);
-    if( ord<0 ) ord = RubikPatternList.getOrdinal(RubikObjectList.DEF_OBJECT);
-    viewPager.setCurrentItem(ord);
-
-    ViewGroup.LayoutParams paramsView = new ViewGroup.LayoutParams( tabWidth,tabHeight );
-
-    for(int i=0; i< RubikPatternList.NUM_OBJECTS; i++)
-      {
-      int ordinal = RubikPatternList.getObject(i);
-      RubikObject object = RubikObjectList.getObject(ordinal);
-      ImageView imageView = new ImageView(act);
-      if( object!=null ) object.setIconTo(act,imageView);
-      imageView.setLayoutParams(paramsView);
-      TabLayout.Tab tab = tabLayout.getTabAt(i);
-      if(tab!=null) tab.setCustomView(imageView);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void rememberState()
-    {
-    mPagerAdapter.rememberState();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static String getDialogTag()
-    {
-    return "DialogPattern";
-    }
-  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPatternListAdapter.java b/src/main/java/org/distorted/dialogs/RubikDialogPatternListAdapter.java
index 45d6ebd0..29062b52 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogPatternListAdapter.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogPatternListAdapter.java
@@ -1,10 +1,11 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
+// Copyright 2023 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
 // Magic Cube is proprietary software licensed under an EULA which you should have received      //
 // along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.dialogs;
@@ -16,7 +17,6 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.BaseExpandableListAdapter;
 import android.widget.TextView;
-
 import org.distorted.objectlib.patterns.RubikPattern;
 import org.distorted.main.R;
 
@@ -26,7 +26,6 @@ class RubikDialogPatternListAdapter extends BaseExpandableListAdapter
   {
   private static final float PATTERN_CHILD_TEXT  = 0.038f;
   private static final float PATTERN_GROUP_TEXT  = 0.060f;
-
   private final Context mContext;
   private final int mTab, mWidth;
 
@@ -70,11 +69,9 @@ class RubikDialogPatternListAdapter extends BaseExpandableListAdapter
       }
 
     int size = (int)(mWidth*PATTERN_CHILD_TEXT);
-
     TextView childItem = view.findViewById(R.id.child);
     childItem.setText(childName);
     childItem.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
-
     return view;
     }
 
@@ -127,17 +124,14 @@ class RubikDialogPatternListAdapter extends BaseExpandableListAdapter
       }
 
     int size = (int)(mWidth*PATTERN_GROUP_TEXT);
-
     TextView heading = view.findViewById(R.id.heading);
     heading.setText(groupName);
     heading.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
-
     RubikPattern pattern = RubikPattern.getInstance();
     int numPatterns = pattern.getNumPatterns(mTab,groupPosition);
     TextView counter = view.findViewById(R.id.counter);
     counter.setText(String.format("%d", numPatterns));
     counter.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
-
     return view;
     }
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPatternPagerAdapter.java b/src/main/java/org/distorted/dialogs/RubikDialogPatternPagerAdapter.java
deleted file mode 100644
index 5abab890..00000000
--- a/src/main/java/org/distorted/dialogs/RubikDialogPatternPagerAdapter.java
+++ /dev/null
@@ -1,95 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.dialogs;
-
-import androidx.annotation.NonNull;
-import androidx.fragment.app.FragmentActivity;
-import androidx.viewpager.widget.PagerAdapter;
-import androidx.viewpager.widget.ViewPager;
-import android.view.View;
-import android.view.ViewGroup;
-
-import org.distorted.objectlib.patterns.RubikPattern;
-import org.distorted.objectlib.patterns.RubikPatternList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class RubikDialogPatternPagerAdapter extends PagerAdapter
-  {
-  private final FragmentActivity mAct;
-  private final RubikDialogPatternView[] mViews;
-  private final RubikDialogPattern mDialog;
-  private final int mNumTabs;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  RubikDialogPatternPagerAdapter(FragmentActivity act, ViewPager viewPager, RubikDialogPattern dialog)
-    {
-    mAct = act;
-    mDialog = dialog;
-    mNumTabs = RubikPatternList.NUM_OBJECTS;
-    mViews = new RubikDialogPatternView[mNumTabs];
-
-    viewPager.setAdapter(this);
-    viewPager.setOffscreenPageLimit(mNumTabs-1);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void rememberState()
-    {
-    RubikPattern pattern = RubikPattern.getInstance();
-
-    for(int i=0; i<mNumTabs; i++)
-      {
-      int cat = mViews[i].getCurrentCategory();
-      int pos = mViews[i].getCurrentVisiblePos();
-      int exp = mViews[i].getExpanded();
-      pattern.rememberState(i,cat,pos,exp);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  @NonNull
-  public Object instantiateItem(@NonNull ViewGroup collection, final int position)
-    {
-    mViews[position] = new RubikDialogPatternView(mAct, mDialog, position);
-    collection.addView(mViews[position]);
-
-    return mViews[position];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public void destroyItem(ViewGroup collection, int position, @NonNull Object view)
-    {
-    collection.removeView((View) view);
-    mViews[position] = null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public int getCount()
-    {
-    return mNumTabs;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public boolean isViewFromObject(@NonNull View view, @NonNull Object object)
-    {
-    return view == object;
-    }
-  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java b/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
deleted file mode 100644
index 9e302161..00000000
--- a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
+++ /dev/null
@@ -1,139 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.dialogs;
-
-import android.content.Context;
-import androidx.fragment.app.FragmentActivity;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ExpandableListView;
-import android.widget.FrameLayout;
-
-import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.patterns.RubikPattern;
-import org.distorted.objectlib.patterns.RubikPatternList;
-
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.screens.ScreenList;
-import org.distorted.screens.RubikScreenPattern;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikDialogPatternView extends FrameLayout
-  {
-  private ExpandableListView mListView;
-  private RubikDialogPattern mDialog;
-  private int mTab, mPos;
-  private int mExpandedGroup;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public RubikDialogPatternView(Context context, AttributeSet attrs, int defStyle)
-    {
-    super(context, attrs, defStyle);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public RubikDialogPatternView(Context context, AttributeSet attrs)
-    {
-    super(context, attrs);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public RubikDialogPatternView(FragmentActivity act, RubikDialogPattern dialog, int position)
-    {
-    super(act);
-
-    final RubikActivity ract = (RubikActivity)getContext();
-    final ObjectControl control = ract.getControl();
-
-    mTab = position;
-    mDialog = dialog;
-
-    RubikPattern pattern = RubikPattern.getInstance();
-    mExpandedGroup = pattern.recallExpanded(position);
-
-    View tab = inflate( act, R.layout.dialog_pattern_tab, null);
-
-    mListView = tab.findViewById(R.id.patternListView);
-    RubikDialogPatternListAdapter listAdapter = new RubikDialogPatternListAdapter(act,mTab, ract.getScreenWidthInPixels());
-    mListView.setAdapter(listAdapter);
-
-    if( mExpandedGroup>=0 )
-      {
-      mListView.expandGroup(mExpandedGroup);
-      }
-
-    int visible = pattern.recallVisiblePos(mTab);
-    mListView.setSelectionFromTop(visible,0);
-
-    mListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener()
-      {
-      @Override
-      public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id)
-        {
-        RubikPattern pattern = RubikPattern.getInstance();
-        int[][] moves   = pattern.reInitialize(mTab, groupPosition, childPosition);
-        int object = RubikPatternList.getObject(mTab);
-        ract.changeIfDifferent(object,control);
-        control.initializeObject(moves);
-
-        ScreenList.switchScreen(ract, ScreenList.PATT);
-        RubikScreenPattern state = (RubikScreenPattern) ScreenList.PATT.getScreenClass();
-        state.setPattern(ract, mTab, groupPosition, childPosition);
-
-        mDialog.rememberState();
-        mDialog.dismiss();
-
-        return false;
-        }
-      });
-
-    mListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener()
-      {
-      @Override
-      public void onGroupExpand(int groupPosition)
-        {
-        if(mExpandedGroup!=-1 && groupPosition!=mExpandedGroup)
-          {
-          mListView.collapseGroup(mExpandedGroup);
-          }
-
-        mExpandedGroup = groupPosition;
-        }
-      });
-
-    addView(tab);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getCurrentCategory()
-    {
-    return mPos;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getCurrentVisiblePos()
-    {
-    return mListView.getFirstVisiblePosition();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getExpanded()
-    {
-    return mExpandedGroup;
-    }
-  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPrivacy.java b/src/main/java/org/distorted/dialogs/RubikDialogPrivacy.java
deleted file mode 100644
index c6fbc5bf..00000000
--- a/src/main/java/org/distorted/dialogs/RubikDialogPrivacy.java
+++ /dev/null
@@ -1,56 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.dialogs;
-
-import android.app.Dialog;
-import android.text.method.LinkMovementMethod;
-import android.text.method.MovementMethod;
-import android.view.View;
-import android.widget.TextView;
-
-import androidx.fragment.app.FragmentActivity;
-
-import org.distorted.main.R;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikDialogPrivacy extends RubikDialogAbstract
-  {
-  public int getResource()      { return R.layout.dialog_privacy; }
-  public int getTitleResource() { return R.string.privacy_policy; }
-  public boolean hasArgument()  { return false; }
-  public int getPositive()      { return R.string.accept; }
-  public int getNegative()      { return R.string.decline; }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void positiveAction()
-    {
-    //final RubikActivity act = (RubikActivity)getContext();
-    //if( act!=null ) act.acceptPrivacy();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void negativeAction()
-    {
-    //final RubikActivity act = (RubikActivity)getContext();
-    //if( act!=null ) act.declinePrivacy();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void prepareBody(Dialog dialog, View view, FragmentActivity act, float size)
-    {
-    MovementMethod mm = LinkMovementMethod.getInstance();
-    TextView text = view.findViewById(R.id.privacy_string);
-    text.setMovementMethod(mm);
-    }
-  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogScores.java b/src/main/java/org/distorted/dialogs/RubikDialogScores.java
index ec682f70..60a600d1 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogScores.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogScores.java
@@ -21,7 +21,6 @@ import android.view.WindowManager;
 import android.widget.ImageView;
 
 import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
 import org.distorted.objects.RubikObject;
 import org.distorted.objects.RubikObjectList;
 
@@ -29,6 +28,9 @@ import org.distorted.objects.RubikObjectList;
 
 public class RubikDialogScores extends RubikDialogAbstract
   {
+  private static final float TAB_WIDTH = 0.066f;
+  private static final float TAB_HEIGHT= 0.066f;
+
   private RubikDialogScoresPagerAdapter mPagerAdapter;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -63,8 +65,8 @@ public class RubikDialogScores extends RubikDialogAbstract
 
   public void prepareBody(Dialog dialog, View view, FragmentActivity act, float size)
     {
-    final int tabHeight= (int)(mHeight*RubikActivity.TAB_HEIGHT);
-    final int tabWidth = (int)(mHeight*RubikActivity.TAB_WIDTH);
+    final int tabHeight= (int)(mHeight*TAB_HEIGHT);
+    final int tabWidth = (int)(mHeight*TAB_WIDTH);
 
     ViewPager viewPager = view.findViewById(R.id.viewpager);
     TabLayout tabLayout = view.findViewById(R.id.sliding_tabs);
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java b/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java
index 54149636..6ef74725 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java
@@ -18,14 +18,13 @@ import androidx.viewpager.widget.ViewPager;
 import android.util.DisplayMetrics;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.LinearLayout;
 
 import org.distorted.main.R;
 import org.distorted.external.RubikScores;
 import org.distorted.external.RubikNetwork;
 import org.distorted.objects.RubikObject;
 import org.distorted.objects.RubikObjectList;
-import org.distorted.screens.RubikScreenPlay;
+import static org.distorted.external.RubikScores.LEVELS_SHOWN;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -138,7 +137,7 @@ class RubikDialogScoresPagerAdapter extends PagerAdapter implements RubikNetwork
       {
       RubikObject object = RubikObjectList.getObject(i);
       int numScramble = object==null ? 1 : object.getNumScramble();
-      mNumLevels[i] = Math.min(numScramble-1, RubikScreenPlay.LEVELS_SHOWN);
+      mNumLevels[i] = Math.min(numScramble-1,LEVELS_SHOWN);
       }
 
     viewPager.setAdapter(this);
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogScoresView.java b/src/main/java/org/distorted/dialogs/RubikDialogScoresView.java
index c1802d34..3dda3a08 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogScoresView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogScoresView.java
@@ -21,7 +21,6 @@ import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
 import org.distorted.external.RubikScores;
 
 import static org.distorted.external.RubikNetwork.MAX_PLACES;
@@ -30,6 +29,9 @@ import static org.distorted.external.RubikNetwork.MAX_PLACES;
 
 public class RubikDialogScoresView extends FrameLayout
   {
+  private static final float SCORES_LEVEL_TEXT = 0.035f;
+  private static final float SCORES_ITEM_TEXT  = 0.025f;
+
   private LinearLayout mLayout=null;
   private int mHeight;
 
@@ -72,7 +74,7 @@ public class RubikDialogScoresView extends FrameLayout
     TextView text = levelLayout.findViewById(R.id.scoresScrambleTitle);
     text.setText(title);
 
-    int size = (int)(mHeight*RubikActivity.SCORES_LEVEL_TEXT);
+    int size = (int)(mHeight*SCORES_LEVEL_TEXT);
     text.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
 
     Resources res = act.getResources();
@@ -88,7 +90,7 @@ public class RubikDialogScoresView extends FrameLayout
     String theirTime;
     int theirCountryID;
 
-    int height = (int)(mHeight* RubikActivity.SCORES_ITEM_TEXT);
+    int height = (int)(mHeight*SCORES_ITEM_TEXT);
     int white = res.getColor(R.color.white);
     int red   = res.getColor(R.color.red);
     boolean equals;
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogSetName.java b/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
index 94d091e1..f98c76b3 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
@@ -23,9 +23,8 @@ import android.widget.EditText;
 import android.widget.TextView;
 
 import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
 import org.distorted.external.RubikScores;
-import org.distorted.screens.ScreenList;
+import org.distorted.playui.PlayActivity;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -81,10 +80,8 @@ public class RubikDialogSetName extends RubikDialogAbstract
 
       try
         {
-        RubikActivity act = (RubikActivity)getActivity();
-        ScreenList.switchScreen(act, ScreenList.PLAY);
+        PlayActivity act = (PlayActivity)getActivity();
         RubikScores.getInstance().setName(name);
-
         Bundle bundle = new Bundle();
         bundle.putString("argument", "true");
         RubikDialogScores scores = new RubikDialogScores();
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogSolved.java b/src/main/java/org/distorted/dialogs/RubikDialogSolved.java
index 9643de2b..564558e4 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogSolved.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogSolved.java
@@ -17,8 +17,7 @@ import android.view.View;
 import android.widget.TextView;
 
 import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.screens.ScreenList;
+import org.distorted.playui.PlayActivity;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -34,8 +33,8 @@ public class RubikDialogSolved extends RubikDialogAbstract
 
   public void positiveAction()
     {
-    RubikActivity act = (RubikActivity)getActivity();
-    ScreenList.switchScreen(act, ScreenList.PLAY);
+    PlayActivity act = (PlayActivity)getActivity();
+    if( act!=null ) act.finish();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogSolverView.java b/src/main/java/org/distorted/dialogs/RubikDialogSolverView.java
deleted file mode 100644
index 00b41f69..00000000
--- a/src/main/java/org/distorted/dialogs/RubikDialogSolverView.java
+++ /dev/null
@@ -1,75 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2023 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.dialogs;
-
-import android.util.TypedValue;
-import android.view.View;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.objects.RubikObject;
-import org.distorted.objects.RubikObjectList;
-import org.distorted.screens.ScreenList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikDialogSolverView
-  {
-  private final View mView;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public RubikDialogSolverView(final RubikActivity act, final RubikDialogSolvers dialog, int index, int object,
-                               int title, int desc, int padding, int fontSize, LinearLayout.LayoutParams pView,
-                               LinearLayout.LayoutParams pText, LinearLayout.LayoutParams pButt )
-    {
-    mView = act.getLayoutInflater().inflate(R.layout.dialog_solvers_pane, null);
-    mView.setLayoutParams(pView);
-    mView.setPadding(padding,padding,padding,padding);
-
-    TextView titleView = mView.findViewById(R.id.solvers_pane_title);
-    titleView.setText(title);
-    TextView descView = mView.findViewById(R.id.solvers_pane_description);
-    descView.setText(desc);
-
-    titleView.setLayoutParams(pText);
-
-    ImageView icon = mView.findViewById(R.id.solvers_pane_image);
-    RubikObject robject = RubikObjectList.getObject(object);
-    if( robject!=null ) robject.setIconTo(act,icon);
-
-    Button button = mView.findViewById(R.id.solvers_pane_button);
-
-    button.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        dialog.dismiss();
-        act.setSolverIndex(index);
-        ScreenList.switchScreen(act, ScreenList.SVER);
-        }
-      });
-
-    button.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize);
-    button.setLayoutParams(pButt);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public View getView()
-    {
-    return mView;
-    }
-  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogSolvers.java b/src/main/java/org/distorted/dialogs/RubikDialogSolvers.java
deleted file mode 100644
index 580c9ad8..00000000
--- a/src/main/java/org/distorted/dialogs/RubikDialogSolvers.java
+++ /dev/null
@@ -1,89 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2022 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.dialogs;
-
-import android.app.Dialog;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.fragment.app.FragmentActivity;
-
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.solvers.ImplementedSolversList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikDialogSolvers extends RubikDialogAbstract
-  {
-  @Override
-  public void onResume()
-    {
-    super.onResume();
-
-    Window window = getDialog().getWindow();
-
-    if( window!=null )
-      {
-      WindowManager.LayoutParams params = window.getAttributes();
-      params.width  = (int)Math.min( mHeight*0.65f,mWidth*0.98f );
-      window.setAttributes(params);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getResource()            { return R.layout.dialog_scrollable_panes; }
-  public int getTitleResource()       { return R.string.solver; }
-  public boolean hasArgument()        { return false; }
-  public int getPositive()            { return R.string.ok; }
-  public int getNegative()            { return -1; }
-  public static String getDialogTag() { return "DialogSolvers"; }
-  public void positiveAction()        { }
-  public void negativeAction()        { }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void prepareBody(Dialog dialog, View view, FragmentActivity act, float size)
-    {
-    int margin= (int)(mHeight*0.010f);
-    int padd  = (int)(mHeight*0.010f);
-    int font  = (int)(mHeight*0.025f);
-
-    LinearLayout layout= view.findViewById(R.id.dialog_scrollable_main_layout);
-    TextView text  = view.findViewById(R.id.dialog_scrollable_message);
-    text.setVisibility(View.GONE);
-
-    LinearLayout.LayoutParams pV = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT );
-    pV.setMargins(margin, margin, margin, 0);
-    LinearLayout.LayoutParams pL = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT );
-    pL.setMargins(margin, margin, margin, margin);
-    LinearLayout.LayoutParams pT = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT );
-    pT.setMargins(0,0,0,2*margin);
-    LinearLayout.LayoutParams pB = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT );
-    pB.setMargins(0,2*margin,0,0);
-
-    int num = ImplementedSolversList.NUM_OBJECTS;
-    RubikActivity ract = (RubikActivity) getContext();
-
-    for(int i=0; i<num; i++)
-      {
-      ImplementedSolversList solver = ImplementedSolversList.getSolver(i);
-      int object = solver.getObject();
-      int title  = solver.getTitle();
-      int description = solver.getDescription();
-      RubikDialogSolverView pane = new RubikDialogSolverView(ract,this,i,object,title,description, padd, font, (i==num-1?pL:pV),pT,pB);
-      layout.addView(pane.getView());
-      }
-    }
-  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogTutorial.java b/src/main/java/org/distorted/dialogs/RubikDialogTutorial.java
deleted file mode 100644
index e0e1d491..00000000
--- a/src/main/java/org/distorted/dialogs/RubikDialogTutorial.java
+++ /dev/null
@@ -1,101 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.dialogs;
-
-import android.app.Dialog;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.ImageView;
-
-import androidx.fragment.app.FragmentActivity;
-import androidx.viewpager.widget.ViewPager;
-
-import com.google.android.material.tabs.TabLayout;
-
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.objects.RubikObject;
-import org.distorted.objects.RubikObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikDialogTutorial extends RubikDialogAbstract
-  {
-  private RubikDialogTutorialPagerAdapter mPagerAdapter;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public void onResume()
-    {
-    super.onResume();
-
-    if( mPagerAdapter!=null ) mPagerAdapter.clickPossible();
-
-    Window window = getDialog().getWindow();
-
-    if( window!=null )
-      {
-      WindowManager.LayoutParams params = window.getAttributes();
-      params.width  = (int)Math.min( mHeight*0.65f,mWidth*0.98f );
-      params.height = (int)Math.min( mHeight*0.85f,mWidth*1.30f );
-      window.setAttributes(params);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getResource()      { return R.layout.dialog_tabbed; }
-  public int getTitleResource() { return R.string.tutorials; }
-  public boolean hasArgument()  { return false; }
-  public int getPositive()      { return R.string.ok; }
-  public int getNegative()      { return -1; }
-  public void positiveAction()  { }
-  public void negativeAction()  { }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void prepareBody(Dialog dialog, View view, FragmentActivity act, float size)
-    {
-    final int tabHeight= (int)(mHeight*RubikActivity.TAB_HEIGHT);
-    final int tabWidth = (int)(mHeight*RubikActivity.TAB_WIDTH);
-
-    ViewPager viewPager = view.findViewById(R.id.viewpager);
-    TabLayout tabLayout = view.findViewById(R.id.sliding_tabs);
-    mPagerAdapter = new RubikDialogTutorialPagerAdapter(act,viewPager);
-    tabLayout.setupWithViewPager(viewPager);
-    int obj = RubikObjectList.getCurrObject();
-    int ord = RubikObjectList.getTutorialOrdinal(obj);
-    viewPager.setCurrentItem(ord);
-
-    ViewGroup.LayoutParams paramsView = new ViewGroup.LayoutParams( tabWidth,tabHeight );
-    int numObjects = RubikObjectList.getNumTutorialObjects();
-
-    for(int i=0; i<numObjects; i++)
-      {
-      int oOrdinal = RubikObjectList.getObjectOrdinal(i);
-      RubikObject object = RubikObjectList.getObject(oOrdinal);
-      ImageView imageView = new ImageView(act);
-      imageView.setLayoutParams(paramsView);
-      if( object!=null ) object.setIconTo(act,imageView);
-      TabLayout.Tab tab = tabLayout.getTabAt(i);
-      if(tab!=null) tab.setCustomView(imageView);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static String getDialogTag()
-    {
-    return "DialogTutorial";
-    }
-  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogTutorialPagerAdapter.java b/src/main/java/org/distorted/dialogs/RubikDialogTutorialPagerAdapter.java
deleted file mode 100644
index 42ba6189..00000000
--- a/src/main/java/org/distorted/dialogs/RubikDialogTutorialPagerAdapter.java
+++ /dev/null
@@ -1,94 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.dialogs;
-
-import android.util.DisplayMetrics;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.fragment.app.FragmentActivity;
-import androidx.viewpager.widget.PagerAdapter;
-import androidx.viewpager.widget.ViewPager;
-
-import org.distorted.objects.RubikObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class RubikDialogTutorialPagerAdapter extends PagerAdapter
-  {
-  private final FragmentActivity mAct;
-  private final RubikDialogTutorialView[] mViews;
-  private final int mNumTabs;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  RubikDialogTutorialPagerAdapter(FragmentActivity act, ViewPager viewPager)
-    {
-    mAct     = act;
-    mNumTabs = RubikObjectList.getNumTutorialObjects();
-    mViews   = new RubikDialogTutorialView[mNumTabs];
-
-    viewPager.setAdapter(this);
-    viewPager.setOffscreenPageLimit(1);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void clickPossible()
-    {
-    for(int i=0; i<mNumTabs; i++)
-      {
-      if( mViews[i]!=null )
-        {
-        mViews[i].clickPossible(true);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  @NonNull
-  public Object instantiateItem(@NonNull ViewGroup collection, final int position)
-    {
-    DisplayMetrics metrics = mAct.getResources().getDisplayMetrics();
-
-    mViews[position] = new RubikDialogTutorialView(mAct, metrics.heightPixels, position);
-    collection.addView(mViews[position]);
-
-    return mViews[position];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public void destroyItem(ViewGroup collection, int position, @NonNull Object view)
-    {
-    collection.removeView((View) view);
-    mViews[position] = null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public int getCount()
-    {
-    return mNumTabs;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public boolean isViewFromObject(@NonNull View view, @NonNull Object object)
-    {
-    return view == object;
-    }
-  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogTutorialView.java b/src/main/java/org/distorted/dialogs/RubikDialogTutorialView.java
deleted file mode 100644
index 408b83f2..00000000
--- a/src/main/java/org/distorted/dialogs/RubikDialogTutorialView.java
+++ /dev/null
@@ -1,191 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.dialogs;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.View;
-import android.widget.Button;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.fragment.app.FragmentActivity;
-
-import com.google.firebase.analytics.FirebaseAnalytics;
-
-import org.distorted.main.BuildConfig;
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.objectlib.json.JsonReader;
-import org.distorted.objects.RubikObject;
-import org.distorted.objects.RubikObjectList;
-
-import java.io.InputStream;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikDialogTutorialView extends FrameLayout
-  {
-  public static final float PANE_HEIGHT  = 0.06f;
-  private boolean mCanClick;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public RubikDialogTutorialView(Context context, AttributeSet attrs, int defStyle)
-    {
-    super(context, attrs, defStyle);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public RubikDialogTutorialView(Context context, AttributeSet attrs)
-    {
-    super(context, attrs);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public RubikDialogTutorialView(FragmentActivity act, int height, int position)
-    {
-    super(act);
-
-    int objectOrdinal = RubikObjectList.getObjectOrdinal(position);
-    RubikObject robject = RubikObjectList.getObject(objectOrdinal);
-    InputStream jsonStream = robject==null ? null : robject.getExtrasStream(act);
-    String[][] tutorials=null;
-
-    if( jsonStream!=null )
-      {
-      try
-        {
-        JsonReader reader = new JsonReader();
-        reader.parseJsonTutorial(jsonStream);
-        tutorials = reader.getTutorials();
-        }
-      catch(Exception ignored) { }
-      }
-
-    if( tutorials!=null )
-      {
-      clickPossible(true);
-      int size = (int)(height*PANE_HEIGHT);
-
-      RubikActivity ract = (RubikActivity)getContext();
-      Resources res = act.getResources();
-      String packageName = act.getPackageName();
-
-      View tab = inflate( act, R.layout.dialog_tutorial_tab, null);
-      LinearLayout layout = tab.findViewById(R.id.tabLayout);
-
-      int colorB = getResources().getColor(R.color.light_grey);
-      int colorT = getResources().getColor(R.color.white);
-
-      for (String[] tutorial : tutorials)
-        {
-        String coun = tutorial[0];
-        String url  = tutorial[1];
-        String desc = tutorial[2];
-        String auth = tutorial[3];
-
-        int countryID = res.getIdentifier(coun, "drawable", packageName);
-
-        View row = createRow(ract, countryID, desc, url, auth, size, objectOrdinal, colorB, colorT);
-        layout.addView(row);
-        }
-
-      addView(tab);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void clickPossible(boolean click)
-    {
-    mCanClick = click;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private View createRow(final RubikActivity act, int countryID, final String desc, final String url,
-                         final String auth, int size, final int obj, int colorB, int colorT)
-    {
-    float textSize = 0.43f*size;
-    View row = inflate( act, R.layout.dialog_tutorial_row, null);
-
-    LinearLayout layout = row.findViewById(R.id.tutorialLayout);
-    layout.setMinimumHeight(size);
-
-    Button butt = row.findViewById(R.id.tutorialButton);
-    butt.setText(R.string.view);
-    butt.setTextColor(colorT);
-    butt.setBackgroundColor(colorB);
-    butt.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
-    butt.setHeight(size);
-
-    butt.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        if( mCanClick )
-          {
-          act.switchToTutorial(url,obj);
-          analyticsReport(act,desc,auth,obj);
-          clickPossible(false);
-          }
-        }
-      });
-
-    ImageView image = row.findViewById(R.id.tutorialCountry);
-    int id = countryID!=0 ? countryID : org.distorted.flags.R.drawable.unknown;
-    image.setImageResource(id);
-
-    TextView author = row.findViewById(R.id.tutorialAuthor);
-    author.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
-    author.setText(auth);
-
-    TextView title  = row.findViewById(R.id.tutorialTitle);
-    title.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
-    title.setText(desc);
-
-    return row;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void analyticsReport(RubikActivity act, String desc, String author, int obj)
-    {
-    String message = desc+" ("+author+")";
-
-    if( BuildConfig.DEBUG )
-       {
-       android.util.Log.d("tutorial", message);
-       }
-    else
-      {
-      FirebaseAnalytics analytics = act.getAnalytics();
-
-      if( analytics!=null )
-        {
-        RubikObject object = RubikObjectList.getObject(obj);
-
-        Bundle bundle = new Bundle();
-        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, message);
-        bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, object==null ? "NULL" : object.getLowerName() );
-        analytics.logEvent(FirebaseAnalytics.Event.TUTORIAL_BEGIN, bundle);
-        }
-      }
-    }
-  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java b/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java
index cf77e074..c8b28757 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java
@@ -32,7 +32,7 @@ import org.distorted.external.RubikUpdates;
 import org.distorted.objectlib.json.JsonReader;
 import org.distorted.objects.RubikObjectList;
 
-import static org.distorted.main_old.RubikActivity.SHOW_DOWNLOADED_DEBUG;
+import static org.distorted.objects.RubikObjectList.SHOW_DOWNLOADED_DEBUG;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/external/RubikNetwork.java b/src/main/java/org/distorted/external/RubikNetwork.java
index 885701b2..87e090ac 100644
--- a/src/main/java/org/distorted/external/RubikNetwork.java
+++ b/src/main/java/org/distorted/external/RubikNetwork.java
@@ -30,8 +30,8 @@ import android.graphics.BitmapFactory;
 import org.distorted.objectlib.json.JsonWriter;
 import org.distorted.objects.RubikObjectList;
 
-import static org.distorted.main_old.RubikActivity.SHOW_DOWNLOADED_DEBUG;
-import static org.distorted.screens.RubikScreenPlay.LEVELS_SHOWN;
+import static org.distorted.objects.RubikObjectList.SHOW_DOWNLOADED_DEBUG;
+import static org.distorted.external.RubikScores.LEVELS_SHOWN;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/external/RubikScores.java b/src/main/java/org/distorted/external/RubikScores.java
index 8fb79473..d34ccff9 100644
--- a/src/main/java/org/distorted/external/RubikScores.java
+++ b/src/main/java/org/distorted/external/RubikScores.java
@@ -21,16 +21,15 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics;
 import org.distorted.main.BuildConfig;
 import org.distorted.objects.RubikObject;
 import org.distorted.objects.RubikObjectList;
-import org.distorted.screens.RubikScreenPlay;
 
 import static org.distorted.objectlib.main.ObjectType.MAX_SCRAMBLES;
-import static org.distorted.screens.RubikScreenPlay.LEVELS_SHOWN;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // hold my own scores, and some other statistics.
 
 public class RubikScores
   {
+  public static final int LEVELS_SHOWN   = 8;
   public static final int RECORD_FIRST   = 0;
   public static final int RECORD_NEW     = 1;
   public static final int RECORD_NOT_NEW = 2;
@@ -259,7 +258,7 @@ public class RubikScores
 
     for(int obj=0; obj<numObjects; obj++)
       {
-      for(int level=0; level<=RubikScreenPlay.LEVELS_SHOWN; level++)
+      for(int level=0; level<=LEVELS_SHOWN; level++)
         {
         if( isSolved(obj,level) )
           {
@@ -504,11 +503,11 @@ public class RubikScores
   public int numberOfSolvedMAXes()
     {
     int numObjects = RubikObjectList.getNumObjects();
-    int ret=0, level = RubikScreenPlay.LEVELS_SHOWN;
+    int ret=0;
 
     for(int obj=0; obj<numObjects; obj++)
       {
-      if( isSolved(obj,level) ) ret++;
+      if( isSolved(obj,LEVELS_SHOWN) ) ret++;
       }
 
     return ret;
diff --git a/src/main/java/org/distorted/external/RubikUpdates.java b/src/main/java/org/distorted/external/RubikUpdates.java
index 24078d7a..b9d6f2a1 100644
--- a/src/main/java/org/distorted/external/RubikUpdates.java
+++ b/src/main/java/org/distorted/external/RubikUpdates.java
@@ -17,7 +17,7 @@ import android.content.Context;
 import android.graphics.Bitmap;
 import org.distorted.objects.RubikObjectList;
 
-import static org.distorted.main_old.RubikActivity.SHOW_DOWNLOADED_DEBUG;
+import static org.distorted.objects.RubikObjectList.SHOW_DOWNLOADED_DEBUG;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/helpers/MovesController.java b/src/main/java/org/distorted/helpers/MovesController.java
index 8adb8320..f8390c0c 100644
--- a/src/main/java/org/distorted/helpers/MovesController.java
+++ b/src/main/java/org/distorted/helpers/MovesController.java
@@ -163,6 +163,9 @@ public class MovesController implements MovesFinished
       StringBuilder moves = new StringBuilder();
       int numMoves = getNumMoves();
 
+
+      android.util.Log.e("D", "saving moves: "+numMoves);
+
       for(int m=0; m<numMoves; m++)
         {
         Move move = mMoves.get(m);
@@ -190,6 +193,8 @@ public class MovesController implements MovesFinished
         String[] tokens = objects.split(" ");
         int length = tokens.length/3;
 
+        android.util.Log.e("D", "restoring moves: "+length);
+
         for(int m=0; m<length; m++)
           {
           String axis  = tokens[3*m  ];
diff --git a/src/main/java/org/distorted/main/MainActivity.java b/src/main/java/org/distorted/main/MainActivity.java
index d25b5097..1b2295fb 100644
--- a/src/main/java/org/distorted/main/MainActivity.java
+++ b/src/main/java/org/distorted/main/MainActivity.java
@@ -406,9 +406,10 @@ public class MainActivity extends AppCompatActivity implements RubikNetwork.Upda
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void switchToPlay(RubikObject object, int scrambles, boolean free)
+    public void switchToPlay(RubikObject object, int scrambles, boolean free, int level)
       {
       Intent intent = new Intent(this, PlayActivity.class);
+      intent.putExtra("level", level);
       intent.putExtra("name", object.getUpperName());
       intent.putExtra("scrambles", scrambles);
       intent.putExtra("local", object.isLocal() );
diff --git a/src/main/java/org/distorted/main/MainObjectPopup.java b/src/main/java/org/distorted/main/MainObjectPopup.java
index b0a34cd0..9bb5b6a4 100644
--- a/src/main/java/org/distorted/main/MainObjectPopup.java
+++ b/src/main/java/org/distorted/main/MainObjectPopup.java
@@ -37,6 +37,7 @@ public class MainObjectPopup
 
   private final PopupWindow mPopup;
   private final int mMenuTextSize;
+  private Button[] mLevel;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -162,43 +163,44 @@ public class MainObjectPopup
     LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(levelWidth,levelHeight);
     params.setMargins(margin,-margin,margin,-margin);
 
-    Button[] level = new Button[LEVELS_SHOWN+1];
+    mLevel = new Button[LEVELS_SHOWN+1];
 
-    level[0] = layout.findViewById(R.id.level0);
-    level[1] = layout.findViewById(R.id.level1);
-    level[2] = layout.findViewById(R.id.level2);
-    level[3] = layout.findViewById(R.id.level3);
-    level[4] = layout.findViewById(R.id.level4);
-    level[5] = layout.findViewById(R.id.level5);
-    level[6] = layout.findViewById(R.id.level6);
-    level[7] = layout.findViewById(R.id.level7);
-    level[8] = layout.findViewById(R.id.levelM);
+    mLevel[0] = layout.findViewById(R.id.level0);
+    mLevel[1] = layout.findViewById(R.id.level1);
+    mLevel[2] = layout.findViewById(R.id.level2);
+    mLevel[3] = layout.findViewById(R.id.level3);
+    mLevel[4] = layout.findViewById(R.id.level4);
+    mLevel[5] = layout.findViewById(R.id.level5);
+    mLevel[6] = layout.findViewById(R.id.level6);
+    mLevel[7] = layout.findViewById(R.id.level7);
+    mLevel[8] = layout.findViewById(R.id.levelM);
 
     int numScramble  = object==null ? 1 : object.getNumScramble();
     int min = Math.min(numScramble,LEVELS_SHOWN);
 
     if( numScramble>=1 && numScramble<=7 )
       {
-      level[numScramble].setText(R.string.levelM);
-      for(int i=numScramble+1; i<=8; i++) level[i].setVisibility(GONE);
+      mLevel[numScramble].setText(R.string.levelM);
+      for(int i=numScramble+1; i<=8; i++) mLevel[i].setVisibility(GONE);
       }
 
     for(int i=0; i<=min; i++)
       {
-      level[i].setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
-      level[i].setLayoutParams(params);
-      level[i].setPadding(0,0,0,0);
+      mLevel[i].setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
+      mLevel[i].setLayoutParams(params);
+      mLevel[i].setPadding(0,0,0,0);
 
+      final int ii=i;
       boolean free = i==0;
       int scrambles = (i>0 && i<min) ? i : numScramble;
 
-      level[i].setOnClickListener( new View.OnClickListener()
+      mLevel[i].setOnClickListener( new View.OnClickListener()
         {
         @Override
         public void onClick(View v)
           {
           mPopup.dismiss();
-          act.switchToPlay(object,scrambles,free);
+          act.switchToPlay(object,scrambles,free,ii);
           }
         });
       }
@@ -206,7 +208,54 @@ public class MainObjectPopup
     int index = (numScramble>=1 && numScramble<=7) ? numScramble : LEVELS_SHOWN;
     LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(levelWidth,levelHeight);
     params2.setMargins(margin,-margin,margin,margin);
-    level[index].setLayoutParams(params2);
+    mLevel[index].setLayoutParams(params2);
+
+    setupLevelButtonVisibilityAndColor(act);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void setupLevelButtonVisibilityAndColor(MainActivity act)
+    {
+    /*
+    int currObject = RubikObjectList.getCurrObject();
+    RubikObject object = RubikObjectList.getObject(currObject);
+    int numScramble = object==null ? 1 : object.getNumScramble();
+    RubikScores scores = RubikScores.getInstance();
+    Resources res = act.getResources();
+    ColorStateList colorG = ColorStateList.valueOf(res.getColor(R.color.green));
+    ColorStateList colorD = ColorStateList.valueOf(res.getColor(R.color.dark_grey));
+
+    for(int level=0; level<=LEVELS_SHOWN; level++)
+      {
+      boolean isSolved = scores.isSolved(currObject,level);
+      mLevel[level].setBackgroundTintList( isSolved ? colorG : colorD);
+      }
+
+    if( numScramble<=LEVELS_SHOWN || mOldNumScramble<=LEVELS_SHOWN )
+      {
+      if( numScramble<mOldNumScramble )
+        {
+        int max = Math.min(LEVELS_SHOWN,mOldNumScramble-1);
+        for(int level=numScramble; level<=max; level++) mLevel[level].setVisibility(View.INVISIBLE);
+        mLevel[numScramble-1].setText(R.string.levelM);
+        }
+      if( numScramble>mOldNumScramble )
+        {
+        int max = Math.min(LEVELS_SHOWN,numScramble-1);
+        mLevel[mOldNumScramble-1].setText( String.valueOf(mOldNumScramble) );
+
+        for(int level=mOldNumScramble; level<=max; level++)
+          {
+          mLevel[level].setVisibility(View.VISIBLE);
+          if( level<max ) mLevel[level].setText( String.valueOf(level+1) );
+          else            mLevel[level].setText( R.string.levelM );
+          }
+        }
+      }
+
+    mOldNumScramble = numScramble;
+    */
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/main_old/RubikActivity.java b/src/main/java/org/distorted/main_old/RubikActivity.java
deleted file mode 100644
index 203e0da0..00000000
--- a/src/main/java/org/distorted/main_old/RubikActivity.java
+++ /dev/null
@@ -1,668 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.main_old;
-
-import java.io.InputStream;
-import java.util.Locale;
-
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Bundle;
-
-import android.util.DisplayMetrics;
-import android.view.DisplayCutout;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.preference.PreferenceManager;
-
-import com.google.firebase.analytics.FirebaseAnalytics;
-import com.google.firebase.inappmessaging.FirebaseInAppMessaging;
-
-import org.distorted.config.ConfigActivity;
-import org.distorted.bandaged.BandagedActivity;
-import org.distorted.dialogs.RubikDialogAbout;
-import org.distorted.library.main.DistortedLibrary;
-
-import org.distorted.library.main.DistortedScreen;
-import org.distorted.main.BuildConfig;
-import org.distorted.main.R;
-import org.distorted.messaging.RubikInAppMessanging;
-import org.distorted.objectlib.helpers.OperatingSystemInterface;
-import org.distorted.objectlib.main.InitAssets;
-import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.main.TwistyObject;
-
-import org.distorted.dialogs.RubikDialogError;
-import org.distorted.external.RubikScores;
-import org.distorted.external.RubikNetwork;
-import org.distorted.objects.RubikObject;
-import org.distorted.objects.RubikObjectList;
-import org.distorted.os.OSInterface;
-import org.distorted.purchase.PurchaseActivity;
-import org.distorted.screens.RubikScreenSolving;
-import org.distorted.screens.ScreenList;
-import org.distorted.screens.RubikScreenPlay;
-import org.distorted.tutorials.TutorialActivity;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikActivity extends AppCompatActivity
-{
-    public static final boolean SHOW_DOWNLOADED_DEBUG = false;
-    public static final boolean SHOW_IAP_DEBUG        = false;
-    public static final boolean USE_IAP               = false;
-
-    public static final float PADDING             = 0.010f;
-    public static final float SMALL_MARGIN        = 0.004f;
-    public static final float BUTTON_TEXT_SIZE    = 0.050f;
-    public static final float TITLE_TEXT_SIZE     = 0.060f;
-    public static final float PATTERN_GROUP_TEXT  = 0.030f;
-    public static final float PATTERN_CHILD_TEXT  = 0.020f;
-    public static final float SCORES_LEVEL_TEXT   = 0.035f;
-    public static final float SCORES_ITEM_TEXT    = 0.025f;
-    public static final float TAB_WIDTH           = 0.066f;
-    public static final float TAB_HEIGHT          = 0.066f;
-    public static final float POPUP_PADDING       = 0.028f;
-    public static final float POPUP_MARGIN        = 0.016f;
-    public static final float POPUP_BOTTOM        = 0.090f;
-    public static final float RATIO_BAR           = 0.100f;
-
-    public static final int FLAGS =  View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
-                                   | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
-                                   | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
-                                   | View.SYSTEM_UI_FLAG_FULLSCREEN
-                                   | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
-
-    private static final int ACTIVITY_NUMBER = 0;
-    private static final float RATIO_INSET= 0.09f;
-
-    private static final String KEY_PLAY = "movesController_play";
-    private static final String KEY_SOLV = "movesController_solv";
-
-    private boolean mJustStarted;
-    private FirebaseAnalytics mFirebaseAnalytics;
-    private static int mScreenWidth, mScreenHeight;
-    private int mCurrentApiVersion;
-    private int mHeightUpperBar;
-    private int mOldVersion1, mOldVersion2, mOldVersion3;
-    private String mOldVersion, mCurrVersion;
-    private int mSolverIndex;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    protected void onCreate(Bundle savedState)
-      {
-      super.onCreate(savedState);
-      DistortedLibrary.onCreate(ACTIVITY_NUMBER);
-      setTheme(R.style.MaterialThemeNoActionBar);
-      setContentView(R.layout.old_main);
-      hideNavigationBar();
-
-      mJustStarted = true;
-      mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
-
-      DisplayMetrics displaymetrics = new DisplayMetrics();
-      getWindowManager().getDefaultDisplay().getRealMetrics(displaymetrics);
-      mScreenWidth =displaymetrics.widthPixels;
-      mScreenHeight=displaymetrics.heightPixels;
-
-      cutoutHack();
-      computeBarHeights();
-
-      mCurrVersion = getAppVers();
-      mSolverIndex = 0;
-
-      Thread thread = new Thread()
-        {
-        public void run()
-          {
-          RubikInAppMessanging listener = new RubikInAppMessanging();
-          FirebaseInAppMessaging.getInstance().addClickListener(listener);
-          }
-        };
-
-      thread.start();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// this does not include possible insets
-
-    private void computeBarHeights()
-      {
-      int barHeight = (int)(mScreenHeight*RATIO_BAR);
-      mHeightUpperBar = barHeight;
-
-      LinearLayout layoutTop = findViewById(R.id.upperBar);
-      LinearLayout layoutBot = findViewById(R.id.lowerBar);
-
-      ViewGroup.LayoutParams paramsTop = layoutTop.getLayoutParams();
-      paramsTop.height = mHeightUpperBar;
-      layoutTop.setLayoutParams(paramsTop);
-      ViewGroup.LayoutParams paramsBot = layoutBot.getLayoutParams();
-      paramsBot.height = barHeight;
-      layoutBot.setLayoutParams(paramsBot);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void hideNavigationBar()
-      {
-      mCurrentApiVersion = Build.VERSION.SDK_INT;
-
-      if(mCurrentApiVersion >= Build.VERSION_CODES.KITKAT)
-        {
-        final View decorView = getWindow().getDecorView();
-
-        decorView.setSystemUiVisibility(FLAGS);
-
-        decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener()
-          {
-          @Override
-          public void onSystemUiVisibilityChange(int visibility)
-            {
-            if((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0)
-              {
-              decorView.setSystemUiVisibility(FLAGS);
-              }
-            }
-          });
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public void onAttachedToWindow()
-      {
-      super.onAttachedToWindow();
-
-      if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.P )
-        {
-        DisplayCutout cutout = getWindow().getDecorView().getRootWindowInsets().getDisplayCutout();
-        int insetHeight = cutout!=null ? cutout.getSafeInsetTop() : 0;
-
-        LinearLayout layoutHid = findViewById(R.id.hiddenBar);
-        ViewGroup.LayoutParams paramsHid = layoutHid.getLayoutParams();
-        paramsHid.height = (int)(insetHeight*RATIO_INSET);
-        layoutHid.setLayoutParams(paramsHid);
-        mHeightUpperBar += paramsHid.height;
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// do not avoid cutouts
-
-    private void cutoutHack()
-      {
-      if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.P )
-        {
-        getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public void onWindowFocusChanged(boolean hasFocus)
-      {
-      super.onWindowFocusChanged(hasFocus);
-
-      if( mCurrentApiVersion >= Build.VERSION_CODES.KITKAT && hasFocus )
-        {
-        getWindow().getDecorView().setSystemUiVisibility(FLAGS);
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    @Override
-    protected void onPause() 
-      {
-      super.onPause();
-      RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
-      view.onPause();
-      DistortedLibrary.onPause(ACTIVITY_NUMBER);
-      RubikNetwork.onPause();
-      savePreferences();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    @Override
-    protected void onResume() 
-      {
-      super.onResume();
-      DistortedLibrary.onResume(ACTIVITY_NUMBER);
-      RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
-      view.onResume();
-
-      SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
-      restorePreferences(preferences,mJustStarted);
-      ScreenList.setScreen(this);
-      restoreMoves(preferences);
-
-      if( mJustStarted )
-        {
-        mJustStarted = false;
-        RubikScores scores = RubikScores.getInstance();
-        scores.incrementNumRuns();
-        scores.setCountry(this);
-        //RubikObjectList.restoreMeshState(preferences);
-        }
-
-      int object = RubikObjectList.getCurrObject();
-      changeIfDifferent(object,view.getObjectControl());
-
-      if( !mOldVersion.equals(mCurrVersion) ) displayNovelties();
-      else if( USE_IAP ) view.setShowStars();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void displayNovelties()
-      {
-      Bundle bundle = new Bundle();
-      bundle.putString("argument",mOldVersion);
-      RubikDialogAbout newDialog = new RubikDialogAbout();
-      newDialog.setArguments(bundle);
-      newDialog.show(getSupportFragmentManager(), RubikDialogAbout.getDialogTag() );
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    @Override
-    protected void onDestroy() 
-      {
-      DistortedLibrary.onDestroy(ACTIVITY_NUMBER);
-      super.onDestroy();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private String getAppVers()
-      {
-      try
-        {
-        PackageInfo pInfo = getPackageManager().getPackageInfo( getPackageName(), 0);
-        return pInfo.versionName;
-        }
-      catch (PackageManager.NameNotFoundException e)
-        {
-        return "unknown";
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void savePreferences()
-      {
-      SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
-      SharedPreferences.Editor editor = preferences.edit();
-
-      editor.putString("appVersion", mCurrVersion );
-      editor.putInt("solverIndex", mSolverIndex );
-
-      for( int i=0; i< ScreenList.LENGTH; i++ )
-        {
-        ScreenList.getScreen(i).getScreenClass().savePreferences(editor);
-        }
-
-      RubikObjectList.savePreferences(editor);
-      //RubikObjectList.saveMeshState(editor);
-      ScreenList.savePreferences(editor);
-      RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
-      OSInterface os = view.getInterface();
-      os.setEditor(editor);
-      view.getObjectControl().savePreferences();
-
-      ScreenList curr = ScreenList.getCurrentScreen();
-
-      if( curr==ScreenList.PLAY )
-        {
-        RubikScreenPlay play = (RubikScreenPlay)ScreenList.PLAY.getScreenClass();
-        play.saveMovePreferences(KEY_PLAY,editor);
-        }
-      if( curr==ScreenList.SOLV )
-        {
-        RubikScreenSolving solv = (RubikScreenSolving)ScreenList.SOLV.getScreenClass();
-        solv.saveMovePreferences(KEY_SOLV,editor);
-        }
-
-      boolean success = editor.commit();
-      if( !success ) android.util.Log.e("D", "Failed to save preferences");
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void restorePreferences(SharedPreferences preferences, boolean justStarted)
-      {
-      mOldVersion = preferences.getString("appVersion","");
-      mSolverIndex = preferences.getInt("solverIndex",0);
-
-      parseOldVersion(mOldVersion);
-
-      RubikObjectList.restorePreferences(this,preferences,justStarted);
-
-      for (int i=0; i<ScreenList.LENGTH; i++)
-        {
-        ScreenList.getScreen(i).getScreenClass().restorePreferences(preferences);
-        }
-
-      RubikScores scores = RubikScores.getInstance();
-
-      if( scores.isVerified() )
-        {
-        FirebaseAnalytics analytics = getAnalytics();
-        analytics.setUserId(scores.getName());
-        }
-
-      // all old users upgrading from version <1.11.4, where there was no concept of 'stars',
-      // get all the stars they have earned
-      int numStars = scores.getNumStars();
-
-      if( justStarted && numStars==0 && oldVersionLessThan(1,11,4) )
-        {
-        scores.correctNumStars();
-        }
-
-      // in 1.11.5 we have introduced IAP. When upgrading from something less than 1.11.5 to
-      // something at least 1.11.5, mark all solved objects as free.
-      // this needs to be after the above ScreenList.getScreen(i).getScreenClass().restorePreferences()
-      // as that restores the Records which we need here
-      // also needs to be after RubikObjectList.restorePreferences()
-      if( USE_IAP && justStarted && oldVersionLessThan(1,11,5) && !mCurrVersion.equals("1.11.4") )
-        {
-        RubikObjectList.firstUpgradeMarkAllSolvedAsFree();
-        }
-
-      ScreenList.restorePreferences(preferences);
-
-      // Versions <= 1.8.6 did not save their 'appVersion' to preferences, therefore in their
-      // case the 'mOldVersion' - version of the app which saved the preferences on the last
-      // go - is empty.
-      // Between versions 1.8.6 and 1.9.0, the order of the cubits in TwistyCube has changed.
-      // If someone has scrambled the cube with v. 1.8.6, then upgraded to 1.9.0 and re-started
-      // the app, because of the different order of the cubits - his cube would be messed up.
-      // So in such case, i.e. on fresh upgrade from version<=1.8.6 to version>=1.9.0, do not
-      // restore the object scrambling.
-
-      if( !mOldVersion.equals("") )
-        {
-        RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
-        OSInterface os = view.getInterface();
-        os.setPreferences(preferences);
-        view.getObjectControl().restorePreferences();
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void parseOldVersion(String version)
-      {
-      if( version==null ) return;
-
-      try
-        {
-        String[] parts = version.split("\\.");
-
-        if( parts.length==3 )
-          {
-          mOldVersion1 = Integer.parseInt(parts[0]);
-          mOldVersion2 = Integer.parseInt(parts[1]);
-          mOldVersion3 = Integer.parseInt(parts[2]);
-          }
-        }
-      catch(Exception ignored)
-        {
-        mOldVersion1 = 0;
-        mOldVersion2 = 0;
-        mOldVersion3 = 0;
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private boolean oldVersionLessThan(int v1, int v2, int v3)
-      {
-      if( mOldVersion1<v1 ) return true;
-      if( mOldVersion1>v1 ) return false;
-      if( mOldVersion2<v2 ) return true;
-      if( mOldVersion2>v2 ) return false;
-      return mOldVersion3<v3;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void restoreMoves(SharedPreferences preferences)
-      {
-      ScreenList curr = ScreenList.getCurrentScreen();
-
-      if( curr==ScreenList.PLAY )
-        {
-        RubikScreenPlay play = (RubikScreenPlay)ScreenList.PLAY.getScreenClass();
-        play.restoreMovePreferences(this,KEY_PLAY,preferences);
-        }
-      if( curr==ScreenList.SOLV )
-        {
-        RubikScreenSolving solv = (RubikScreenSolving)ScreenList.SOLV.getScreenClass();
-        solv.restoreMovePreferences(this,KEY_SOLV,preferences);
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    void OpenGLError()
-      {
-      RubikDialogError errDiag = new RubikDialogError();
-      errDiag.show(getSupportFragmentManager(), null);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public FirebaseAnalytics getAnalytics()
-      {
-      return mFirebaseAnalytics;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public int getHeightUpperBar()
-      {
-      return mHeightUpperBar;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public TwistyObject getObject()
-      {
-      RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
-      return view.getObjectControl().getObject();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public DistortedScreen getScreen()
-      {
-      RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
-      return view.getRenderer().getScreen();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public ObjectControl getControl()
-      {
-      RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
-      return view.getObjectControl();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public int getScreenWidthInPixels()
-      {
-      return mScreenWidth;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public int getScreenHeightInPixels()
-      {
-      return mScreenHeight;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void changeObject(int newObject, boolean reportChange)
-      {
-      RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
-      ObjectControl control = view.getObjectControl();
-      TwistyObject oldObject = control.getObject();
-      changeIfDifferent(newObject,control);
-
-      if( reportChange && oldObject!=null )
-        {
-        RubikObject robject = RubikObjectList.getObject(newObject);
-        String newName = robject==null ? "NULL" : robject.getUpperName();
-        float fps = view.getRenderer().getFPS();
-        fps = (int)(fps+0.5f);
-        StringBuilder name = new StringBuilder();
-        name.append(oldObject.getShortName());
-        name.append(' ');
-        name.append(fps);
-        name.append(" --> ");
-        name.append(newName);
-
-        if( BuildConfig.DEBUG )
-          {
-          android.util.Log.e("rubik", name.toString());
-          }
-        else
-          {
-          FirebaseAnalytics analytics = getAnalytics();
-
-          if( analytics!=null )
-            {
-            Bundle bundle = new Bundle();
-            bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, name.toString());
-            analytics.logEvent(FirebaseAnalytics.Event.SELECT_ITEM, bundle);
-            }
-          }
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void changeIfDifferent(int ordinal, ObjectControl control)
-      {
-      RubikObject object = RubikObjectList.getObject(ordinal);
-      int iconMode  = TwistyObject.MODE_NORM;
-      InputStream jsonStream = object==null ? null : object.getObjectStream(this);
-      InputStream meshStream = object==null ? null : object.getMeshStream(this);
-      String name = object==null ? "NULL" : object.getUpperName();
-      RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
-      OSInterface os = view.getInterface();
-      InitAssets asset = new InitAssets(jsonStream,meshStream,os);
-
-      control.changeIfDifferent(ordinal,name,iconMode,asset);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void switchToTutorial(String url, int objectOrdinal)
-      {
-      Intent intent = new Intent(this, TutorialActivity.class);
-      intent.putExtra("url", url);
-      intent.putExtra("obj", objectOrdinal);
-      startActivity(intent);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void switchToConfig(int objectOrdinal)
-      {
-      Intent intent = new Intent(this, ConfigActivity.class);
-      intent.putExtra("obj", objectOrdinal);
-      startActivity(intent);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void switchToBandagedCreator(int objectOrdinal)
-      {
-      Intent intent = new Intent(this, BandagedActivity.class);
-      intent.putExtra("obj", objectOrdinal);
-      startActivity(intent);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void switchToPurchase(int objectOrdinal)
-      {
-      Intent intent = new Intent(this, PurchaseActivity.class);
-      intent.putExtra("obj", objectOrdinal);
-      startActivity(intent);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void reloadObject(String shortName)
-      {
-      TwistyObject currObject = getObject();
-      String name = currObject==null ? "" : currObject.getShortName();
-
-      if( name.toLowerCase(Locale.ENGLISH).equals(shortName) )
-        {
-        RubikObject object = RubikObjectList.getObject(name);
-
-        if( object!=null )
-          {
-          int iconMode  = TwistyObject.MODE_NORM;
-          InputStream jsonStream = object.getObjectStream(this);
-          InputStream meshStream = object.getMeshStream(this);
-          RubikSurfaceView view  = findViewById(R.id.rubikSurfaceView);
-          OSInterface os         = view.getInterface();
-          InitAssets asset       = new InitAssets(jsonStream,meshStream,os);
-          ObjectControl control  = getControl();
-          control.changeObject(-1,iconMode,asset);
-          }
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void setSolverIndex(int index)
-      {
-      mSolverIndex = index;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public int getSolverIndex()
-      {
-      return mSolverIndex;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   public OperatingSystemInterface getInterface()
-     {
-     RubikSurfaceView view  = findViewById(R.id.rubikSurfaceView);
-     return view.getInterface();
-     }
-}
diff --git a/src/main/java/org/distorted/main_old/RubikObjectLibInterface.java b/src/main/java/org/distorted/main_old/RubikObjectLibInterface.java
deleted file mode 100644
index 0a9c28f6..00000000
--- a/src/main/java/org/distorted/main_old/RubikObjectLibInterface.java
+++ /dev/null
@@ -1,539 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.main_old;
-
-import android.os.Bundle;
-
-import androidx.annotation.NonNull;
-
-import com.google.android.play.core.review.ReviewInfo;
-import com.google.android.play.core.review.ReviewManager;
-import com.google.android.play.core.review.ReviewManagerFactory;
-import com.google.android.play.core.tasks.OnCompleteListener;
-import com.google.android.play.core.tasks.OnFailureListener;
-import com.google.android.play.core.tasks.Task;
-import com.google.firebase.analytics.FirebaseAnalytics;
-import com.google.firebase.crashlytics.FirebaseCrashlytics;
-
-import org.distorted.dialogs.RubikDialogScoresView;
-import org.distorted.library.main.DistortedScreen;
-import org.distorted.library.message.EffectMessageSender;
-
-import org.distorted.external.RubikNetwork;
-import org.distorted.main.BuildConfig;
-import org.distorted.objectlib.helpers.BlockController;
-import org.distorted.objectlib.helpers.ObjectLibInterface;
-import org.distorted.objectlib.main.ObjectControl;
-
-import org.distorted.dialogs.RubikDialogNewRecord;
-import org.distorted.dialogs.RubikDialogSolved;
-import org.distorted.external.RubikScores;
-import org.distorted.objects.RubikObject;
-import org.distorted.objects.RubikObjectList;
-import org.distorted.overlays.DataStars;
-import org.distorted.overlays.ListenerOverlay;
-import org.distorted.overlays.OverlayStars;
-import org.distorted.screens.RubikScreenPlay;
-import org.distorted.screens.RubikScreenReady;
-import org.distorted.screens.RubikScreenSolver;
-import org.distorted.screens.RubikScreenSolving;
-import org.distorted.screens.ScreenList;
-import org.distorted.solvers.SolverMain;
-
-import java.lang.ref.WeakReference;
-
-import static org.distorted.external.RubikScores.RECORD_FIRST;
-import static org.distorted.external.RubikScores.RECORD_NEW;
-import static org.distorted.external.RubikScores.RECORD_NOT_NEW;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikObjectLibInterface implements ObjectLibInterface, ListenerOverlay
-{
-  private final WeakReference<RubikActivity> mAct;
-  private int mIsNewRecord;
-  private int mNewRecord;
-  private int mLastCubitColor, mLastCubit, mLastCubitFace;
-  private boolean mReviewAsked;
-  private int mNumRotations, mNumScrambles;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  RubikObjectLibInterface(RubikActivity act)
-    {
-    mAct = new WeakReference<>(act);
-    mLastCubitColor = -1;
-    mReviewAsked = false;
-    mNumRotations = 0;
-    mNumScrambles = 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void analyticsReport(RubikActivity act, String message, String name, long timeBegin)
-    {
-    long elapsed = System.currentTimeMillis() - timeBegin;
-    String msg = message+" startTime: "+timeBegin+" elapsed: "+elapsed+" name: "+name;
-
-    if( BuildConfig.DEBUG )
-       {
-       android.util.Log.d("libInterface", msg);
-       }
-    else
-      {
-      FirebaseAnalytics analytics = act.getAnalytics();
-
-      if( analytics!=null )
-        {
-        Bundle bundle = new Bundle();
-        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, msg);
-        analytics.logEvent(FirebaseAnalytics.Event.SHARE, bundle);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void reportRecord(RubikActivity act, long startTime, long endTime, String debug, int scrambleNum)
-    {
-    RubikScreenPlay play= (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-    RubikScores scores  = RubikScores.getInstance();
-    int object  = RubikObjectList.getCurrObject();
-    int level   = play.getLevel();
-    String name = scores.getName();
-    RubikObject obj = RubikObjectList.getObject(object);
-    String objName = obj==null ? "NULL" : obj.getUpperName();
-
-    String record = objName+" level "+level+" time "+mNewRecord+" isNew: "+mIsNewRecord+" scrambleNum: "+scrambleNum;
-
-    if( BuildConfig.DEBUG )
-       {
-       android.util.Log.e("libInterface", debug);
-       android.util.Log.e("libInterface", name);
-       android.util.Log.e("libInterface", record);
-       }
-    else
-      {
-      if( level>=9 && mNewRecord<300*level )
-        {
-        long timeNow = System.currentTimeMillis();
-        long elapsed = timeNow - startTime;
-        String suspicious ="start"+startTime+"end"+endTime+"elapsed"+elapsed+"obj"+objName+"level"+level+"record"+mNewRecord+"scrambles"+scrambleNum+debug;
-        RubikNetwork network = RubikNetwork.getInstance();
-        network.suspicious(suspicious,act);
-        }
-
-      FirebaseAnalytics analytics = act.getAnalytics();
-
-      if( analytics!=null )
-        {
-        Bundle bundle = new Bundle();
-        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, debug);
-        bundle.putString(FirebaseAnalytics.Param.CHARACTER, name);
-        bundle.putString(FirebaseAnalytics.Param.LEVEL, record);
-        analytics.logEvent(FirebaseAnalytics.Event.LEVEL_UP, bundle);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private Bundle createDialogBundle()
-    {
-    Bundle bundle = new Bundle();
-    String arg = RubikDialogScoresView.formatRecord(mNewRecord);
-    bundle.putString("argument", arg );
-    return bundle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void requestReview(RubikActivity act)
-    {
-    android.util.Log.e("D", "ASKING FOR REVIEW");
-
-    mReviewAsked = true;
-    final String name = RubikScores.getInstance().getName();
-    final long timeBegin = System.currentTimeMillis();
-    final ReviewManager manager = ReviewManagerFactory.create(act);
-    Task<ReviewInfo> request = manager.requestReviewFlow();
-
-    request.addOnCompleteListener(new OnCompleteListener<ReviewInfo>()
-      {
-      @Override
-      public void onComplete (@NonNull Task<ReviewInfo> task)
-        {
-        if (task.isSuccessful())
-          {
-          ReviewInfo reviewInfo = task.getResult();
-          Task<Void> flow = manager.launchReviewFlow(act, reviewInfo);
-
-          flow.addOnFailureListener(new OnFailureListener()
-            {
-            @Override
-            public void onFailure(Exception e)
-              {
-              analyticsReport(act,"Failed", name, timeBegin);
-              }
-            });
-
-          flow.addOnCompleteListener(new OnCompleteListener<Void>()
-            {
-            @Override
-            public void onComplete(@NonNull Task<Void> task)
-              {
-              analyticsReport(act,"Complete", name, timeBegin);
-              }
-            });
-          }
-        else analyticsReport(act,"Not Successful", name, timeBegin);
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void onScrambleEffectFinished()
-    {
-    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-
-    if( play.shouldReactToEndOfScrambling() )
-      {
-      RubikActivity act = mAct.get();
-      RubikScores.getInstance().incrementNumPlays();
-
-      act.runOnUiThread(new Runnable()
-        {
-        @Override
-        public void run()
-          {
-          ScreenList.switchScreen( act, ScreenList.READ);
-          ObjectControl control = act.getControl();
-          control.unblockEverything();
-          }
-        });
-      }
-    else
-      {
-      mNumScrambles++;
-
-      if( mNumScrambles==10 && !mReviewAsked )
-        {
-        RubikActivity act = mAct.get();
-        requestReview(act);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void onFinishRotation(int axis, int row, int angle)
-    {
-    mNumRotations++;
-
-    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
-      {
-      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
-      solv.addMove(mAct.get(), axis, row, angle);
-      }
-    if( ScreenList.getCurrentScreen()== ScreenList.PLAY )
-      {
-      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-      play.addMove(mAct.get(), axis, row, angle);
-      }
-
-    if( mNumRotations==40 && !mReviewAsked )
-      {
-      RubikActivity act = mAct.get();
-      requestReview(act);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void onBeginRotation()
-    {
-    if( ScreenList.getCurrentScreen()== ScreenList.READ )
-      {
-      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
-      solving.resetElapsed();
-      RubikActivity act = mAct.get();
-
-      act.runOnUiThread(new Runnable()
-        {
-        @Override
-        public void run()
-          {
-          ScreenList.switchScreen( act, ScreenList.SOLV);
-          }
-        });
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void failedToDrag()
-    {
-    ScreenList curr = ScreenList.getCurrentScreen();
-
-    if( curr==ScreenList.PLAY )
-      {
-      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-      play.reddenLock(mAct.get());
-      }
-    else if( curr==ScreenList.READ )
-      {
-      RubikScreenReady read = (RubikScreenReady) ScreenList.READ.getScreenClass();
-      read.reddenLock(mAct.get());
-      }
-    else if( curr==ScreenList.SOLV )
-      {
-      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
-      solv.reddenLock(mAct.get());
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void onSolved()
-    {
-    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
-      {
-      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
-      mNewRecord = solving.stopTimerAndGetRecord();
-      mIsNewRecord = solving.setRecord();
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void onObjectCreated(long time)
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void reportProblem(String problem, boolean recordException)
-    {
-    if( BuildConfig.DEBUG )
-      {
-      android.util.Log.e("libInterface", problem);
-      }
-    else
-      {
-      if( recordException )
-        {
-        Exception ex = new Exception(problem);
-        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
-        crashlytics.setCustomKey("problem" , problem);
-        crashlytics.recordException(ex);
-        }
-      else
-        {
-        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
-        crashlytics.log(problem);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void reportScramblingProblem(int place, long pause, long resume, long time)
-    {
-    String error = "SCRAMBLING BLOCK "+place+" blocked for "+time;
-
-    if( BuildConfig.DEBUG )
-       {
-       android.util.Log.e("libInterface", error);
-       }
-    else
-      {
-      Exception ex = new Exception(error);
-      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
-      crashlytics.setCustomKey("pause" , pause );
-      crashlytics.setCustomKey("resume", resume );
-      crashlytics.recordException(ex);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void reportRotationProblem(int place, long pause, long resume, long time)
-    {
-    String error = "ROTATION BLOCK "+place+" blocked for "+time;
-
-    if( BuildConfig.DEBUG )
-       {
-       android.util.Log.e("libInterface", error);
-       }
-    else
-      {
-      Exception ex = new Exception(error);
-      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
-      crashlytics.setCustomKey("pause" , pause );
-      crashlytics.setCustomKey("resume", resume);
-      crashlytics.recordException(ex);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void reportThreadProblem(int place, long pause, long resume, long time)
-    {
-    String error = EffectMessageSender.reportState();
-
-    if( BuildConfig.DEBUG )
-       {
-       android.util.Log.e("libInterface", error);
-       }
-    else
-      {
-      Exception ex = new Exception(error);
-      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
-      crashlytics.setCustomKey("pause" , pause  );
-      crashlytics.setCustomKey("resume", resume );
-      crashlytics.recordException(ex);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void reportBlockProblem(int type, int place, long pause, long resume, long time)
-    {
-    switch(type)
-      {
-      case BlockController.TYPE_SCRAMBLING: reportScramblingProblem(place,pause,resume,time); break;
-      case BlockController.TYPE_ROTATION  : reportRotationProblem(place,pause,resume,time); break;
-      case BlockController.TYPE_THREAD    : reportThreadProblem(place,pause,resume,time); break;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void reportJSONError(String error, int ordinal)
-    {
-    RubikObject object = RubikObjectList.getObject(ordinal);
-    String name = object==null ? "NULL" : object.getUpperName();
-
-    if( BuildConfig.DEBUG )
-       {
-       android.util.Log.e("libInterface", "name="+name+" JSON error: "+error);
-       }
-    else
-      {
-      Exception ex = new Exception(error);
-      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
-      crashlytics.setCustomKey("name" , name );
-      crashlytics.setCustomKey("JSONerror", error );
-      crashlytics.recordException(ex);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void onReplaceModeDown(int cubit, int face)
-    {
-    RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
-    int color = solver.getCurrentColor();
-    int currObject = RubikObjectList.getCurrObject();
-    mLastCubitColor = SolverMain.cubitIsLocked(currObject,cubit);
-    mLastCubit = cubit;
-    mLastCubitFace = face;
-    ObjectControl control = mAct.get().getControl();
-    control.setTextureMap( cubit, face, color );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void onReplaceModeUp()
-    {
-    if( mLastCubitColor>=0 )
-      {
-      ObjectControl control = mAct.get().getControl();
-      control.setTextureMap( mLastCubit, mLastCubitFace, mLastCubitColor );
-      mLastCubitColor = -1;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void onWinEffectFinished(long startTime, long endTime, String debug, int scrambleNum)
-    {
-    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
-      {
-      RubikActivity act = mAct.get();
-      reportRecord(act,startTime,endTime,debug,scrambleNum);
-
-      RubikScores scores = RubikScores.getInstance();
-      int numWins = scores.incrementNumWins();
-      int numRuns = scores.getNumRuns();
-
-      if( numRuns==3 || numRuns==6 || numWins==4 || numWins==20 || numWins==50 || numWins==80 || numWins==100)
-        {
-        requestReview(act);
-        }
-
-      switch(mIsNewRecord)
-        {
-        case RECORD_FIRST  : if( RubikActivity.USE_IAP )
-                                {
-                                RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-                                int level = play.getLevel();
-                                int newStars = scores.computeNumStars(level);
-                                int totStars = scores.getNumStars();
-                                scores.changeNumStars(newStars);
-                                DistortedScreen screen = act.getScreen();
-                                OverlayStars stars = new OverlayStars();
-                                DataStars data  = new DataStars(totStars,newStars,act.getResources());
-                                stars.startOverlay(screen,this,data);
-                                }
-                             else
-                                {
-                                Bundle bundle = createDialogBundle();
-                                RubikDialogNewRecord d2 = new RubikDialogNewRecord();
-                                d2.setArguments(bundle);
-                                d2.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
-                                }
-                             break;
-        case RECORD_NEW    : Bundle byes = createDialogBundle();
-                             RubikDialogNewRecord dyes = new RubikDialogNewRecord();
-                             dyes.setArguments(byes);
-                             dyes.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
-                             break;
-        case RECORD_NOT_NEW: Bundle bno = createDialogBundle();
-                             RubikDialogSolved dno = new RubikDialogSolved();
-                             dno.setArguments(bno);
-                             dno.show( act.getSupportFragmentManager(), RubikDialogSolved.getDialogTag() );
-                             break;
-        }
-
-      act.runOnUiThread(new Runnable()
-        {
-        @Override
-        public void run()
-          {
-          ScreenList.switchScreen( act, ScreenList.DONE);
-          }
-        });
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void overlayFinished(long id)
-    {
-    RubikActivity act = mAct.get();
-    Bundle bundle = createDialogBundle();
-    RubikDialogNewRecord d = new RubikDialogNewRecord();
-    d.setArguments(bundle);
-    d.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
-    }
-}
diff --git a/src/main/java/org/distorted/main_old/RubikRenderer.java b/src/main/java/org/distorted/main_old/RubikRenderer.java
deleted file mode 100644
index 2578c776..00000000
--- a/src/main/java/org/distorted/main_old/RubikRenderer.java
+++ /dev/null
@@ -1,218 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.main_old;
-
-import android.app.Activity;
-import android.content.res.Resources;
-import android.opengl.GLES30;
-import android.opengl.GLSurfaceView;
-
-import org.distorted.library.main.InternalOutputSurface;
-import org.distorted.main.BuildConfig;
-import org.distorted.objectlib.effects.BaseEffect;
-import org.distorted.library.effect.EffectType;
-import org.distorted.library.effect.VertexEffectQuaternion;
-import org.distorted.library.effect.VertexEffectRotate;
-import org.distorted.library.main.DistortedLibrary;
-import org.distorted.library.main.DistortedScreen;
-import org.distorted.library.mesh.MeshBase;
-import org.distorted.external.RubikNetwork;
-import org.distorted.objectlib.main.ObjectControl;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
-import com.google.firebase.crashlytics.FirebaseCrashlytics;
-
-import java.io.InputStream;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.LibraryUser
-{
-   public static final float BRIGHTNESS = 0.30f;
-
-   private final RubikSurfaceView mView;
-   private final Resources mResources;
-   private final DistortedScreen mScreen;
-   private final ObjectControl mControl;
-   private final Fps mFPS;
-   private boolean mErrorShown;
-   private boolean mDebugSent;
-
-   private static class Fps
-     {
-     private static final int NUM_FRAMES  = 100;
-
-     private long lastTime=0;
-     private final long[] durations;
-     private int currDuration;
-     private float currFPS;
-
-     Fps()
-       {
-       durations = new long[NUM_FRAMES+1];
-       currDuration = 0;
-
-       for (int i=0; i<NUM_FRAMES+1; i++) durations[i] = 16;
-       durations[NUM_FRAMES] = NUM_FRAMES * 16;
-       }
-
-     void onRender(long time)
-       {
-       if( lastTime==0 ) lastTime = time;
-
-       currDuration++;
-       if (currDuration >= NUM_FRAMES) currDuration = 0;
-       durations[NUM_FRAMES] += ((time - lastTime) - durations[currDuration]);
-       durations[currDuration] = time - lastTime;
-
-       currFPS = ((int)(10000.0f*NUM_FRAMES/durations[NUM_FRAMES]))/10.0f;
-
-       lastTime = time;
-       }
-
-     float getFPS()
-       {
-       return currFPS;
-       }
-     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   RubikRenderer(RubikSurfaceView v)
-     {
-     mView = v;
-     mResources = v.getResources();
-
-     mErrorShown = false;
-     mControl = v.getObjectControl();
-     mFPS = new Fps();
-     mScreen = new DistortedScreen();
-     mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
-     mScreen.enableDepthStencil(InternalOutputSurface.DEPTH_NO_STENCIL);
-     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   float getFPS()
-     {
-     return mFPS.getFPS();
-     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   DistortedScreen getScreen()
-     {
-     return mScreen;
-     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// various things are done here delayed, 'after the next render' as not to be done mid-render and
-// cause artifacts.
-
-   @Override
-   public void onDrawFrame(GL10 glUnused)
-     {
-     long time = System.currentTimeMillis();
-     mFPS.onRender(time);
-     mControl.preRender();
-     mScreen.render(time);
-     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   @Override
-   public void onSurfaceChanged(GL10 glUnused, int width, int height)
-      {
-      mScreen.resize(width,height);
-      mView.setScreenSize(width,height);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   @Override
-   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
-      {
-      DistortedLibrary.setMax(EffectType.VERTEX,ObjectControl.MAX_QUATS+1);
-      MeshBase.setMaxEffComponents(ObjectControl.MAX_MOVING_PARTS);
-
-      VertexEffectRotate.enable();
-      VertexEffectQuaternion.enable();
-      BaseEffect.Type.enableEffects();
-      //OverlayGeneric.enableEffects();
-
-      DistortedLibrary.onSurfaceCreated(this,1);
-      DistortedLibrary.setCull(true);
-
-      if( !mDebugSent )
-        {
-        mDebugSent= true;
-        Activity act = (Activity)mView.getContext();
-        RubikNetwork network = RubikNetwork.getInstance();
-        network.downloadUpdates(act);
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   public void distortedException(Exception ex)
-     {
-     String message = ex.getMessage();
-     String shading = GLES30.glGetString(GLES30.GL_SHADING_LANGUAGE_VERSION);
-     String version = GLES30.glGetString(GLES30.GL_VERSION);
-     String vendor  = GLES30.glGetString(GLES30.GL_VENDOR);
-     String renderer= GLES30.glGetString(GLES30.GL_RENDERER);
-
-     if( message==null ) message = "exception NULL";
-
-     if( BuildConfig.DEBUG )
-       {
-       android.util.Log.e("DISTORTED", message );
-       android.util.Log.e("DISTORTED", "GLSL Version "+shading);
-       android.util.Log.e("DISTORTED", "GL Version "  +version);
-       android.util.Log.e("DISTORTED", "GL Vendor "   +vendor);
-       android.util.Log.e("DISTORTED", "GL Renderer " +renderer);
-       }
-     else
-       {
-       FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
-       crashlytics.setCustomKey("DistortedError", message );
-       crashlytics.setCustomKey("GLSL Version"  , shading );
-       crashlytics.setCustomKey("GLversion"     , version );
-       crashlytics.setCustomKey("GL Vendor "    , vendor  );
-       crashlytics.setCustomKey("GLSLrenderer"  , renderer);
-       crashlytics.recordException(ex);
-       }
-
-     int glsl = DistortedLibrary.getGLSL();
-
-     if( glsl< 300 && !mErrorShown )
-       {
-       mErrorShown = true;
-       RubikActivity act = (RubikActivity)mView.getContext();
-       act.OpenGLError();
-       }
-     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   public InputStream localFile(int fileID)
-     {
-     return mResources.openRawResource(fileID);
-     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   public void logMessage(String message)
-     {
-     android.util.Log.e("Rubik", message );
-     }
-}
diff --git a/src/main/java/org/distorted/main_old/RubikSurfaceView.java b/src/main/java/org/distorted/main_old/RubikSurfaceView.java
deleted file mode 100644
index 1696d870..00000000
--- a/src/main/java/org/distorted/main_old/RubikSurfaceView.java
+++ /dev/null
@@ -1,174 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.main_old;
-
-import android.annotation.SuppressLint;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.ConfigurationInfo;
-import android.opengl.GLES30;
-import android.opengl.GLSurfaceView;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-
-import com.google.firebase.crashlytics.FirebaseCrashlytics;
-
-import org.distorted.external.RubikScores;
-import org.distorted.library.main.DistortedScreen;
-import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.main.TwistyObjectNode;
-import org.distorted.os.OSInterface;
-import org.distorted.overlays.DataStars;
-import org.distorted.overlays.OverlayStars;
-import org.distorted.screens.ScreenList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikSurfaceView extends GLSurfaceView
-{
-    private ObjectControl mObjectController;
-    private OSInterface mInterface;
-    private RubikRenderer mRenderer;
-    private boolean mCreated;
-    private boolean mShowStars;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    void setScreenSize(int width, int height)
-      {
-      mObjectController.setScreenSizeAndScaling(width,height, Math.min(width, (int)(0.75f*height)));
-
-      if( !mCreated )
-        {
-        mCreated = true;
-        mObjectController.createNode(width,height);
-        TwistyObjectNode objectNode = mObjectController.getNode();
-        objectNode.glDepthMask(false);
-        objectNode.glStencilMask(0);
-        mRenderer.getScreen().attach(objectNode);
-
-        if( mShowStars )
-          {
-          mShowStars = false;
-          RubikScores scores = RubikScores.getInstance();
-          int totStars = scores.getNumStars();
-          DistortedScreen screen = mRenderer.getScreen();
-          OverlayStars stars = new OverlayStars();
-          DataStars data = new DataStars(totStars,0,getResources());
-          stars.startOverlay(screen,null,data);
-          }
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    void setShowStars()
-      {
-      mShowStars = true;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    RubikRenderer getRenderer()
-      {
-      return mRenderer;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    OSInterface getInterface()
-      {
-      return mInterface;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    ObjectControl getObjectControl()
-      {
-      return mObjectController;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public RubikSurfaceView(Context context, AttributeSet attrs)
-      {
-      super(context,attrs);
-
-      mCreated = false;
-      mShowStars = false;
-
-      if(!isInEditMode())
-        {
-        RubikActivity act = (RubikActivity)context;
-        RubikObjectLibInterface ref = new RubikObjectLibInterface(act);
-        mInterface = new OSInterface(act,ref);
-        mObjectController = new ObjectControl(mInterface);
-        mRenderer = new RubikRenderer(this);
-
-        final ActivityManager activityManager= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-
-        try
-          {
-          final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
-          int esVersion = configurationInfo.reqGlEsVersion>>16;
-          setEGLContextClientVersion(esVersion);
-          setRenderer(mRenderer);
-          }
-        catch(Exception ex)
-          {
-          act.OpenGLError();
-
-          String shading = GLES30.glGetString(GLES30.GL_SHADING_LANGUAGE_VERSION);
-          String version = GLES30.glGetString(GLES30.GL_VERSION);
-          String vendor  = GLES30.glGetString(GLES30.GL_VENDOR);
-          String renderer= GLES30.glGetString(GLES30.GL_RENDERER);
-
-          FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
-          crashlytics.setCustomKey("GLSL Version"  , shading );
-          crashlytics.setCustomKey("GL version"    , version );
-          crashlytics.setCustomKey("GL Vendor "    , vendor  );
-          crashlytics.setCustomKey("GLSL renderer" , renderer);
-          crashlytics.recordException(ex);
-          }
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public void onPause()
-      {
-      super.onPause();
-      mObjectController.onPause();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public void onResume()
-      {
-      super.onResume();
-      mObjectController.onResume();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    @SuppressLint("ClickableViewAccessibility")
-    @Override
-    public boolean onTouchEvent(MotionEvent event)
-      {
-      mInterface.setMotionEvent(event);
-      int mode = ScreenList.getMode();
-      return mObjectController.onTouchEvent(mode);
-      }
-}
-
diff --git a/src/main/java/org/distorted/objects/RubikObject.java b/src/main/java/org/distorted/objects/RubikObject.java
index 5aef3f6c..46cbf561 100644
--- a/src/main/java/org/distorted/objects/RubikObject.java
+++ b/src/main/java/org/distorted/objects/RubikObject.java
@@ -26,13 +26,10 @@ import org.distorted.dmesh.ObjectMesh;
 import org.distorted.external.RubikFiles;
 import org.distorted.jsons.ObjectJson;
 import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.patterns.RubikPatternList;
 import org.distorted.solvers.ImplementedSolversList;
 
-import static org.distorted.main_old.RubikActivity.SHOW_DOWNLOADED_DEBUG;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class RubikObject
@@ -84,7 +81,7 @@ public class RubikObject
 
   RubikObject(RubikObjectList.DownloadedObject object)
     {
-    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "new downloaded RubikObject "+object.shortName+" added");
+    if( RubikObjectList.SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "new downloaded RubikObject "+object.shortName+" added");
 
     mLowerName     = object.shortName;
     mUpperName     = object.shortName.toUpperCase(Locale.ENGLISH);
@@ -114,7 +111,7 @@ public class RubikObject
 
     if( object.objectVersion>mObjectVersion )
       {
-      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Updating RubikObject's "+object.shortName+" main JSON");
+      if( RubikObjectList.SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Updating RubikObject's "+object.shortName+" main JSON");
 
       mObjectVersion= object.objectVersion;
       mNumScramble  = object.numScrambles;
@@ -125,7 +122,7 @@ public class RubikObject
 
     if( object.extrasVersion>mExtrasVersion )
       {
-      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Updating RubikObject's "+object.shortName+" extras JSON");
+      if( RubikObjectList.SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Updating RubikObject's "+object.shortName+" extras JSON");
 
       mExtrasVersion = object.extrasVersion;
       mExtrasID = -1;
@@ -199,7 +196,7 @@ public class RubikObject
 
   public boolean isFree()
     {
-    return (!RubikActivity.USE_IAP || mIsFree);
+    return (!RubikObjectList.USE_IAP || mIsFree);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/RubikObjectList.java b/src/main/java/org/distorted/objects/RubikObjectList.java
index 04d0e34d..07e2262b 100644
--- a/src/main/java/org/distorted/objects/RubikObjectList.java
+++ b/src/main/java/org/distorted/objects/RubikObjectList.java
@@ -20,16 +20,16 @@ import org.distorted.external.RubikScores;
 import org.distorted.objectlib.signature.ObjectConstants;
 import org.distorted.objectlib.main.ObjectType;
 
-import static org.distorted.main_old.RubikActivity.SHOW_IAP_DEBUG;
-import static org.distorted.main_old.RubikActivity.USE_IAP;
 import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS;
-import static org.distorted.main_old.RubikActivity.SHOW_DOWNLOADED_DEBUG;
-import static org.distorted.screens.RubikScreenPlay.LEVELS_SHOWN;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class RubikObjectList
 {
+  public static final boolean SHOW_DOWNLOADED_DEBUG = false;
+  public static final boolean SHOW_IAP_DEBUG        = false;
+  public static final boolean USE_IAP               = false;
+
   public static final int DEF_OBJECT= ObjectConstants.CUBE_3;
   private static RubikObjectList mThis;
   private static int mNumObjects;
@@ -432,7 +432,7 @@ public class RubikObjectList
       {
       RubikObject object = getObject(obj);
 
-      if( object!=null && !object.isFree() && scores.isSolved(obj,LEVELS_SHOWN) )
+      if( object!=null && !object.isFree() && scores.isSolved(obj,RubikScores.LEVELS_SHOWN) )
         {
         markAsFree(object,scores);
         ret++;
diff --git a/src/main/java/org/distorted/playui/PlayActivity.java b/src/main/java/org/distorted/playui/PlayActivity.java
index 0262b576..d8e84a26 100644
--- a/src/main/java/org/distorted/playui/PlayActivity.java
+++ b/src/main/java/org/distorted/playui/PlayActivity.java
@@ -58,6 +58,7 @@ public class PlayActivity extends AppCompatActivity
     private int mHeightUpperBar;
     private boolean mObjectLocal;
     private int mObjectOrdinal;
+    private int mLevel;
     private boolean mModeFree;
     private boolean mJustStarted;
     private FirebaseAnalytics mFirebaseAnalytics;
@@ -79,6 +80,7 @@ public class PlayActivity extends AppCompatActivity
 
       if( b!=null )
         {
+        mLevel         = b.getInt("level");
         mObjectName    = b.getString("name");
         mNumScrambles  = b.getInt("scrambles");
         mObjectLocal   = b.getBoolean("local");
@@ -87,6 +89,7 @@ public class PlayActivity extends AppCompatActivity
         }
       else
         {
+        mLevel = 0;
         mObjectName = "";
         mNumScrambles = 0;
         mObjectLocal = true;
@@ -216,11 +219,16 @@ public class PlayActivity extends AppCompatActivity
       ObjectControl control = view.getObjectControl();
       view.onResume();
 
-      ScreenList.switchScreen(this, mModeFree ? ScreenList.FREE : ScreenList.SCRA );
       SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
       restorePreferences(preferences);
       restoreMoves(preferences);
 
+      ScreenList sl =  mJustStarted ?
+                      (mModeFree ? ScreenList.FREE : ScreenList.SCRA) :
+                      ScreenList.getCurrentScreen();
+
+      ScreenList.switchScreen(this,sl);
+
       mJustStarted = false;
 
       if( mObjectName.length()>0 )
@@ -367,6 +375,13 @@ public class PlayActivity extends AppCompatActivity
       return mNumScrambles;
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public int getLevel()
+      {
+      return mLevel;
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     public ObjectControl getControl()
diff --git a/src/main/java/org/distorted/playui/ScreenList.java b/src/main/java/org/distorted/playui/ScreenList.java
index 7679b019..fe55eb34 100644
--- a/src/main/java/org/distorted/playui/ScreenList.java
+++ b/src/main/java/org/distorted/playui/ScreenList.java
@@ -81,6 +81,8 @@ public enum ScreenList
 
   public static void savePreferences(SharedPreferences.Editor editor)
     {
+    android.util.Log.e("D", "saving current state: "+mCurrScreen.name() );
+
     editor.putString("curr_state_name", mCurrScreen.name() );
     }
 
@@ -90,6 +92,8 @@ public enum ScreenList
     {
     String currScreenName = preferences.getString("curr_state_name", ScreenList.SCRA.name() );
     mCurrScreen = getScreenFromName(currScreenName);
+
+    android.util.Log.e("D", "restoring current state: "+currScreenName );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/playui/ScreenSolving.java b/src/main/java/org/distorted/playui/ScreenSolving.java
index 27596bcd..1132e01d 100644
--- a/src/main/java/org/distorted/playui/ScreenSolving.java
+++ b/src/main/java/org/distorted/playui/ScreenSolving.java
@@ -37,6 +37,7 @@ public class ScreenSolving extends ScreenBase
   private boolean mRunning;
   private final RubikScores mScores;
   private long mElapsed;
+  private int mLevel;
   private TransparentImageButton mBackButton;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -57,6 +58,7 @@ public class ScreenSolving extends ScreenBase
 
   void enterScreen(final PlayActivity act)
     {
+    mLevel = act.getLevel();
     float width = act.getScreenWidthInPixels();
     float titleSize  = width*PlayActivity.TITLE_TEXT_SIZE;
 
@@ -181,16 +183,8 @@ public class ScreenSolving extends ScreenBase
 
   public int setRecord()
     {
-    /*
-    ScreenPlay play = (ScreenPlay) ScreenList.PLAY.getScreenClass();
-    int level = play.getLevel()-1;
-    */
-
-    int level = 0;
-    android.util.Log.e("D", "TODO: implement level!!");
-
     int object = RubikObjectList.getCurrObject();
-    return mScores.setRecord(object, level, (int)mElapsed);
+    return mScores.setRecord(object, mLevel, (int)mElapsed);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/purchase/PurchaseActivity.java b/src/main/java/org/distorted/purchase/PurchaseActivity.java
index 87fea205..08d88c2c 100644
--- a/src/main/java/org/distorted/purchase/PurchaseActivity.java
+++ b/src/main/java/org/distorted/purchase/PurchaseActivity.java
@@ -23,8 +23,8 @@ import androidx.preference.PreferenceManager;
 import org.distorted.dialogs.RubikDialogError;
 import org.distorted.external.RubikScores;
 import org.distorted.library.main.DistortedLibrary;
+import org.distorted.main.MainActivity;
 import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
 import org.distorted.objectlib.main.InitAssets;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.TwistyObject;
@@ -41,7 +41,7 @@ public class PurchaseActivity extends AppCompatActivity
     private static final float RATIO_UBAR = 0.14f;
     private static final float RATIO_LBAR = 0.10f;
     private static final float RATIO_VIEW = 0.50f;
-    public static final int FLAGS = RubikActivity.FLAGS;
+    public static final int FLAGS = MainActivity.FLAGS;
 
     private static int mScreenWidth, mScreenHeight;
     private int mCurrentApiVersion;
diff --git a/src/main/java/org/distorted/screens/RubikScreenAbstract.java b/src/main/java/org/distorted/screens/RubikScreenAbstract.java
deleted file mode 100644
index 9c35b6f5..00000000
--- a/src/main/java/org/distorted/screens/RubikScreenAbstract.java
+++ /dev/null
@@ -1,24 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.screens;
-
-import android.content.SharedPreferences;
-
-import org.distorted.main_old.RubikActivity;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class RubikScreenAbstract
-  {
-  abstract void enterScreen(RubikActivity act);
-  abstract void leaveScreen(RubikActivity act);
-  public abstract void savePreferences(SharedPreferences.Editor editor);
-  public abstract void restorePreferences(SharedPreferences preferences);
-  }
diff --git a/src/main/java/org/distorted/screens/RubikScreenBase.java b/src/main/java/org/distorted/screens/RubikScreenBase.java
deleted file mode 100644
index 8508082e..00000000
--- a/src/main/java/org/distorted/screens/RubikScreenBase.java
+++ /dev/null
@@ -1,107 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.screens;
-
-import android.app.Activity;
-import android.content.SharedPreferences;
-import android.widget.LinearLayout;
-
-import org.distorted.helpers.TransparentImageButton;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.objectlib.main.ObjectControl;
-
-import org.distorted.helpers.LockController;
-import org.distorted.helpers.MovesController;
-import org.distorted.main.R;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-abstract class RubikScreenBase extends RubikScreenAbstract
-  {
-  private final LockController mLockController;
-  protected MovesController mMovesController;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void createBottomPane(final RubikActivity act, TransparentImageButton butt)
-    {
-    mMovesController.clearMoves(act);
-
-    LinearLayout layoutBot = act.findViewById(R.id.lowerBar);
-    layoutBot.removeAllViews();
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1);
-
-    LinearLayout layoutLeft = new LinearLayout(act);
-    layoutLeft.setLayoutParams(params);
-    LinearLayout layoutMid = new LinearLayout(act);
-    layoutMid.setLayoutParams(params);
-    LinearLayout layoutRight = new LinearLayout(act);
-    layoutRight.setLayoutParams(params);
-
-    ObjectControl control = act.getControl();
-    mMovesController.setupButton(act,control);
-    layoutLeft.addView(mMovesController.getButton());
-    mLockController.setupButton(act,control);
-    layoutMid.addView(mLockController.getButton());
-
-    if( butt !=null ) layoutRight.addView(butt);
-
-    layoutBot.addView(layoutLeft);
-    layoutBot.addView(layoutMid);
-    layoutBot.addView(layoutRight);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void setLockState(final RubikActivity act)
-    {
-    boolean locked = act.getControl().retLocked();
-    mLockController.setState(act,locked);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public RubikScreenBase()
-    {
-    mLockController = new LockController();
-    mMovesController= new MovesController();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void addMove(Activity act, int axis, int row, int angle)
-    {
-    mMovesController.addMove(act,axis,row,angle);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void reddenLock(final RubikActivity act)
-    {
-    ObjectControl control = act.getControl();
-    mLockController.reddenLock(act,control);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void saveMovePreferences(String key,SharedPreferences.Editor editor)
-    {
-    mMovesController.savePreferences(key,editor);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void restoreMovePreferences(Activity act, String key, SharedPreferences preferences)
-    {
-    mMovesController.restorePreferences(act,key,preferences);
-    }
-  }
diff --git a/src/main/java/org/distorted/screens/RubikScreenDone.java b/src/main/java/org/distorted/screens/RubikScreenDone.java
deleted file mode 100644
index 8bdbd227..00000000
--- a/src/main/java/org/distorted/screens/RubikScreenDone.java
+++ /dev/null
@@ -1,112 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.screens;
-
-import android.content.SharedPreferences;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.fragment.app.FragmentManager;
-
-import org.distorted.dialogs.RubikDialogNewRecord;
-import org.distorted.dialogs.RubikDialogSolved;
-import org.distorted.helpers.TransparentImageButton;
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikScreenDone extends RubikScreenAbstract
-  {
-  private TransparentImageButton mBackButton;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void leaveScreen(RubikActivity act)
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void enterScreen(final RubikActivity act)
-    {
-    float width = act.getScreenWidthInPixels();
-    float titleSize = width*RubikActivity.TITLE_TEXT_SIZE;
-    LayoutInflater inflater = act.getLayoutInflater();
-
-    // TOP ////////////////////////////
-    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
-    layoutTop.removeAllViews();
-    TextView label = (TextView)inflater.inflate(R.layout.upper_text, null);
-    label.setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize);
-    label.setText(R.string.solved);
-    layoutTop.addView(label);
-
-    // BOT ////////////////////////////
-    LinearLayout layoutBot = act.findViewById(R.id.lowerBar);
-    layoutBot.removeAllViews();
-
-    LinearLayout.LayoutParams paramsL = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1);
-    LinearLayout.LayoutParams paramsR = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,2);
-
-    LinearLayout layoutLeft = new LinearLayout(act);
-    layoutLeft.setLayoutParams(paramsL);
-    LinearLayout layoutRight = new LinearLayout(act);
-    layoutRight.setLayoutParams(paramsR);
-
-    setupBackButton(act);
-
-    layoutRight.addView(mBackButton);
-    layoutBot.addView(layoutLeft);
-    layoutBot.addView(layoutRight);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupBackButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    mBackButton = new TransparentImageButton(act,R.drawable.ui_back,params);
-
-    mBackButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        ScreenList.goBack(act);
-
-        FragmentManager mana = act.getSupportFragmentManager();
-        RubikDialogNewRecord diag1 = (RubikDialogNewRecord) mana.findFragmentByTag(RubikDialogNewRecord.getDialogTag());
-        RubikDialogSolved    diag2 = (RubikDialogSolved   ) mana.findFragmentByTag(RubikDialogSolved.getDialogTag());
-
-        if( diag1 !=null ) diag1.dismiss();
-        if( diag2 !=null ) diag2.dismiss();
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void savePreferences(SharedPreferences.Editor editor)
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void restorePreferences(SharedPreferences preferences)
-    {
-
-    }
-  }
diff --git a/src/main/java/org/distorted/screens/RubikScreenPattern.java b/src/main/java/org/distorted/screens/RubikScreenPattern.java
deleted file mode 100644
index 0988086e..00000000
--- a/src/main/java/org/distorted/screens/RubikScreenPattern.java
+++ /dev/null
@@ -1,247 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.screens;
-
-import android.content.SharedPreferences;
-import androidx.fragment.app.FragmentManager;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import org.distorted.objectlib.main.ObjectControl;
-
-import org.distorted.main.R;
-import org.distorted.dialogs.RubikDialogPattern;
-import org.distorted.helpers.TransparentImageButton;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.objects.RubikObjectList;
-import org.distorted.objectlib.patterns.RubikPattern;
-import org.distorted.objectlib.patterns.RubikPatternList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikScreenPattern extends RubikScreenAbstract
-  {
-  private TextView mText;
-  private TransparentImageButton mPrevButton, mNextButton, mBackButton;
-  private TextView mMovesText;
-  private int mNumMoves;
-  private int mPatternOrdinal, mCategory, mPattern;
-  private float mButtonSize;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  RubikScreenPattern()
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void leaveScreen(RubikActivity act)
-    {
-    int object = RubikPatternList.getObject(mPatternOrdinal);
-
-    if( !RubikObjectList.setCurrObject(object) )
-      {
-      act.changeObject(object,false);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void enterScreen(final RubikActivity act)
-    {
-    float width = act.getScreenWidthInPixels();
-    mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
-    float titleSize  = width*RubikActivity.TITLE_TEXT_SIZE;
-    LayoutInflater inflater = act.getLayoutInflater();
-
-    // TOP ////////////////////////////
-    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
-    layoutTop.removeAllViews();
-    mText = (TextView)inflater.inflate(R.layout.upper_pattern_text, null);
-    mText.setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize);
-    mText.setText(R.string.patterns);
-    layoutTop.addView(mText);
-
-    // BOT ////////////////////////////
-    LinearLayout layoutBot = act.findViewById(R.id.lowerBar);
-    layoutBot.removeAllViews();
-
-    setupPrevButton(act);
-    setupNextButton(act);
-    setupTextView(act,width);
-
-    setTrioState(false);
-
-    LinearLayout.LayoutParams paramsL = new LinearLayout.LayoutParams((int)(width/2),LinearLayout.LayoutParams.MATCH_PARENT);
-    LinearLayout.LayoutParams paramsM = new LinearLayout.LayoutParams((int)(width/6),LinearLayout.LayoutParams.MATCH_PARENT);
-    LinearLayout.LayoutParams paramsR = new LinearLayout.LayoutParams((int)(width/3),LinearLayout.LayoutParams.MATCH_PARENT);
-
-    LinearLayout layoutLeft = new LinearLayout(act);
-    layoutLeft.setLayoutParams(paramsL);
-    LinearLayout layoutMid = new LinearLayout(act);
-    layoutMid.setLayoutParams(paramsM);
-    LinearLayout layoutRight = new LinearLayout(act);
-    layoutRight.setLayoutParams(paramsR);
-
-    layoutLeft.addView(mPrevButton);
-    layoutLeft.addView(mMovesText);
-    layoutLeft.addView(mNextButton);
-
-    setupBackButton(act);
-
-    layoutRight.addView(mBackButton);
-
-    layoutBot.addView(layoutLeft);
-    layoutBot.addView(layoutMid);
-    layoutBot.addView(layoutRight);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void showDialog(FragmentManager manager)
-    {
-    RubikDialogPattern diag = new RubikDialogPattern();
-    diag.show( manager, RubikDialogPattern.getDialogTag() );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setTrioState(boolean enable)
-    {
-    int state = enable ? View.VISIBLE : View.INVISIBLE;
-
-    if( mPrevButton!=null ) mPrevButton.setVisibility(state);
-    if( mNextButton!=null ) mNextButton.setVisibility(state);
-    if( mMovesText !=null ) mMovesText.setVisibility(state);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupBackButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    mBackButton = new TransparentImageButton(act,R.drawable.ui_back,params);
-
-    mBackButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        FragmentManager mana = act.getSupportFragmentManager();
-        ScreenList.goBack(act);
-        showDialog(mana);
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupPrevButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    mPrevButton = new TransparentImageButton(act,R.drawable.ui_left,params);
-
-    mPrevButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        RubikPattern pattern = RubikPattern.getInstance();
-        ObjectControl control = act.getControl();
-        pattern.backMove( control, mPatternOrdinal, mCategory, mPattern);
-        int currMove = pattern.getCurMove(mPatternOrdinal, mCategory, mPattern);
-        mMovesText.setText(act.getString(R.string.mo_placeholder,currMove,mNumMoves));
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupNextButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    mNextButton = new TransparentImageButton(act,R.drawable.ui_right,params);
-
-    mNextButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        RubikPattern pattern = RubikPattern.getInstance();
-        ObjectControl control = act.getControl();
-        pattern.makeMove( control, mPatternOrdinal, mCategory, mPattern);
-        int currMove = pattern.getCurMove(mPatternOrdinal, mCategory, mPattern);
-        mMovesText.setText(act.getString(R.string.mo_placeholder,currMove,mNumMoves));
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupTextView(final RubikActivity act, final float width)
-    {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,2.0f);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mMovesText = new TextView(act);
-    mMovesText.setTextSize(20);
-    mMovesText.setLayoutParams(params);
-    mMovesText.setPadding(padding,0,padding,0);
-    mMovesText.setGravity(Gravity.CENTER);
-    mMovesText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
-    mMovesText.setText(act.getString(R.string.mo_placeholder,0,0));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void setPattern(final RubikActivity act, int ordinal, int category, int pattern)
-    {
-    mPatternOrdinal = ordinal;
-    mCategory       = category;
-    mPattern        = pattern;
-
-    setTrioState(true);
-
-    RubikPattern patt = RubikPattern.getInstance();
-    String patternName = patt.getPatternName(ordinal,category,pattern);
-    mText.setText(patternName);
-
-    mNumMoves   = patt.getNumMoves(ordinal,category,pattern);
-    int currMove= patt.getCurMove(ordinal,category,pattern);
-
-    mMovesText.setText(act.getString(R.string.mo_placeholder,currMove,mNumMoves));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void savePreferences(SharedPreferences.Editor editor)
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void restorePreferences(SharedPreferences preferences)
-    {
-
-    }
-  }
diff --git a/src/main/java/org/distorted/screens/RubikScreenPlay.java b/src/main/java/org/distorted/screens/RubikScreenPlay.java
deleted file mode 100644
index 53ee542a..00000000
--- a/src/main/java/org/distorted/screens/RubikScreenPlay.java
+++ /dev/null
@@ -1,714 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.screens;
-
-import java.lang.ref.WeakReference;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.os.Build;
-import android.os.Bundle;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.GridLayout;
-import android.widget.ImageButton;
-import android.widget.LinearLayout;
-import android.widget.PopupWindow;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import org.distorted.dialogs.RubikDialogCreators;
-import org.distorted.dialogs.RubikDialogSolvers;
-import org.distorted.dialogs.RubikDialogStarsStatus;
-import org.distorted.dialogs.RubikDialogUpdates;
-import org.distorted.dialogs.RubikDialogAbout;
-import org.distorted.external.RubikNetwork;
-import org.distorted.external.RubikScores;
-import org.distorted.external.RubikUpdates;
-
-import org.distorted.helpers.PopupCreator;
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.dialogs.RubikDialogPattern;
-import org.distorted.dialogs.RubikDialogScores;
-import org.distorted.dialogs.RubikDialogTutorial;
-import org.distorted.helpers.TransparentImageButton;
-import org.distorted.objectlib.effects.BaseEffect;
-import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objects.RubikObject;
-import org.distorted.objects.RubikObjectList;
-
-import static android.view.View.GONE;
-import static android.view.View.inflate;
-import static org.distorted.main_old.RubikActivity.USE_IAP;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikScreenPlay extends RubikScreenBase implements RubikNetwork.Updatee
-  {
-  private static final int MP = LinearLayout.LayoutParams.MATCH_PARENT;
-
-  private static final float MENU_BUTTON_HEIGHT  = 0.068f;
-  private static final float MENU_TEXT_SIZE      = 0.024f;
-  private static final float MENU_MARGIN         = 0.008f;
-  private static final float MENU_WIDTH          = 0.650f;
-  private static final float LEVEL_BUTTON_HEIGHT = 0.089f;
-
-  public static final int NUM_COLUMNS  = 5;
-  public static final int LEVELS_SHOWN = 8;
-  private static final int[] mLocation = new int[2];
-
-  private TransparentImageButton mObjButton, mMenuButton, mSolveButton, mScrambleButton;
-  private PopupWindow mObjectPopup, mMenuPopup;
-  private WeakReference<RubikActivity> mWeakAct;
-  private TextView mBubbleUpdates;
-  private Button[] mLevel;
-  private int mObjectSize, mMenuLayoutWidth, mMenuLayoutHeight, mMenuButtonHeight, mMenuTextSize;
-  private int mLevelValue;
-  private int mColCount, mRowCount, mMaxRowCount;
-  private int mUpperBarHeight;
-  private boolean mShouldReactToEndOfScrambling;
-  private float mScreenWidth, mScreenHeight;
-  private int mLevelHeight, mLevelWidth;
-  private int mOldNumScramble;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void leaveScreen(RubikActivity act)
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void enterScreen(final RubikActivity act)
-    {
-    mWeakAct = new WeakReference<>(act);
-    mScreenWidth  = act.getScreenWidthInPixels();
-    mScreenHeight = act.getScreenHeightInPixels();
-    mUpperBarHeight = act.getHeightUpperBar();
-    mMenuButtonHeight = (int)(mScreenHeight*MENU_BUTTON_HEIGHT);
-    mMenuTextSize     = (int)(mScreenHeight*MENU_TEXT_SIZE);
-
-    mObjectPopup = null;
-
-    // TOP ////////////////////////////
-    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
-    layoutTop.removeAllViews();
-
-    setupSolveButton(act);
-    layoutTop.addView(mSolveButton);
-    setupMenuButton(act,mScreenWidth, mScreenHeight);
-    layoutTop.addView(mMenuButton);
-    setupScrambleButton(act);
-    layoutTop.addView(mScrambleButton);
-
-    // BOTTOM /////////////////////////
-    setupObjectButton(act,mScreenWidth);
-    createBottomPane(act,mObjButton);
-    }
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupObjectButton(final RubikActivity act, final float width)
-    {
-    final int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(MP,MP,1.0f);
-    mObjButton = new TransparentImageButton(act, R.drawable.ui_cube_menu,params);
-
-    mObjButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View view)
-        {
-        if( act.getControl().isScramblingAndSolvingNotBlocked() )
-          {
-          if( mObjectPopup==null )
-            {
-            float width = act.getScreenWidthInPixels();
-            float height= act.getScreenHeightInPixels();
-            setupObjectWindow(act,width,height);
-            }
-
-          int rowCount = Math.min(mMaxRowCount,mRowCount);
-          View popupView = mObjectPopup.getContentView();
-          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
-          displayPopup(act,view,mObjectPopup,mObjectSize*mColCount,mObjectSize*rowCount+5*margin,margin,margin);
-          }
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupMenuButton(final RubikActivity act, final float width, final float height)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(MP,MP,1.0f);
-    mMenuButton = new TransparentImageButton(act, R.drawable.ui_menu,params);
-
-    mMenuButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View view)
-        {
-        if( act.getControl().isScramblingAndSolvingNotBlocked() )
-          {
-          if( mMenuPopup==null )
-            {
-            float width = act.getScreenWidthInPixels();
-            setupMenuWindow(act,width,height);
-            }
-
-          View popupView = mMenuPopup.getContentView();
-          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
-          setupLevelButtonVisibilityAndColor(act);
-          displayPopup(act,view,mMenuPopup,mMenuLayoutWidth,mMenuLayoutHeight,(int)(-mMenuLayoutWidth/2 + width/6),0);
-          }
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupObjectWindow(final RubikActivity act, final float width, final float height)
-    {
-    int numObjects = RubikObjectList.getNumObjects();
-    mRowCount = (numObjects + NUM_COLUMNS-1) / NUM_COLUMNS;
-    mColCount = NUM_COLUMNS;
-
-    int cubeSize = (int)( (Math.min(width,(int)(height*0.7f))) / 9 );
-    int margin   = (int)(height*RubikActivity.POPUP_MARGIN);
-    int padding  = (int)(height*RubikActivity.POPUP_PADDING);
-    int botHeight= (int)(height*RubikActivity.POPUP_BOTTOM);
-    mObjectSize  = (int)(cubeSize + 2*margin + 0.5f);
-    mMaxRowCount = (int)((height-1.8f*mUpperBarHeight)/mObjectSize);
-
-    LinearLayout view = (LinearLayout)inflate( act, R.layout.popup_object, null);
-    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
-    RelativeLayout bottomLayout = view.findViewById(R.id.bottomLayout);
-
-    ViewGroup.LayoutParams params = bottomLayout.getLayoutParams();
-    params.height = botHeight;
-
-    setupBottomLayout(act,bottomLayout);
-
-    PopupCreator.createObjectGrid(objectGrid,act,mRowCount,mColCount,numObjects,margin,cubeSize,padding);
-
-    for(int child=0; child<numObjects; child++)
-      {
-      final RubikObject obj = RubikObjectList.getObject(child);
-      View v = objectGrid.getChildAt(child);
-      ImageButton button = PopupCreator.getButton(obj,v);
-      final int ordinal = child;
-
-      button.setOnClickListener( new View.OnClickListener()
-        {
-        @Override
-        public void onClick(View v)
-          {
-          if( obj!=null && act.getControl().isScramblingAndSolvingNotBlocked() && ScreenList.getCurrentScreen()==ScreenList.PLAY )
-            {
-            if( obj.isFree() )
-              {
-              RubikObjectList.setCurrObject(ordinal);
-              act.changeObject(ordinal,true);
-              if( mMenuPopup!=null ) setupLevelButtonVisibilityAndColor(act);
-              mMovesController.clearMoves(act);
-              }
-            else
-              {
-              act.switchToPurchase(ordinal);
-              }
-            }
-
-          if( mObjectPopup!=null ) mObjectPopup.dismiss();
-          }
-        });
-      }
-
-    mObjectPopup = new PopupWindow(act);
-    mObjectPopup.setFocusable(true);
-    mObjectPopup.setContentView(view);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupBottomLayout(final RubikActivity act, final RelativeLayout layout)
-    {
-    ImageButton buttonTut = layout.findViewById(R.id.buttonTut);
-    ImageButton buttonDow = layout.findViewById(R.id.buttonDow);
-    ImageButton buttonInf = layout.findViewById(R.id.buttonInf);
-
-    buttonTut.setImageResource(R.drawable.ui_tutorial);
-    buttonDow.setImageResource(R.drawable.ui_download);
-    buttonInf.setImageResource(R.drawable.ui_info);
-
-    TypedValue outValue = new TypedValue();
-    act.getTheme().resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, outValue, true);
-    buttonTut.setBackgroundResource(outValue.resourceId);
-    buttonDow.setBackgroundResource(outValue.resourceId);
-    buttonInf.setBackgroundResource(outValue.resourceId);
-
-    buttonTut.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        if( mObjectPopup!=null ) mObjectPopup.dismiss();
-        RubikDialogTutorial tDiag = new RubikDialogTutorial();
-        tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
-        }
-      });
-
-    buttonDow.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        if( mObjectPopup!=null ) mObjectPopup.dismiss();
-        RubikDialogUpdates uDiag = new RubikDialogUpdates();
-        uDiag.show( act.getSupportFragmentManager(), RubikDialogUpdates.getDialogTag() );
-        }
-      });
-
-    buttonInf.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        if( mObjectPopup!=null ) mObjectPopup.dismiss();
-        int currObject = RubikObjectList.getCurrObject();
-        act.switchToConfig(currObject);
-        }
-      });
-
-    mBubbleUpdates = layout.findViewById(R.id.bubbleUpdates);
-    mBubbleUpdates.setVisibility(View.INVISIBLE);
-
-    RubikNetwork network = RubikNetwork.getInstance();
-    network.signUpForUpdates(this);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void setupSolveButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(MP,MP,1.0f);
-    mSolveButton = new TransparentImageButton(act, R.drawable.ui_cube_solve,params);
-
-    mSolveButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        act.getControl().solveObject();
-        mMovesController.clearMoves(act);
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupScrambleButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(MP,MP,1.0f);
-    mScrambleButton = new TransparentImageButton(act, R.drawable.ui_cube_scramble,params);
-
-    mScrambleButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        int duration = BaseEffect.Type.FAST_SCRAMBLE.getDuration();
-        boolean success = act.getControl().fastScrambleObject(duration,RubikObject.FAST_SCRAMBLES);
-        if( success ) mShouldReactToEndOfScrambling = false;
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupMenuWindow(final RubikActivity act, final float width, final float height)
-    {
-    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-    final View layout = layoutInflater.inflate(R.layout.popup_menu, null);
-
-    mMenuPopup = new PopupWindow(act);
-    mMenuPopup.setContentView(layout);
-    mMenuPopup.setFocusable(true);
-    int padding = (int)(height*MENU_MARGIN);
-    int numButtons = USE_IAP ? 7 : 6;
-    mLevelHeight = (int)(height*LEVEL_BUTTON_HEIGHT);
-    mMenuLayoutHeight= padding + numButtons*(mMenuButtonHeight+padding) + mLevelHeight/3 + 3*(mLevelHeight+padding);
-    mMenuLayoutWidth = Math.min((int)(width*MENU_WIDTH),mMenuLayoutHeight/2);
-    mLevelWidth = (mMenuLayoutWidth-4*padding)/3;
-
-    layout.setPadding(padding,0,padding,0);
-
-    if( USE_IAP )
-      {
-      Button stars = layout.findViewById(R.id.menuStars);
-      stars.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
-      stars.setOnClickListener( new View.OnClickListener()
-          {
-          @Override
-          public void onClick(View v)
-            {
-            mMenuPopup.dismiss();
-            RubikDialogStarsStatus d = new RubikDialogStarsStatus();
-            d.show(act.getSupportFragmentManager(), null);
-            }
-          });
-      }
-    else
-      {
-      Button stars = layout.findViewById(R.id.menuStars);
-      stars.setVisibility(GONE);
-      }
-
-    Button solver = layout.findViewById(R.id.menuSolver);
-    solver.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
-    solver.setOnClickListener( new View.OnClickListener()
-        {
-        @Override
-        public void onClick(View v)
-          {
-          mMenuPopup.dismiss();
-          RubikDialogSolvers solvers = new RubikDialogSolvers();
-          solvers.show(act.getSupportFragmentManager(), RubikDialogSolvers.getDialogTag() );
-          }
-        });
-
-    Button highScores = layout.findViewById(R.id.menuHighScores);
-    highScores.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
-    highScores.setOnClickListener( new View.OnClickListener()
-        {
-        @Override
-        public void onClick(View v)
-          {
-          mMenuPopup.dismiss();
-          Bundle sBundle = new Bundle();
-          sBundle.putString("argument", "false");
-          RubikDialogScores scores = new RubikDialogScores();
-          scores.setArguments(sBundle);
-          scores.show(act.getSupportFragmentManager(), null);
-          }
-        });
-
-    Button prettyPatterns = layout.findViewById(R.id.menuPrettyPatterns);
-    prettyPatterns.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
-    prettyPatterns.setOnClickListener( new View.OnClickListener()
-        {
-        @Override
-        public void onClick(View v)
-          {
-          mMenuPopup.dismiss();
-          RubikDialogPattern pDiag = new RubikDialogPattern();
-          pDiag.show( act.getSupportFragmentManager(), RubikDialogPattern.getDialogTag() );
-          }
-        });
-
-    Button tutorials = layout.findViewById(R.id.menuTutorials);
-    tutorials.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
-    tutorials.setOnClickListener( new View.OnClickListener()
-        {
-        @Override
-        public void onClick(View v)
-          {
-          mMenuPopup.dismiss();
-          RubikDialogTutorial tDiag = new RubikDialogTutorial();
-          tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
-          }
-        });
-
-    Button bandaged = layout.findViewById(R.id.menuBandaged);
-    bandaged.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
-    bandaged.setOnClickListener( new View.OnClickListener()
-        {
-        @Override
-        public void onClick(View v)
-          {
-          mMenuPopup.dismiss();
-          RubikDialogCreators creators = new RubikDialogCreators();
-          creators.show(act.getSupportFragmentManager(), RubikDialogCreators.getDialogTag() );
-          }
-        });
-
-    Button whatsNew = layout.findViewById(R.id.menuNew);
-    whatsNew.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
-    whatsNew.setOnClickListener( new View.OnClickListener()
-        {
-        @Override
-        public void onClick(View v)
-          {
-          mMenuPopup.dismiss();
-          RubikDialogAbout aDiag = new RubikDialogAbout();
-          aDiag.show(act.getSupportFragmentManager(), null);
-          }
-        });
-
-    TextView levels = layout.findViewById(R.id.menuLevels);
-    levels.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
-
-    setupLevelButtons(act,layout,padding/2);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupLevelButtons(RubikActivity act, View layout, int margin)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mLevelWidth,mLevelHeight);
-    params.setMargins(margin,margin,margin,margin);
-
-    mOldNumScramble = LEVELS_SHOWN+1;
-
-    mLevel = new Button[LEVELS_SHOWN+1];
-
-    mLevel[0] = layout.findViewById(R.id.level1);
-    mLevel[1] = layout.findViewById(R.id.level2);
-    mLevel[2] = layout.findViewById(R.id.level3);
-    mLevel[3] = layout.findViewById(R.id.level4);
-    mLevel[4] = layout.findViewById(R.id.level5);
-    mLevel[5] = layout.findViewById(R.id.level6);
-    mLevel[6] = layout.findViewById(R.id.level7);
-    mLevel[7] = layout.findViewById(R.id.level8);
-    mLevel[8] = layout.findViewById(R.id.levelM);
-
-    for(int i=0; i<=LEVELS_SHOWN; i++)
-      {
-      final int ii = i;
-      mLevel[i].setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
-      mLevel[i].setLayoutParams(params);
-      mLevel[i].setOnClickListener( new View.OnClickListener()
-        {
-        @Override
-        public void onClick(View v)
-          {
-          ObjectControl control = act.getControl();
-
-          if( control.isScramblingAndSolvingNotBlocked() )
-            {
-            if( mMenuPopup!=null ) mMenuPopup.dismiss();
-
-            int currObject = RubikObjectList.getCurrObject();
-            RubikObject object = RubikObjectList.getObject(currObject);
-            final int scrambles = ii<LEVELS_SHOWN ? ii+1 : (object==null ? 0 : object.getNumScramble());
-
-            boolean success = control.scrambleObject(scrambles);
-            if( success )
-              {
-              mLevelValue = ii+1;
-              mShouldReactToEndOfScrambling = true;
-              }
-            }
-          }
-        });
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupLevelButtonVisibilityAndColor(RubikActivity act)
-    {
-    int currObject = RubikObjectList.getCurrObject();
-    RubikObject object = RubikObjectList.getObject(currObject);
-    int numScramble = object==null ? 1 : object.getNumScramble();
-    RubikScores scores = RubikScores.getInstance();
-    Resources res = act.getResources();
-    ColorStateList colorG = ColorStateList.valueOf(res.getColor(R.color.green));
-    ColorStateList colorD = ColorStateList.valueOf(res.getColor(R.color.dark_grey));
-
-    for(int level=0; level<=LEVELS_SHOWN; level++)
-      {
-      boolean isSolved = scores.isSolved(currObject,level);
-      mLevel[level].setBackgroundTintList( isSolved ? colorG : colorD);
-      }
-
-    if( numScramble<=LEVELS_SHOWN || mOldNumScramble<=LEVELS_SHOWN )
-      {
-      if( numScramble<mOldNumScramble )
-        {
-        int max = Math.min(LEVELS_SHOWN,mOldNumScramble-1);
-        for(int level=numScramble; level<=max; level++) mLevel[level].setVisibility(View.INVISIBLE);
-        mLevel[numScramble-1].setText(R.string.levelM);
-        }
-      if( numScramble>mOldNumScramble )
-        {
-        int max = Math.min(LEVELS_SHOWN,numScramble-1);
-        mLevel[mOldNumScramble-1].setText( String.valueOf(mOldNumScramble) );
-
-        for(int level=mOldNumScramble; level<=max; level++)
-          {
-          mLevel[level].setVisibility(View.VISIBLE);
-          if( level<max ) mLevel[level].setText( String.valueOf(level+1) );
-          else            mLevel[level].setText( R.string.levelM );
-          }
-        }
-      }
-
-    mOldNumScramble = numScramble;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// This is necessary! Otherwise the ObjectPopup will not be re-created next time and we will still
-// hold a reference to the old instance of the RubikActivity class (because setupObjectWindow is not
-// going to be called)
-// An reference to the old instance of RubikActivity will cause all sorts of strange issues.
-
-  public void savePreferences(SharedPreferences.Editor editor)
-    {
-    editor.putInt("play_LevelValue", mLevelValue );
-
-    if( mObjectPopup!=null )
-      {
-      mObjectPopup.dismiss();
-      mObjectPopup = null;
-      }
-
-    if( mMenuPopup!=null )
-      {
-      mMenuPopup.dismiss();
-      mMenuPopup = null;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void restorePreferences(SharedPreferences preferences)
-    {
-    mLevelValue = preferences.getInt("play_LevelValue", 0);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
-
-  private void displayPopup(Activity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
-    {
-    View topLayout = act.findViewById(R.id.relativeLayout);
-    boolean isFullScreen;
-
-    if( topLayout!=null )
-      {
-      topLayout.getLocationOnScreen(mLocation);
-      isFullScreen = (mLocation[1]==0);
-      }
-    else
-      {
-      isFullScreen = true;
-      }
-
-    try
-      {
-      // if on Android 11 or we are fullscreen
-      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
-        {
-        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
-        window.update(view, w, h);
-        }
-      else  // Android 10 or below in pop-up mode or split-screen mode
-        {
-        view.getLocationOnScreen(mLocation);
-        int width  = view.getWidth();
-        int height = view.getHeight();
-        int x = mLocation[0]+(width-w)/2;
-        int y = mLocation[1]+height+yoff;
-
-        window.showAsDropDown(view);
-        window.update(x,y,w,h);
-        }
-      }
-    catch( IllegalArgumentException iae )
-      {
-      // ignore, this means window is 'not attached to window manager' -
-      // which most probably is because we are already exiting the app.
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getLevel()
-    {
-    return mLevelValue;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void recreatePopup()
-    {
-    mObjectPopup = null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public boolean shouldReactToEndOfScrambling()
-    {
-    return mShouldReactToEndOfScrambling;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void receiveUpdate(RubikUpdates updates)
-    {
-    Activity act = mWeakAct.get();
-
-    if( act!=null )
-      {
-      act.runOnUiThread(new Runnable()
-        {
-        @Override
-        public void run()
-          {
-          int num = updates.getCompletedNumber();
-
-          if( num>0 )
-            {
-            String shownNum = String.valueOf(num);
-            mBubbleUpdates.setText(shownNum);
-            mBubbleUpdates.setVisibility(View.VISIBLE);
-            int height = (int)(0.05f*mScreenWidth);
-            mBubbleUpdates.setTextSize(TypedValue.COMPLEX_UNIT_PX,height);
-            }
-         else
-            {
-            mBubbleUpdates.setVisibility(View.INVISIBLE);
-            }
-          }
-        });
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void errorUpdate()
-    {
-    android.util.Log.e("D", "RubikScreenPlay: Error receiving downloaded objects update");
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getType()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void objectDownloaded(String shortName)
-    {
-    recreatePopup();
-    }
-  }
diff --git a/src/main/java/org/distorted/screens/RubikScreenReady.java b/src/main/java/org/distorted/screens/RubikScreenReady.java
deleted file mode 100644
index 8b65f76b..00000000
--- a/src/main/java/org/distorted/screens/RubikScreenReady.java
+++ /dev/null
@@ -1,86 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.screens;
-
-import android.content.SharedPreferences;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import org.distorted.helpers.TransparentImageButton;
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikScreenReady extends RubikScreenBase
-  {
-  private TransparentImageButton mBackButton;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void leaveScreen(RubikActivity act)
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void enterScreen(final RubikActivity act)
-    {
-    float width = act.getScreenWidthInPixels();
-    float titleSize = width*RubikActivity.TITLE_TEXT_SIZE;
-    LayoutInflater inflater = act.getLayoutInflater();
-
-    // TOP ////////////////////////////
-    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
-    layoutTop.removeAllViews();
-    TextView label = (TextView)inflater.inflate(R.layout.upper_text, null);
-    label.setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize);
-    label.setText(R.string.ready);
-    layoutTop.addView(label);
-
-    setupBackButton(act);
-    createBottomPane(act,mBackButton);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupBackButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    mBackButton = new TransparentImageButton(act,R.drawable.ui_back,params);
-
-    mBackButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        ScreenList.goBack(act);
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void savePreferences(SharedPreferences.Editor editor)
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void restorePreferences(SharedPreferences preferences)
-    {
-
-    }
-  }
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolution.java b/src/main/java/org/distorted/screens/RubikScreenSolution.java
deleted file mode 100644
index 1dfe81ea..00000000
--- a/src/main/java/org/distorted/screens/RubikScreenSolution.java
+++ /dev/null
@@ -1,294 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.screens;
-
-import android.content.SharedPreferences;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.helpers.MovesFinished;
-
-import org.distorted.helpers.TransparentImageButton;
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.objectlib.patterns.RubikPattern;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikScreenSolution extends RubikScreenAbstract implements MovesFinished
-  {
-  private static final int MILLIS_PER_DEGREE = 6;
-
-  private TransparentImageButton mPrevButton, mNextButton, mBackButton;
-  private TextView mMovesText;
-  private int[][] mMoves;
-  private int mCurrMove, mNumMoves;
-  private boolean mCanRotate;
-  private float mButtonSize;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void leaveScreen(RubikActivity act)
-    {
-    ObjectControl control = act.getControl();
-    control.solveOnly();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void enterScreen(final RubikActivity act)
-    {
-    float width = act.getScreenWidthInPixels();
-    mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
-    float titleSize  = width*RubikActivity.TITLE_TEXT_SIZE;
-
-    LayoutInflater inflater = act.getLayoutInflater();
-
-    // TOP ////////////////////////////
-    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
-    layoutTop.removeAllViews();
-
-    final TextView text = (TextView)inflater.inflate(R.layout.upper_text, null);
-    text.setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize);
-    text.setText(R.string.solution);
-    layoutTop.addView(text);
-
-    // BOT ////////////////////////////
-    LinearLayout layoutBot = act.findViewById(R.id.lowerBar);
-    layoutBot.removeAllViews();
-
-    LinearLayout.LayoutParams paramsL = new LinearLayout.LayoutParams((int)(width/2),LinearLayout.LayoutParams.MATCH_PARENT);
-    LinearLayout.LayoutParams paramsM = new LinearLayout.LayoutParams((int)(width/6),LinearLayout.LayoutParams.MATCH_PARENT);
-    LinearLayout.LayoutParams paramsR = new LinearLayout.LayoutParams((int)(width/3),LinearLayout.LayoutParams.MATCH_PARENT);
-
-    LinearLayout layoutLeft = new LinearLayout(act);
-    layoutLeft.setLayoutParams(paramsL);
-    LinearLayout layoutMid = new LinearLayout(act);
-    layoutMid.setLayoutParams(paramsM);
-    LinearLayout layoutRight = new LinearLayout(act);
-    layoutRight.setLayoutParams(paramsR);
-
-    setupPrevButton(act);
-    setupNextButton(act);
-    setupTextView(act,width);
-
-    layoutLeft.addView(mPrevButton);
-    layoutLeft.addView(mMovesText);
-    layoutLeft.addView(mNextButton);
-
-    setupBackButton(act);
-
-    layoutRight.addView(mBackButton);
-
-    layoutBot.addView(layoutLeft);
-    layoutBot.addView(layoutMid);
-    layoutBot.addView(layoutRight);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupPrevButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    mPrevButton = new TransparentImageButton(act,R.drawable.ui_left,params);
-
-    mPrevButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        ObjectControl control = act.getControl();
-        backMove(control);
-        mMovesText.setText(act.getString(R.string.mo_placeholder,mCurrMove,mNumMoves));
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupNextButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    mNextButton = new TransparentImageButton(act,R.drawable.ui_right,params);
-
-    mNextButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        ObjectControl control = act.getControl();
-        makeMove(control);
-        mMovesText.setText(act.getString(R.string.mo_placeholder,mCurrMove,mNumMoves));
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupTextView(final RubikActivity act, final float width)
-    {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,2.0f);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mMovesText = new TextView(act);
-    mMovesText.setTextSize(20);
-    mMovesText.setLayoutParams(params);
-    mMovesText.setPadding(padding,0,padding,0);
-    mMovesText.setGravity(Gravity.CENTER);
-    mMovesText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
-    mMovesText.setText(act.getString(R.string.mo_placeholder,mCurrMove,mNumMoves));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupBackButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    mBackButton = new TransparentImageButton(act,R.drawable.ui_back,params);
-
-    mBackButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        ScreenList.goBack(act);
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void makeMove(ObjectControl control)
-    {
-    if( mCanRotate )
-      {
-      mCurrMove++;
-
-      if( mCurrMove>mNumMoves )
-        {
-        mCurrMove= 0;
-        control.initializeObject(null);
-        }
-      else
-        {
-        int axis      = mMoves[mCurrMove-1][0];
-		    int rowBitmap = mMoves[mCurrMove-1][1];
-		    int bareAngle = mMoves[mCurrMove-1][2];
-
-        if( bareAngle!=0 )
-          {
-          mCanRotate = false;
-          control.addRotation(this, axis, rowBitmap, bareAngle, MILLIS_PER_DEGREE);
-          }
-        else
-          {
-          android.util.Log.e("solution", "error: solution contains angle 0");
-          }
-        }
-      }
-    else
-      {
-      android.util.Log.e("solution", "failed to make move!");
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void backMove(ObjectControl control)
-    {
-    if( mCanRotate )
-      {
-      mCurrMove--;
-
-      if( mCurrMove<0 )
-        {
-        mCurrMove=mNumMoves;
-        control.initializeObject(mMoves);
-        }
-      else
-        {
-        int axis      = mMoves[mCurrMove][0];
-		    int rowBitmap = mMoves[mCurrMove][1];
-		    int bareAngle = mMoves[mCurrMove][2];
-
-        if( bareAngle!=0 )
-          {
-          mCanRotate = false;
-          control.addRotation(this, axis, rowBitmap, -bareAngle, MILLIS_PER_DEGREE);
-          }
-        else
-          {
-          android.util.Log.e("solution", "error: solution contains angle 0");
-          }
-        }
-      }
-    else
-      {
-      android.util.Log.e("solution", "failed to back move!");
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void setupMoves(final RubikActivity act, String moves)
-    {
-    mCanRotate= true;
-    mCurrMove = 0;
-    mNumMoves = moves.length()/4;
-    mMoves    = new int[mNumMoves][3];
-
-    RubikPattern.parseMoves(mMoves,mNumMoves,moves);
-
-    mMovesText.setText(act.getString(R.string.mo_placeholder,mCurrMove,mNumMoves));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void setupMoves(final RubikActivity act, int[][] moves)
-    {
-    mCanRotate= true;
-    mCurrMove = 0;
-    mNumMoves = moves==null ? 0 : moves.length;
-    mMoves    = moves;
-
-    mMovesText.setText(act.getString(R.string.mo_placeholder,mCurrMove,mNumMoves));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void savePreferences(SharedPreferences.Editor editor)
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void restorePreferences(SharedPreferences preferences)
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void onActionFinished(final long effectID)
-    {
-    mCanRotate = true;
-    }
-  }
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolver.java b/src/main/java/org/distorted/screens/RubikScreenSolver.java
deleted file mode 100644
index 1d8f058a..00000000
--- a/src/main/java/org/distorted/screens/RubikScreenSolver.java
+++ /dev/null
@@ -1,472 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.screens;
-
-import static org.distorted.objectlib.main.TwistyObject.*;
-
-import java.lang.ref.WeakReference;
-
-import android.content.SharedPreferences;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import androidx.core.content.ContextCompat;
-import android.view.View;
-import android.widget.ImageButton;
-import android.widget.LinearLayout;
-
-import org.distorted.dialogs.RubikDialogSolverImpossible;
-import org.distorted.main.MainActivity;
-import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.signature.ObjectConstants;
-import org.distorted.objectlib.main.TwistyObject;
-
-import org.distorted.dialogs.RubikDialogSolverError;
-import org.distorted.helpers.TransparentImageButton;
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.objectlib.shape.ShapeDiamond;
-import org.distorted.objectlib.shape.ShapeDodecahedron;
-import org.distorted.objectlib.shape.ShapeHexahedron;
-import org.distorted.objectlib.shape.ShapeIcosahedron;
-import org.distorted.objectlib.shape.ShapeOctahedron;
-import org.distorted.objectlib.shape.ShapeTetrahedron;
-import org.distorted.objects.RubikObjectList;
-import org.distorted.solvers.ImplementedSolversList;
-import org.distorted.solvers.SolverMain;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikScreenSolver extends RubikScreenAbstract
-  {
-  private static final int RESET_DURATION = 1000;
-  private static final int MODE_NORMAL = 0;
-  private static final int MODE_DINO_4 = 1;
-
-  private static Bitmap[] mBitmap;
-  private ImageButton[] mColorButton;
-  private TransparentImageButton mResetButton,mBackButton, mSolveButton;
-  private boolean mSolving;
-  private int mCurrentColor, mCurrentButton;
-  private int[] mFaceColors;
-  private int mColorMode;
-  private int mNumColors;
-  private float mBitmapSize;
-  private WeakReference<RubikActivity> mWeakAct;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void leaveScreen(RubikActivity act)
-    {
-    ObjectControl control = act.getControl();
-    control.unsetLock();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void enterScreen(final RubikActivity act)
-    {
-    ObjectControl control = act.getControl();
-    control.setLock(false);
-
-    float width = act.getScreenWidthInPixels();
-    float heigh = act.getScreenHeightInPixels();
-
-    mWeakAct = new WeakReference<>(act);
-    mSolving = false;
-
-    int solverIndex= act.getSolverIndex();
-    ImplementedSolversList currentSolver = ImplementedSolversList.getSolver(solverIndex);
-    int currentObject = currentSolver.getObject();
-    act.changeIfDifferent(currentObject,control);
-    control.solveOnly();
-    RubikObjectList.setCurrObject(currentObject);
-
-    generateFaceColors(currentObject);
-
-    final float BUTTON_RATIO = 0.75f;
-    int sizeV = (int)(heigh*MainActivity.RATIO_BAR*BUTTON_RATIO);
-    int sizeH = (int)((width/mNumColors)*BUTTON_RATIO);
-    mBitmapSize = Math.min(sizeV,sizeH);
-
-    // TOP ////////////////////////////
-    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
-    layoutTop.removeAllViews();
-
-    if( mNumColors>0 )
-      {
-      setupBitmaps();
-      setupColorButtons(act,width);
-      markButton(act);
-      }
-
-    for(ImageButton button: mColorButton) layoutTop.addView(button);
-
-    // BOT ////////////////////////////
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1);
-
-    LinearLayout layoutL = new LinearLayout(act);
-    layoutL.setLayoutParams(params);
-    LinearLayout layoutM = new LinearLayout(act);
-    layoutM.setLayoutParams(params);
-    LinearLayout layoutR = new LinearLayout(act);
-    layoutR.setLayoutParams(params);
-
-    LinearLayout layoutBot = act.findViewById(R.id.lowerBar);
-    layoutBot.removeAllViews();
-
-    setupResetButton(act);
-    setupSolveButton(act);
-    setupBackButton(act);
-
-    layoutL.addView(mResetButton);
-    layoutM.addView(mSolveButton);
-    layoutR.addView(mBackButton);
-
-    layoutBot.addView(layoutL);
-    layoutBot.addView(layoutM);
-    layoutBot.addView(layoutR);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// This doesn't quite work in many cases, but in case of the solvers that will pop up in foreseeable
-// future it should be ok.
-
-  public void generateFaceColors(int object)
-    {
-    mColorMode = MODE_NORMAL;
-
-    if( object== ObjectConstants.PYRA_3 ||
-        object== ObjectConstants.PYRA_4 ||
-        object== ObjectConstants.PYRA_5 ||
-        object== ObjectConstants.PDUO_2 ||
-        object== ObjectConstants.JING_2 ||
-        object== ObjectConstants.MORP_2 ||
-        object== ObjectConstants.MORP_3 ||
-        object== ObjectConstants.MORP_4  )
-      {
-      mNumColors  = ShapeTetrahedron.NUM_FACES;
-      mFaceColors = ShapeTetrahedron.FACE_COLORS;
-      }
-    else if( object== ObjectConstants.DIAM_2 ||
-             object== ObjectConstants.DIAM_3 ||
-             object== ObjectConstants.DIAM_4 ||
-             object== ObjectConstants.TRAJ_3 ||
-             object== ObjectConstants.TRAJ_4 ||
-             object== ObjectConstants.PDIA_3  )
-      {
-      mNumColors  = ShapeOctahedron.NUM_FACES;
-      mFaceColors = ShapeOctahedron.FACE_COLORS;
-      }
-    else if( object== ObjectConstants.CRYS_3 ||
-             object== ObjectConstants.STAR_3 ||
-             object== ObjectConstants.PENT_2 ||
-             object== ObjectConstants.KILO_3 ||
-             object== ObjectConstants.KILO_5 ||
-             object== ObjectConstants.MEGA_3 ||
-             object== ObjectConstants.MEGA_5  )
-      {
-      mNumColors  = ShapeDodecahedron.NUM_FACES;
-      mFaceColors = ShapeDodecahedron.FACE_COLORS;
-      }
-    else if( object== ObjectConstants.BALL_4 )
-      {
-      mNumColors  = ShapeDiamond.NUM_FACES;
-      mFaceColors = ShapeDiamond.FACE_COLORS;
-      }
-    else if( object== ObjectConstants.ICOS_2 )
-      {
-      mNumColors  = ShapeIcosahedron.NUM_FACES;
-      mFaceColors = ShapeIcosahedron.FACE_COLORS;
-      }
-    else if( object== ObjectConstants.DIN4_3 )
-      {
-      mNumColors  = 4;
-      mFaceColors = new int[] { COLOR_YELLOW, COLOR_RED, COLOR_BLUE, COLOR_WHITE };
-      mColorMode  = MODE_DINO_4;
-      }
-    else
-      {
-      mNumColors  = ShapeHexahedron.NUM_FACES;
-      mFaceColors = ShapeHexahedron.FACE_COLORS;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupBitmaps()
-    {
-    final int SIZE = (int)mBitmapSize;
-    final float R = SIZE*0.15f;
-    final float M = SIZE*0.08f;
-
-    mBitmap = new Bitmap[mNumColors];
-
-    Paint paint = new Paint();
-    paint.setColor(0xff008800);
-    paint.setStyle(Paint.Style.FILL);
-
-    paint.setAntiAlias(true);
-    paint.setTextAlign(Paint.Align.CENTER);
-    paint.setStyle(Paint.Style.FILL);
-
-    for(int i=0; i<mNumColors; i++)
-      {
-      mBitmap[i] = Bitmap.createBitmap(SIZE, SIZE, Bitmap.Config.ARGB_8888);
-      Canvas canvas = new Canvas(mBitmap[i]);
-
-      paint.setColor(0xff000000);
-      canvas.drawRect(0, 0, SIZE, SIZE, paint);
-
-      paint.setColor(mFaceColors[i]);
-      canvas.drawRoundRect( M, M, SIZE-M, SIZE-M, R, R, paint);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int translateColor(int color)
-    {
-    if( mColorMode==MODE_DINO_4 )
-      {
-      int realColor = mFaceColors[color];
-      int[] hexColors = ShapeHexahedron.FACE_COLORS;
-
-      for(int i=0; i<6; i++)
-        if( hexColors[i]==realColor ) return i;
-      }
-
-    return color;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupColorButtons(final RubikActivity act, final float width)
-    {
-    mColorButton = new ImageButton[mNumColors];
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
-
-    for(int i=0; i<mNumColors; i++)
-      {
-      final int ii = i;
-      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
-      params.topMargin    = margin;
-      params.bottomMargin = margin;
-      params.leftMargin   = margin;
-      params.rightMargin  = margin;
-
-      mColorButton[i] = new ImageButton(act);
-      mColorButton[i].setLayoutParams(params);
-      mColorButton[i].setPadding(padding,0,padding,0);
-      mColorButton[i].setImageBitmap(mBitmap[i]);
-
-      mColorButton[i].setOnClickListener( new View.OnClickListener()
-        {
-        @Override
-        public void onClick(View view)
-          {
-          mCurrentColor = translateColor(ii);
-          mCurrentButton= ii;
-          markButton(act);
-          }
-        });
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupResetButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
-    mResetButton = new TransparentImageButton(act, R.drawable.ui_reset, params);
-
-    mResetButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        ObjectControl control = act.getControl();
-        control.resetTextureMapsEffect(RESET_DURATION);
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupSolveButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    mSolveButton = new TransparentImageButton(act,R.drawable.ui_solve,params);
-
-    mSolveButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        if( !mSolving )
-          {
-          mSolving = true;
-          TwistyObject object = act.getObject();
-          SolverMain solver = new SolverMain( act.getInterface(), act.getResources(), object );
-          solver.start();
-          }
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupBackButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    mBackButton = new TransparentImageButton(act,R.drawable.ui_back,params);
-
-    mBackButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        ObjectControl control = act.getControl();
-        control.resetAllTextureMaps();
-        ScreenList.goBack(act);
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void markButton(RubikActivity act)
-    {
-    if( mCurrentButton>=mNumColors )
-      {
-      mCurrentButton = 0;
-      mCurrentColor = translateColor(0);
-      }
-
-    for(int b=0; b<mNumColors; b++)
-      {
-      Drawable d = mColorButton[b].getBackground();
-
-      if( b==mCurrentButton )
-        {
-        d.setColorFilter(ContextCompat.getColor(act,R.color.red), PorterDuff.Mode.MULTIPLY);
-        }
-      else
-        {
-        d.clearColorFilter();
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void savePreferences(SharedPreferences.Editor editor)
-    {
-    editor.putInt("stateSolver_color" , mCurrentColor );
-    editor.putInt("stateSolver_button", mCurrentButton);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void restorePreferences(SharedPreferences preferences)
-    {
-    mCurrentColor = preferences.getInt("stateSolver_color" , 0);
-    mCurrentButton= preferences.getInt("stateSolver_button", 0);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getCurrentColor()
-    {
-    return mCurrentColor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void setSolved(final String moves)
-    {
-    mSolving = false;
-    final RubikActivity act = mWeakAct.get();
-
-    if( act!=null )
-      {
-      act.runOnUiThread(new Runnable()
-        {
-        @Override
-        public void run()
-          {
-          ScreenList.switchScreen(act, ScreenList.SOLU);
-          RubikScreenSolution solution = (RubikScreenSolution) ScreenList.SOLU.getScreenClass();
-          solution.setupMoves(act, moves);
-          }
-        });
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void setSolved(final int[][] moves)
-    {
-    mSolving = false;
-    final RubikActivity act = mWeakAct.get();
-
-    if( act!=null )
-      {
-      act.runOnUiThread(new Runnable()
-        {
-        @Override
-        public void run()
-          {
-          ScreenList.switchScreen(act, ScreenList.SOLU);
-          RubikScreenSolution solution = (RubikScreenSolution) ScreenList.SOLU.getScreenClass();
-          solution.setupMoves(act, moves);
-          }
-        });
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void displayErrorDialog(String message)
-    {
-    mSolving = false;
-    RubikActivity act = mWeakAct.get();
-
-    if( act!=null )
-      {
-      RubikDialogSolverError dialog = new RubikDialogSolverError();
-      Bundle bundle = new Bundle();
-      bundle.putString("argument", message );
-      dialog.setArguments(bundle);
-      dialog.show( act.getSupportFragmentManager(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void displayImpossibleDialog(String message)
-    {
-    mSolving = false;
-    RubikActivity act = mWeakAct.get();
-
-    if( act!=null )
-      {
-      RubikDialogSolverImpossible dialog = new RubikDialogSolverImpossible();
-      Bundle bundle = new Bundle();
-      bundle.putString("argument", message );
-      dialog.setArguments(bundle);
-      dialog.show( act.getSupportFragmentManager(), null);
-      }
-    }
-  }
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolving.java b/src/main/java/org/distorted/screens/RubikScreenSolving.java
deleted file mode 100644
index 7af8a923..00000000
--- a/src/main/java/org/distorted/screens/RubikScreenSolving.java
+++ /dev/null
@@ -1,197 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.screens;
-
-import java.util.Timer;
-import java.util.TimerTask;
-
-import android.content.SharedPreferences;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import org.distorted.dialogs.RubikDialogAbandon;
-import org.distorted.helpers.TransparentImageButton;
-import org.distorted.main.R;
-import org.distorted.main_old.RubikActivity;
-import org.distorted.external.RubikScores;
-import org.distorted.objects.RubikObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikScreenSolving extends RubikScreenBase
-  {
-  private static final int MOVES_THRESHHOLD = 10;
-
-  private TextView mTime;
-  private Timer mTimer;
-  private long mStartTime;
-  private boolean mRunning;
-  private final RubikScores mScores;
-  private long mElapsed;
-  private TransparentImageButton mBackButton;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  RubikScreenSolving()
-    {
-    mScores = RubikScores.getInstance();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void leaveScreen(RubikActivity act)
-    {
-    stopCounting();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void enterScreen(final RubikActivity act)
-    {
-    float width = act.getScreenWidthInPixels();
-    float titleSize  = width*RubikActivity.TITLE_TEXT_SIZE;
-
-    startCounting(act);
-
-    LayoutInflater inflater = act.getLayoutInflater();
-
-    // TOP ////////////////////////////
-    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
-    layoutTop.removeAllViews();
-    mTime = (TextView)inflater.inflate(R.layout.upper_text, null);
-    int elapsed = (int)mElapsed/1000;
-    mTime.setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize);
-    mTime.setText(act.getString(R.string.tm_placeholder,elapsed/60,elapsed%60));
-    layoutTop.addView(mTime);
-
-    setupBackButton(act);
-    createBottomPane(act,mBackButton);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setupBackButton(final RubikActivity act)
-    {
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    mBackButton = new TransparentImageButton(act,R.drawable.ui_back,params);
-
-    mBackButton.setOnClickListener( new View.OnClickListener()
-      {
-      @Override
-      public void onClick(View v)
-        {
-        if( mMovesController.getNumMoves() > MOVES_THRESHHOLD )
-          {
-          RubikDialogAbandon abaDiag = new RubikDialogAbandon();
-          abaDiag.show(act.getSupportFragmentManager(), null);
-          }
-        else
-          {
-          ScreenList.goBack(act);
-          }
-        }
-      });
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void savePreferences(SharedPreferences.Editor editor)
-    {
-    stopCounting();
-
-    mElapsed = System.currentTimeMillis()-mStartTime;
-    editor.putLong("stateSolving_elapsed" , mElapsed);
-    mScores.savePreferences(editor);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void restorePreferences(SharedPreferences preferences)
-    {
-    mElapsed = preferences.getLong("stateSolving_elapsed" , 0 );
-    mScores.restorePreferences(preferences);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void startCounting(final RubikActivity act)
-    {
-    if( !mRunning )
-      {
-      mRunning = true;
-      mStartTime = System.currentTimeMillis() - mElapsed;
-      mTimer = new Timer();
-
-      mTimer.scheduleAtFixedRate(new TimerTask()
-        {
-        @Override
-        public void run()
-          {
-          act.runOnUiThread(new Runnable()
-            {
-            @Override
-            public void run()
-              {
-              int elapsed = (int)(System.currentTimeMillis()-mStartTime)/1000;
-              mTime.setText(act.getString(R.string.tm_placeholder,elapsed/60,elapsed%60));
-              }
-            });
-          }
-        }, 0, 1000);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void stopCounting()
-    {
-    if( mTimer!=null )
-      {
-      mTimer.cancel();
-      mTimer = null;
-      }
-
-    mRunning = false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int stopTimerAndGetRecord()
-    {
-    if( mRunning )
-      {
-      stopCounting();
-      mElapsed = System.currentTimeMillis()-mStartTime;
-      return (int)mElapsed;
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int setRecord()
-    {
-    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-    int object = RubikObjectList.getCurrObject();
-    int level = play.getLevel()-1;
-    return mScores.setRecord(object, level, (int)mElapsed);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void resetElapsed()
-    {
-    mElapsed = 0;
-    }
-  }
diff --git a/src/main/java/org/distorted/screens/ScreenList.java b/src/main/java/org/distorted/screens/ScreenList.java
deleted file mode 100644
index b9fc5b62..00000000
--- a/src/main/java/org/distorted/screens/ScreenList.java
+++ /dev/null
@@ -1,167 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is proprietary software licensed under an EULA which you should have received      //
-// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.screens;
-
-import android.content.SharedPreferences;
-import android.os.Bundle;
-
-import com.google.firebase.analytics.FirebaseAnalytics;
-
-import org.distorted.main_old.RubikActivity;
-import static org.distorted.objectlib.main.ObjectControl.*;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public enum ScreenList
-  {
-  PLAY ( null , MODE_ROTATE , new RubikScreenPlay()     ),
-  SOLV ( PLAY , MODE_ROTATE , new RubikScreenSolving()  ),
-  PATT ( PLAY , MODE_DRAG   , new RubikScreenPattern()  ),
-  SVER ( PLAY , MODE_REPLACE, new RubikScreenSolver()   ),
-  SOLU ( SVER , MODE_DRAG   , new RubikScreenSolution() ),
-  READ ( PLAY , MODE_ROTATE , new RubikScreenReady()    ),
-  DONE ( PLAY , MODE_DRAG   , new RubikScreenDone()     ),
-  ;
-
-  public static final int LENGTH = values().length;
-  private static final ScreenList[] screens;
-  private final ScreenList mBack;
-  private final int mMode;
-  private final RubikScreenAbstract mClass;
-
-  private static ScreenList mCurrScreen;
-
-  static
-    {
-    int i = 0;
-    screens = new ScreenList[LENGTH];
-    for(ScreenList state: ScreenList.values()) screens[i++] = state;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static ScreenList getScreen(int ordinal)
-    {
-    return ordinal>=0 && ordinal<LENGTH ?  screens[ordinal] : PLAY;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static ScreenList getScreenFromName(String name)
-    {
-    for(int i=0; i<LENGTH; i++)
-      {
-      if( name.equals(screens[i].name()) )
-        {
-        return screens[i];
-        }
-      }
-
-    return PLAY;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static ScreenList getCurrentScreen()
-    {
-    return mCurrScreen;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int getMode()
-    {
-    return mCurrScreen.mMode;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void savePreferences(SharedPreferences.Editor editor)
-    {
-    editor.putString("curr_state_name", mCurrScreen.name() );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void restorePreferences(SharedPreferences preferences)
-    {
-    String currScreenName = preferences.getString("curr_state_name", ScreenList.PLAY.name() );
-    mCurrScreen = getScreenFromName(currScreenName);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void goBack(RubikActivity act)
-    {
-    switchScreen(act, mCurrScreen.mBack );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void setScreen(RubikActivity act)
-    {
-    mCurrScreen.enterScreen(act);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void switchScreen(RubikActivity act, ScreenList next)
-    {
-    if( next!=null )
-      {
-      FirebaseAnalytics analytics = act.getAnalytics();
-
-      if( analytics!=null )
-        {
-        Bundle bundle = new Bundle();
-        bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, next.toString());
-        analytics.logEvent(FirebaseAnalytics.Event.LEVEL_START, bundle);
-        }
-
-      if( mCurrScreen !=null ) mCurrScreen.leaveScreen(act);
-      next.enterScreen(act);
-      mCurrScreen = next;
-      }
-    else
-      {
-      act.finish();
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  ScreenList(ScreenList back, int mode, RubikScreenAbstract clazz)
-    {
-    mBack = back;
-    mMode = mode;
-    mClass= clazz;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public RubikScreenAbstract getScreenClass()
-    {
-    return mClass;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void leaveScreen(RubikActivity act)
-    {
-    mClass.leaveScreen(act);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void enterScreen(RubikActivity act)
-    {
-    mClass.enterScreen(act);
-    }
-  }
\ No newline at end of file
