commit b710a57497968786846a4e698e1718e4319e7dfe
Author: leszek <leszek@koltunski.pl>
Date:   Fri Nov 10 16:15:40 2023 +0100

    Progress with tutorials.

diff --git a/src/main/java/org/distorted/dialogs/RubikDialogTutorial.java b/src/main/java/org/distorted/dialogs/RubikDialogTutorial.java
index 728536b9..e0e1d491 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogTutorial.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogTutorial.java
@@ -59,20 +59,8 @@ public class RubikDialogTutorial extends RubikDialogAbstract
   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 positiveAction()  { }
+  public void negativeAction()  { }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogTutorialSingle.java b/src/main/java/org/distorted/dialogs/RubikDialogTutorialSingle.java
new file mode 100644
index 00000000..3c75ce96
--- /dev/null
+++ b/src/main/java/org/distorted/dialogs/RubikDialogTutorialSingle.java
@@ -0,0 +1,191 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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 static android.view.View.inflate;
+
+import android.app.Dialog;
+import android.content.res.Resources;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.fragment.app.FragmentActivity;
+
+import org.distorted.main.R;
+import org.distorted.objectlib.json.JsonReader;
+import org.distorted.objects.RubikObject;
+import org.distorted.objects.RubikObjectList;
+import org.distorted.tutorials.TutorialActivity;
+
+import java.io.InputStream;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class RubikDialogTutorialSingle extends RubikDialogAbstract
+  {
+  public static final float PANE_HEIGHT  = 0.06f;
+  private Dialog mDialog;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  @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_tutorial_single; }
+  public int getTitleResource() { return R.string.tutorials; }
+  public boolean hasArgument()  { return true; }
+  public int getPositive()      { return -1; }
+  public int getNegative()      { return -1; }
+  public void positiveAction()  { }
+  public void negativeAction()  { }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void prepareBody(Dialog dialog, View view, FragmentActivity act, float size)
+    {
+    mDialog = dialog;
+
+    int objectOrdinal = RubikObjectList.getOrdinal(mArgument);
+
+    android.util.Log.e("D", "dialog tutorial: object "+mArgument);
+
+    if( objectOrdinal<0 )
+      {
+      android.util.Log.e("D", "object "+mArgument+" not found");
+      return;
+      }
+    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 )
+      {
+      int paneSize = (int)(mHeight*PANE_HEIGHT);
+      Resources res = act.getResources();
+      String packageName = act.getPackageName();
+
+      LinearLayout layout = view.findViewById(R.id.tutLayout);
+
+      int colorB = getResources().getColor(R.color.light_grey);
+      int colorT = getResources().getColor(R.color.white);
+
+      int numTuts = tutorials.length;
+
+      for( int t=0; t<numTuts; t++)
+        {
+        String[] tutorial = tutorials[t];
+
+        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(act, countryID, desc, url, auth, paneSize, colorB, colorT, t==(numTuts-1) );
+        layout.addView(row);
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private View createRow(final FragmentActivity act, int countryID, final String desc, final String url,
+                         final String auth, int size, int colorB, int colorT, boolean last)
+    {
+    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);
+
+    final TutorialActivity tact = (TutorialActivity)getContext();
+
+    butt.setOnClickListener( new View.OnClickListener()
+      {
+      @Override
+      public void onClick(View v)
+        {
+        mDialog.dismiss();
+        if( tact!=null ) tact.loadTutorial(url);
+        }
+      });
+
+    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);
+
+    if( last )
+      {
+      int m = 20;
+      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
+      params.bottomMargin = m;
+      params.leftMargin   = m;
+      params.rightMargin  = m;
+      layout.setLayoutParams(params);
+      }
+
+    return row;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static String getDialogTag()
+    {
+    return "DialogTutorialSingle";
+    }
+  }
diff --git a/src/main/java/org/distorted/main/MainActivity.java b/src/main/java/org/distorted/main/MainActivity.java
index e7ee7b30..0bae410d 100644
--- a/src/main/java/org/distorted/main/MainActivity.java
+++ b/src/main/java/org/distorted/main/MainActivity.java
@@ -359,10 +359,9 @@ public class MainActivity extends AppCompatActivity implements RubikNetwork.Upda
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void switchToTutorial(String url, int objectOrdinal)
+    public void switchToTutorial(int objectOrdinal)
       {
       Intent intent = new Intent(this, TutorialActivity.class);
-      intent.putExtra("url", url);
       intent.putExtra("obj", objectOrdinal);
       startActivity(intent);
       }
diff --git a/src/main/java/org/distorted/main/MainObjectPopup.java b/src/main/java/org/distorted/main/MainObjectPopup.java
index ffd3ce4d..828c13ce 100644
--- a/src/main/java/org/distorted/main/MainObjectPopup.java
+++ b/src/main/java/org/distorted/main/MainObjectPopup.java
@@ -111,7 +111,8 @@ public class MainObjectPopup
         @Override
         public void onClick(View v)
           {
-
+          mPopup.dismiss();
+          act.switchToTutorial(ordinal);
           }
         });
       }
