commit 45831b78f6f245dad712222667fe00c061412e9b
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Jan 2 15:36:49 2023 +0100

    Purchase Pane: post-purchase dialogs.

diff --git a/src/main/java/org/distorted/dialogs/RubikDialogExplainStars.java b/src/main/java/org/distorted/dialogs/RubikDialogExplainStars.java
deleted file mode 100644
index 8edac461..00000000
--- a/src/main/java/org/distorted/dialogs/RubikDialogExplainStars.java
+++ /dev/null
@@ -1,79 +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.content.DialogInterface;
-import android.os.Bundle;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AppCompatDialogFragment;
-import androidx.fragment.app.FragmentActivity;
-
-import org.distorted.main.R;
-import org.distorted.main.RubikActivity;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class RubikDialogExplainStars extends AppCompatDialogFragment
-  {
-  @NonNull
-  @Override
-  public Dialog onCreateDialog(Bundle savedInstanceState)
-    {
-    FragmentActivity act = getActivity();
-    LayoutInflater inflater = act.getLayoutInflater();
-    AlertDialog.Builder builder = new AlertDialog.Builder(act);
-    DisplayMetrics displaymetrics = new DisplayMetrics();
-    act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
-    final float butSize = displaymetrics.widthPixels * RubikActivity.DIALOG_BUTTON_SIZE;
-    final View view = inflater.inflate(R.layout.dialog_explain_stars, null);
-
-    builder.setCancelable(true);
-
-    builder.setPositiveButton( R.string.ok, new DialogInterface.OnClickListener()
-      {
-      @Override
-      public void onClick(DialogInterface dialog, int which) { }
-      });
-
-    builder.setView(view);
-
-    final Dialog dialog = builder.create();
-    dialog.setCanceledOnTouchOutside(false);
-    Window window = dialog.getWindow();
-
-    if( window!=null )
-      {
-      window.getDecorView().setSystemUiVisibility(RubikActivity.FLAGS);
-      }
-
-    dialog.setOnShowListener(new DialogInterface.OnShowListener()
-      {
-      @Override
-      public void onShow(DialogInterface dialog)
-        {
-        Button btnPositive = ((AlertDialog)dialog).getButton(Dialog.BUTTON_POSITIVE);
-        btnPositive.setTextSize(TypedValue.COMPLEX_UNIT_PX, butSize);
-        Button btnNegative = ((AlertDialog)dialog).getButton(Dialog.BUTTON_NEGATIVE);
-        btnNegative.setTextSize(TypedValue.COMPLEX_UNIT_PX, butSize);
-        }
-      });
-
-    return dialog;
-    }
-  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogStarsError.java b/src/main/java/org/distorted/dialogs/RubikDialogStarsError.java
new file mode 100644
index 00000000..76e8d074
--- /dev/null
+++ b/src/main/java/org/distorted/dialogs/RubikDialogStarsError.java
@@ -0,0 +1,92 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.content.DialogInterface;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatDialogFragment;
+import androidx.fragment.app.FragmentActivity;
+
+import org.distorted.main.R;
+import org.distorted.main.RubikActivity;
+import org.distorted.purchase.PurchaseScreenPane;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class RubikDialogStarsError extends AppCompatDialogFragment
+  {
+  @NonNull
+  @Override
+  public Dialog onCreateDialog(Bundle savedInstanceState)
+    {
+    FragmentActivity act = getActivity();
+    LayoutInflater inflater = act.getLayoutInflater();
+    AlertDialog.Builder builder = new AlertDialog.Builder(act);
+    DisplayMetrics displaymetrics = new DisplayMetrics();
+    act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
+    final float butSize = displaymetrics.widthPixels * RubikActivity.DIALOG_BUTTON_SIZE;
+    final View view = inflater.inflate(R.layout.dialog_explain_stars, null);
+
+    Bundle args = getArguments();
+    long price;
+
+    try
+      {
+      price = args.getInt("price");
+      }
+    catch(Exception e)
+      {
+      price = PurchaseScreenPane.UNLOCK_ALL_PRICE;
+      }
+
+    builder.setCancelable(true);
+
+    builder.setPositiveButton( R.string.ok, new DialogInterface.OnClickListener()
+      {
+      @Override
+      public void onClick(DialogInterface dialog, int which) { }
+      });
+
+    builder.setView(view);
+
+    final Dialog dialog = builder.create();
+    dialog.setCanceledOnTouchOutside(false);
+    Window window = dialog.getWindow();
+
+    if( window!=null )
+      {
+      window.getDecorView().setSystemUiVisibility(RubikActivity.FLAGS);
+      }
+
+    dialog.setOnShowListener(new DialogInterface.OnShowListener()
+      {
+      @Override
+      public void onShow(DialogInterface dialog)
+        {
+        Button btnPositive = ((AlertDialog)dialog).getButton(Dialog.BUTTON_POSITIVE);
+        btnPositive.setTextSize(TypedValue.COMPLEX_UNIT_PX, butSize);
+        Button btnNegative = ((AlertDialog)dialog).getButton(Dialog.BUTTON_NEGATIVE);
+        btnNegative.setTextSize(TypedValue.COMPLEX_UNIT_PX, butSize);
+        }
+      });
+
+    return dialog;
+    }
+  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogStarsExplain.java b/src/main/java/org/distorted/dialogs/RubikDialogStarsExplain.java
new file mode 100644
index 00000000..48231c23
--- /dev/null
+++ b/src/main/java/org/distorted/dialogs/RubikDialogStarsExplain.java
@@ -0,0 +1,79 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.content.DialogInterface;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatDialogFragment;
+import androidx.fragment.app.FragmentActivity;
+
+import org.distorted.main.R;
+import org.distorted.main.RubikActivity;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class RubikDialogStarsExplain extends AppCompatDialogFragment
+  {
+  @NonNull
+  @Override
+  public Dialog onCreateDialog(Bundle savedInstanceState)
+    {
+    FragmentActivity act = getActivity();
+    LayoutInflater inflater = act.getLayoutInflater();
+    AlertDialog.Builder builder = new AlertDialog.Builder(act);
+    DisplayMetrics displaymetrics = new DisplayMetrics();
+    act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
+    final float butSize = displaymetrics.widthPixels * RubikActivity.DIALOG_BUTTON_SIZE;
+    final View view = inflater.inflate(R.layout.dialog_explain_stars, null);
+
+    builder.setCancelable(true);
+
+    builder.setPositiveButton( R.string.ok, new DialogInterface.OnClickListener()
+      {
+      @Override
+      public void onClick(DialogInterface dialog, int which) { }
+      });
+
+    builder.setView(view);
+
+    final Dialog dialog = builder.create();
+    dialog.setCanceledOnTouchOutside(false);
+    Window window = dialog.getWindow();
+
+    if( window!=null )
+      {
+      window.getDecorView().setSystemUiVisibility(RubikActivity.FLAGS);
+      }
+
+    dialog.setOnShowListener(new DialogInterface.OnShowListener()
+      {
+      @Override
+      public void onShow(DialogInterface dialog)
+        {
+        Button btnPositive = ((AlertDialog)dialog).getButton(Dialog.BUTTON_POSITIVE);
+        btnPositive.setTextSize(TypedValue.COMPLEX_UNIT_PX, butSize);
+        Button btnNegative = ((AlertDialog)dialog).getButton(Dialog.BUTTON_NEGATIVE);
+        btnNegative.setTextSize(TypedValue.COMPLEX_UNIT_PX, butSize);
+        }
+      });
+
+    return dialog;
+    }
+  }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogStarsSuccess.java b/src/main/java/org/distorted/dialogs/RubikDialogStarsSuccess.java
new file mode 100644
index 00000000..d41329d2
--- /dev/null
+++ b/src/main/java/org/distorted/dialogs/RubikDialogStarsSuccess.java
@@ -0,0 +1,92 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.content.DialogInterface;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatDialogFragment;
+import androidx.fragment.app.FragmentActivity;
+
+import org.distorted.main.R;
+import org.distorted.main.RubikActivity;
+import org.distorted.purchase.PurchaseScreenPane;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class RubikDialogStarsSuccess extends AppCompatDialogFragment
+  {
+  @NonNull
+  @Override
+  public Dialog onCreateDialog(Bundle savedInstanceState)
+    {
+    FragmentActivity act = getActivity();
+    LayoutInflater inflater = act.getLayoutInflater();
+    AlertDialog.Builder builder = new AlertDialog.Builder(act);
+    DisplayMetrics displaymetrics = new DisplayMetrics();
+    act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
+    final float butSize = displaymetrics.widthPixels * RubikActivity.DIALOG_BUTTON_SIZE;
+    final View view = inflater.inflate(R.layout.dialog_explain_stars, null);
+
+    Bundle args = getArguments();
+    String objectName;
+
+    try
+      {
+      objectName = args.getString("object");
+      }
+    catch(Exception e)
+      {
+      objectName = null;
+      }
+
+    builder.setCancelable(true);
+
+    builder.setPositiveButton( R.string.ok, new DialogInterface.OnClickListener()
+      {
+      @Override
+      public void onClick(DialogInterface dialog, int which) { }
+      });
+
+    builder.setView(view);
+
+    final Dialog dialog = builder.create();
+    dialog.setCanceledOnTouchOutside(false);
+    Window window = dialog.getWindow();
+
+    if( window!=null )
+      {
+      window.getDecorView().setSystemUiVisibility(RubikActivity.FLAGS);
+      }
+
+    dialog.setOnShowListener(new DialogInterface.OnShowListener()
+      {
+      @Override
+      public void onShow(DialogInterface dialog)
+        {
+        Button btnPositive = ((AlertDialog)dialog).getButton(Dialog.BUTTON_POSITIVE);
+        btnPositive.setTextSize(TypedValue.COMPLEX_UNIT_PX, butSize);
+        Button btnNegative = ((AlertDialog)dialog).getButton(Dialog.BUTTON_NEGATIVE);
+        btnNegative.setTextSize(TypedValue.COMPLEX_UNIT_PX, butSize);
+        }
+      });
+
+    return dialog;
+    }
+  }
diff --git a/src/main/java/org/distorted/main/RubikActivity.java b/src/main/java/org/distorted/main/RubikActivity.java
index 98e8fef3..4fcff8c4 100644
--- a/src/main/java/org/distorted/main/RubikActivity.java
+++ b/src/main/java/org/distorted/main/RubikActivity.java
@@ -35,7 +35,7 @@ import com.google.firebase.inappmessaging.FirebaseInAppMessaging;
 
 import org.distorted.config.ConfigActivity;
 import org.distorted.bandaged.BandagedCreatorActivity;
-import org.distorted.dialogs.RubikDialogExplainStars;
+import org.distorted.dialogs.RubikDialogStarsExplain;
 import org.distorted.library.main.DistortedLibrary;
 
 import org.distorted.library.main.DistortedScreen;
@@ -304,7 +304,7 @@ public class RubikActivity extends AppCompatActivity
 
     private void explainStars()
       {
-      RubikDialogExplainStars staDiag = new RubikDialogExplainStars();
+      RubikDialogStarsExplain staDiag = new RubikDialogStarsExplain();
       staDiag.show(getSupportFragmentManager(), null);
       }
 
diff --git a/src/main/java/org/distorted/purchase/PurchaseScreenPane.java b/src/main/java/org/distorted/purchase/PurchaseScreenPane.java
index 0a95df45..de4f659a 100644
--- a/src/main/java/org/distorted/purchase/PurchaseScreenPane.java
+++ b/src/main/java/org/distorted/purchase/PurchaseScreenPane.java
@@ -10,6 +10,7 @@
 package org.distorted.purchase;
 
 import android.graphics.drawable.Drawable;
+import android.os.Bundle;
 import android.util.TypedValue;
 import android.view.View;
 import android.widget.ImageButton;
@@ -19,6 +20,8 @@ import android.widget.TextView;
 
 import androidx.core.content.res.ResourcesCompat;
 
+import org.distorted.dialogs.RubikDialogStarsError;
+import org.distorted.external.RubikScores;
 import org.distorted.main.R;
 import org.distorted.objectlib.json.JsonReader;
 import org.distorted.objects.RubikObject;
@@ -30,7 +33,7 @@ import java.io.InputStream;
 
 public class PurchaseScreenPane
 {
-  private static final int UNLOCK_ALL_PRICE = 500;
+  public static final int UNLOCK_ALL_PRICE = 500;
 
   private static final int[] IMAGES =
     {
@@ -48,42 +51,77 @@ public class PurchaseScreenPane
   private RubikObject mObject;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO: charge the user an amount of stars
 
-  private boolean chargeUser(RubikObject object)
+  private boolean chargeUser(int amount)
     {
-    return true;
+    RubikScores scores = RubikScores.getInstance();
+    int numStars = scores.getNumStars();
+
+    if( numStars>=amount )
+      {
+      scores.changeNumStars(-amount);
+      return true;
+      }
+
+    return false;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO: charge the user an amount of stars
 
-  private boolean chargeUser()
+  private void showError(PurchaseActivity act, int price)
     {
-    return true;
+    Bundle bundle = new Bundle();
+    bundle.putInt("price", price );
+    RubikDialogStarsError d = new RubikDialogStarsError();
+    d.setArguments(bundle);
+    d.show(act.getSupportFragmentManager(), null);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void oneButtonClicked()
+  private void showSuccess(PurchaseActivity act, RubikObject object)
+    {
+    Bundle bundle = new Bundle();
+    bundle.putString("object", object.getUpperName() );
+    RubikDialogStarsError d = new RubikDialogStarsError();
+    d.setArguments(bundle);
+    d.show(act.getSupportFragmentManager(), null);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void oneButtonClicked(PurchaseActivity act)
     {
     if( mObject!=null )
       {
-      if( !RubikObjectList.objectAlreadyBought(mObject) && chargeUser(mObject) )
+      int price = mObject.getPrice();
+
+      if( chargeUser(price) )
         {
-        android.util.Log.e("D", "buying "+mObject.getUpperName());
         RubikObjectList.buyObject(mObject);
+        showSuccess(act,mObject);
+        }
+      else
+        {
+        showError(act,price);
         }
       }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void allButtonClicked()
+  private void allButtonClicked(PurchaseActivity act)
     {
-    if( !RubikObjectList.allAlreadyBought() && chargeUser() )
+    int price = UNLOCK_ALL_PRICE;
+
+    if( chargeUser(price) )
       {
       RubikObjectList.buyAll();
+      showSuccess(act,null);
+      }
+    else
+      {
+      showError(act,price);
       }
     }
 
@@ -115,7 +153,7 @@ public class PurchaseScreenPane
       @Override
       public void onClick(View v)
         {
-        oneButtonClicked();
+        oneButtonClicked(act);
         }
       });
 
@@ -124,7 +162,7 @@ public class PurchaseScreenPane
       @Override
       public void onClick(View v)
         {
-        allButtonClicked();
+        allButtonClicked(act);
         }
       });
     }
