commit f895e77a4fe7a9ee09c1a5a831fa9bc24f9a0fc9
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Mar 23 12:52:37 2020 +0000

    Implement a new Dialog, SetName.

diff --git a/src/main/java/org/distorted/dialog/RubikDialogNewRecord.java b/src/main/java/org/distorted/dialog/RubikDialogNewRecord.java
index 5a876c35..e684e625 100644
--- a/src/main/java/org/distorted/dialog/RubikDialogNewRecord.java
+++ b/src/main/java/org/distorted/dialog/RubikDialogNewRecord.java
@@ -35,6 +35,7 @@ import android.widget.TextView;
 import org.distorted.magic.R;
 import org.distorted.magic.RubikActivity;
 import org.distorted.object.RubikObjectList;
+import org.distorted.scores.RubikScores;
 import org.distorted.uistate.RubikState;
 import org.distorted.uistate.RubikStatePlay;
 
@@ -66,29 +67,43 @@ public class RubikDialogNewRecord extends AppCompatDialogFragment
     TextView tv = (TextView) inflater.inflate(R.layout.dialog_title, null);
     tv.setText(R.string.new_record);
     builder.setCustomTitle(tv);
-
     builder.setCancelable(true);
+
     builder.setPositiveButton( R.string.yes, new DialogInterface.OnClickListener()
       {
       @Override
       public void onClick(DialogInterface dialog, int which)
         {
         RubikActivity act = (RubikActivity)getActivity();
-        RubikState.switchState(act,RubikState.PLAY);
-
-        RubikStatePlay play = (RubikStatePlay) RubikState.PLAY.getStateClass();
-        int object = play.getObject();
-        int size   = play.getSize();
-
+        RubikScores scores = RubikScores.getInstance();
+        String name = scores.getName();
         Bundle bundle = new Bundle();
-        bundle.putInt("tab", RubikObjectList.pack(object,size) );
-        bundle.putBoolean("submitting", true);
+        RubikState.switchState(act,RubikState.PLAY);
 
-        RubikDialogScores scores = new RubikDialogScores();
-        scores.setArguments(bundle);
-        scores.show(act.getSupportFragmentManager(), null);
+        if( name.length()>0 )
+          {
+          RubikStatePlay play = (RubikStatePlay) RubikState.PLAY.getStateClass();
+          int object = play.getObject();
+          int size   = play.getSize();
+
+          bundle.putInt("tab", RubikObjectList.pack(object,size) );
+          bundle.putBoolean("submitting", true);
+
+          RubikDialogScores scoresDiag = new RubikDialogScores();
+          scoresDiag.setArguments(bundle);
+          scoresDiag.show(act.getSupportFragmentManager(), null);
+          }
+        else
+          {
+          bundle.putString("name", name );
+
+          RubikDialogSetName nameDiag = new RubikDialogSetName();
+          nameDiag.setArguments(bundle);
+          nameDiag.show(act.getSupportFragmentManager(), null);
+          }
         }
       });