diff --git a/src/main/java/org/distorted/tutorials/TutorialActivity.java b/src/main/java/org/distorted/tutorials/TutorialActivity.java
index 7d36d38a..973f2dd3 100644
--- a/src/main/java/org/distorted/tutorials/TutorialActivity.java
+++ b/src/main/java/org/distorted/tutorials/TutorialActivity.java
@@ -11,7 +11,6 @@ package org.distorted.tutorials;
 
 import java.io.InputStream;
 
-import android.content.Intent;
 import android.os.Build;
 import android.os.Bundle;
 import android.util.DisplayMetrics;
@@ -23,9 +22,10 @@ import android.widget.LinearLayout;
 
 import androidx.appcompat.app.AppCompatActivity;
 
+import org.distorted.dialogs.RubikDialogTutorialSingle;
 import org.distorted.library.main.DistortedLibrary;
 
-import org.distorted.main_old.RubikActivity;
+import org.distorted.main.MainActivity;
 import org.distorted.objectlib.main.InitAssets;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.TwistyObject;
@@ -35,7 +35,6 @@ import org.distorted.dialogs.RubikDialogError;
 import org.distorted.objects.RubikObject;
 import org.distorted.objects.RubikObjectList;
 import org.distorted.os.OSInterface;
-import org.distorted.purchase.PurchaseActivity;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -44,12 +43,11 @@ public class TutorialActivity extends AppCompatActivity
     private static final String URL = "https://www.youtube.com/embed/";
     private static final int ACTIVITY_NUMBER = 1;
     public static final float BAR_RATIO = 0.17f;
-    public static final int FLAGS = RubikActivity.FLAGS;
+    public static final int FLAGS = MainActivity.FLAGS;
 
     private static int mScreenWidth, mScreenHeight;
     private int mCurrentApiVersion;
     private TutorialScreen mScreen;
-    private String mURL;
     private int mObjectOrdinal;
     private TutorialWebView mWebView;
     private boolean mIsFree;
@@ -70,7 +68,6 @@ public class TutorialActivity extends AppCompatActivity
 
       if(b != null)
         {
-        mURL           = b.getString("url");
         mObjectOrdinal = b.getInt("obj");
         RubikObject obj= RubikObjectList.getObject(mObjectOrdinal);
         mIsFree = (obj!=null && obj.isFree());
@@ -83,6 +80,19 @@ public class TutorialActivity extends AppCompatActivity
 
       hideNavigationBar();
       cutoutHack();
+      showDialog();
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void showDialog()
+      {
+      RubikObjectList.setCurrObject(mObjectOrdinal);
+      Bundle bundle = new Bundle();
+      bundle.putString("argument",RubikObjectList.getCurrentName());
+      RubikDialogTutorialSingle diag = new RubikDialogTutorialSingle();
+      diag.setArguments(bundle);
+      diag.show( getSupportFragmentManager(), RubikDialogTutorialSingle.getDialogTag() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -113,16 +123,13 @@ public class TutorialActivity extends AppCompatActivity
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    @Override
-    public void onAttachedToWindow()
+    public void loadTutorial(String url)
       {
-      super.onAttachedToWindow();
-
       if( mWebView==null )
         {
         WebView videoView = findViewById(R.id.tutorialVideoView);
         mWebView = new TutorialWebView(videoView);
-        mWebView.load(URL+mURL);
+        mWebView.load(URL+url);
         }
       }
 
@@ -262,13 +269,4 @@ public class TutorialActivity extends AppCompatActivity
       TutorialSurfaceView view = findViewById(R.id.tutorialSurfaceView);
       return view.getObjectControl();
       }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void switchToPurchase()
-      {
-      Intent intent = new Intent(this, PurchaseActivity.class);
-      intent.putExtra("obj", mObjectOrdinal);
-      startActivity(intent);
-      }
 }
diff --git a/src/main/java/org/distorted/tutorials/TutorialScreen.java b/src/main/java/org/distorted/tutorials/TutorialScreen.java
index ce962fdd..0f017935 100644
--- a/src/main/java/org/distorted/tutorials/TutorialScreen.java
+++ b/src/main/java/org/distorted/tutorials/TutorialScreen.java
@@ -42,7 +42,7 @@ public class TutorialScreen
       @Override
       public void onClick(View v)
         {
-        act.switchToPurchase();
+        //act.switchToPurchase();
         }
       });
     }
diff --git a/src/main/res/layout/dialog_tutorial_single.xml b/src/main/res/layout/dialog_tutorial_single.xml
new file mode 100644
index 00000000..784e212c
--- /dev/null
+++ b/src/main/res/layout/dialog_tutorial_single.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/tutScrollView"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:id="@+id/tutLayout"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
+    </LinearLayout>
+
+</ScrollView>