+
     builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener()
       {
       @Override
diff --git a/src/main/java/org/distorted/dialog/RubikDialogScores.java b/src/main/java/org/distorted/dialog/RubikDialogScores.java
index 579a3f92..9c5d161e 100644
--- a/src/main/java/org/distorted/dialog/RubikDialogScores.java
+++ b/src/main/java/org/distorted/dialog/RubikDialogScores.java
@@ -102,7 +102,7 @@ public class RubikDialogScores extends AppCompatDialogFragment
 
     ViewPager viewPager = view.findViewById(R.id.viewpager);
     TabLayout tabLayout = view.findViewById(R.id.sliding_tabs);
-    mPagerAdapter = new RubikDialogScoresPagerAdapter(act,viewPager,isSubmitting);
+    mPagerAdapter = new RubikDialogScoresPagerAdapter(act,viewPager,isSubmitting, this);
     tabLayout.setupWithViewPager(viewPager);
 
     viewPager.setCurrentItem(curTab);
diff --git a/src/main/java/org/distorted/dialog/RubikDialogScoresPagerAdapter.java b/src/main/java/org/distorted/dialog/RubikDialogScoresPagerAdapter.java
index 426bf8b6..2006f332 100644
--- a/src/main/java/org/distorted/dialog/RubikDialogScoresPagerAdapter.java
+++ b/src/main/java/org/distorted/dialog/RubikDialogScoresPagerAdapter.java
@@ -19,6 +19,7 @@
 
 package org.distorted.dialog;
 
+import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.v4.app.FragmentActivity;
 import android.support.v4.view.PagerAdapter;
@@ -27,6 +28,7 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
+import org.distorted.scores.RubikScores;
 import org.distorted.scores.RubikScoresDownloader;
 import org.distorted.object.RubikObjectList;
 
@@ -37,6 +39,7 @@ import static org.distorted.uistate.RubikStatePlay.MAX_SCRAMBLE;
 class RubikDialogScoresPagerAdapter extends PagerAdapter implements RubikScoresDownloader.Receiver
   {
   private FragmentActivity mAct;
+  private RubikDialogScores mDialog;
   private RubikDialogScoresView[] mViews;
   private ViewPager mViewPager;
   private int mNumTabs;
@@ -85,7 +88,16 @@ class RubikDialogScoresPagerAdapter extends PagerAdapter implements RubikScoresD
 
     switch(errorNumber)
       {
-      case '2': message("Name Taken");   // TODO
+      case '2': RubikScores scores = RubikScores.getInstance();
+                Bundle bundle = new Bundle();
+                bundle.putString("name", scores.getName() );
+
+                RubikDialogSetName nameDiag = new RubikDialogSetName();
+                nameDiag.setArguments(bundle);
+                nameDiag.show(mAct.getSupportFragmentManager(), null);
+
+                mDialog.dismiss();
+
                 break;
       case '3': message("Server error");
                 break;
@@ -147,9 +159,10 @@ class RubikDialogScoresPagerAdapter extends PagerAdapter implements RubikScoresD
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  RubikDialogScoresPagerAdapter(FragmentActivity act, ViewPager viewPager, boolean isSubmitting)
+  RubikDialogScoresPagerAdapter(FragmentActivity act, ViewPager viewPager, boolean isSubmitting, RubikDialogScores diag)
     {
     mAct = act;
+    mDialog = diag;
     mNumTabs = RubikObjectList.getTotal();
     mViews = new RubikDialogScoresView[mNumTabs];
     mViewPager = viewPager;
diff --git a/src/main/java/org/distorted/dialog/RubikDialogScoresView.java b/src/main/java/org/distorted/dialog/RubikDialogScoresView.java
index 215f817a..22cf5169 100644
--- a/src/main/java/org/distorted/dialog/RubikDialogScoresView.java
+++ b/src/main/java/org/distorted/dialog/RubikDialogScoresView.java
@@ -87,6 +87,7 @@ public class RubikDialogScoresView extends FrameLayout
     float myRecordInSeconds = (myRecordInMillis/100)/10.0f;
     boolean mySubmitted = scores.isSubmitted(object, size, scramble);
     String myName = scores.getName();
+    if( myName.length()==0 ) myName = act.getString(R.string.you);
     int myCountryID = res.getIdentifier( scores.getCountry(), "drawable", packageName);
     String myRecord = ( myRecordInMillis<RubikScores.NO_RECORD ) ? Float.toString(myRecordInSeconds) : "??";
     String theirTime;
diff --git a/src/main/java/org/distorted/dialog/RubikDialogSetName.java b/src/main/java/org/distorted/dialog/RubikDialogSetName.java
new file mode 100644
index 00000000..6136c91f
--- /dev/null
+++ b/src/main/java/org/distorted/dialog/RubikDialogSetName.java
@@ -0,0 +1,129 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2020 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is free software: you can redistribute it and/or modify                            //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Magic Cube is distributed in the hope that it will be useful,                                 //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.dialog;
+
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.FragmentActivity;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatDialogFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import org.distorted.magic.R;
+import org.distorted.magic.RubikActivity;
+import org.distorted.object.RubikObjectList;
+import org.distorted.scores.RubikScores;
+import org.distorted.uistate.RubikState;
+import org.distorted.uistate.RubikStatePlay;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class RubikDialogSetName extends AppCompatDialogFragment
+  {
+  @Override
+  public void onStart()
+    {
+    super.onStart();
+
+    Window window = getDialog().getWindow();
+    window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
+                    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
+    window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  @NonNull
+  @Override
+  public Dialog onCreateDialog(Bundle savedInstanceState)
+    {
+    FragmentActivity act = getActivity();
+    LayoutInflater inflater = act.getLayoutInflater();
+    AlertDialog.Builder builder = new AlertDialog.Builder(act);
+
+    Bundle args = getArguments();
+    String name;
+
+    try
+      {
+      name = args.getString("name");
+      }
+    catch(Exception e)
+      {
+      name = "";
+      }
+
+    boolean first = name.length()==0;
+
+    TextView tv = (TextView) inflater.inflate(R.layout.dialog_title, null);
+    tv.setText( first ? R.string.choose_name : R.string.name_taken);
+    builder.setCustomTitle(tv);
+
+    final View view = inflater.inflate(R.layout.dialog_set_name, null);
+    TextView text = view.findViewById(R.id.set_name_message);
+
+    if( first )
+      {
+      text.setText(R.string.new_name);
+      }
+    else
+      {
+      text.setText(act.getString(R.string.new_name_try_again, name));
+      }
+
+    builder.setCancelable(true);
+    builder.setPositiveButton( R.string.ok, new DialogInterface.OnClickListener()
+      {
+      @Override
+      public void onClick(DialogInterface dialog, int which)
+        {
+        RubikActivity act = (RubikActivity)getActivity();
+        RubikState.switchState(act,RubikState.PLAY);
+
+        EditText edit = view.findViewById(R.id.set_name);
+        String name = edit.getText().toString();
+        RubikScores.getInstance().setName(name);
+
+        RubikStatePlay play = (RubikStatePlay) RubikState.PLAY.getStateClass();
+        int object = play.getObject();
+        int size   = play.getSize();
+
+        Bundle bundle = new Bundle();
+        bundle.putInt("tab", RubikObjectList.pack(object,size) );
+        bundle.putBoolean("submitting", true);
+
+        RubikDialogScores scores = new RubikDialogScores();
+        scores.setArguments(bundle);
+        scores.show(act.getSupportFragmentManager(), null);
+        }
+      });
+
+    builder.setView(view);
+
+    return builder.create();
+    }
+  }
diff --git a/src/main/java/org/distorted/scores/RubikScores.java b/src/main/java/org/distorted/scores/RubikScores.java
index 74623a8e..a178a02f 100644
--- a/src/main/java/org/distorted/scores/RubikScores.java
+++ b/src/main/java/org/distorted/scores/RubikScores.java
@@ -63,7 +63,7 @@ public class RubikScores
           mSubmitted[i][j][k] = 0;
           }
 
-    mName = "YOU";
+    mName = "";
     mCountry = "un";
 
     mNameIsVerified = false;
@@ -251,7 +251,7 @@ public class RubikScores
         }
       }
 
-    mName           = preferences.getString("scores_name"  , "YOU" );
+    mName           = preferences.getString("scores_name"  , "" );
     mNameIsVerified = preferences.getBoolean("scores_isVerified", false);
     mNumPlays       = preferences.getInt("scores_numPlays", 0);
     mNumRuns        = preferences.getInt("scores_numRuns" , 0);
diff --git a/src/main/res/layout/dialog_set_name.xml b/src/main/res/layout/dialog_set_name.xml
new file mode 100644
index 00000000..58e84068
--- /dev/null
+++ b/src/main/res/layout/dialog_set_name.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center_horizontal"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:gravity="center|fill_horizontal"
+        android:layout_marginLeft="10dp"
+        android:layout_marginRight="10dp"
+        android:layout_marginTop="0dp"
+        android:background="@color/grey"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/set_name_message"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center"
+            android:textSize="24sp"
+            android:layout_marginTop="10dp"
+            android:layout_marginLeft="10dp"
+            android:layout_marginRight="10dp"
+            android:layout_marginBottom="10dp"/>
+
+        <EditText
+            android:id="@+id/set_name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 1cb620fb..ff885e4d 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -17,6 +17,7 @@
     <string name="ok">OK</string>
     <string name="yes">YES</string>
     <string name="no">NO</string>
+    <string name="you">YOU</string>
     <string name="ready">Ready?</string>
     <string name="sizechange_effect">Size Change Effect</string>
     <string name="solve_effect">Solve Effect</string>
@@ -24,6 +25,10 @@
     <string name="win_effect">Win Effect</string>
     <string name="duration">Duration:</string>
     <string name="type">Type:</string>
+    <string name="choose_name">Choose a Name</string>
+    <string name="name_taken">Name Taken</string>
+    <string name="new_name">Before your first submit, you need to choose a name:</string>
+    <string name="new_name_try_again">The name you have chosen, %s, is already taken. Try again:</string>
     <string name="downloading">Downloading…</string>
     <string name="submitting">Submitting…</string>
     <string name="credits1">Open Source app developed using the Distorted graphics library. </string>
