From c761287a8a3b46ea5c066bb7f9ea3c50b4dc2595 Mon Sep 17 00:00:00 2001
From: str4d <str4d@mail.i2p>
Date: Mon, 26 Aug 2013 01:23:00 +0000
Subject: [PATCH] Added support for complex branching with Conditionals

---
 .../i2p/android/wizard/model/Conditional.java | 54 +++++++++++++++
 src/net/i2p/android/wizard/model/Page.java    | 65 ++++++++++++++++++-
 2 files changed, 117 insertions(+), 2 deletions(-)
 create mode 100644 src/net/i2p/android/wizard/model/Conditional.java

diff --git a/src/net/i2p/android/wizard/model/Conditional.java b/src/net/i2p/android/wizard/model/Conditional.java
new file mode 100644
index 000000000..0458c2b83
--- /dev/null
+++ b/src/net/i2p/android/wizard/model/Conditional.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2013 str4d
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.i2p.android.wizard.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Conditional implements ModelCallbacks {
+    private Object mData = null;
+    private List<Page> mConditionalPages = new ArrayList<Page>();
+
+    public void onPageDataChanged(Page page) {
+        mData = page.getData().get(Page.SIMPLE_DATA_KEY);
+        for (Page p : mConditionalPages)
+            p.isSatisfied();
+    }
+
+    public void onPageTreeChanged() {
+    }
+
+    public interface Condition {
+        public boolean isSatisfied();
+    }
+
+    public class EqualCondition<T> implements Condition {
+        private T mCompValue;
+
+        public EqualCondition(Page page, T compValue) {
+            mCompValue = compValue;
+            mConditionalPages.add(page);
+        }
+
+        public boolean isSatisfied() {
+            // If we have no data from the conditional,
+            // assume that the page will be shown.
+            if (mData == null) return true;
+            return mCompValue.equals(mData);
+        }
+    }
+}
diff --git a/src/net/i2p/android/wizard/model/Page.java b/src/net/i2p/android/wizard/model/Page.java
index 0135f3312..01d7e60c9 100644
--- a/src/net/i2p/android/wizard/model/Page.java
+++ b/src/net/i2p/android/wizard/model/Page.java
@@ -21,6 +21,7 @@ import android.os.Bundle;
 import android.support.v4.app.Fragment;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Represents a single page in the wizard.
@@ -33,6 +34,24 @@ public abstract class Page implements PageTreeNode {
 
     protected ModelCallbacks mCallbacks;
 
+    /**
+     * Conditionals that rely on this page.
+     */
+    protected List<ModelCallbacks> mConditionals = new ArrayList<ModelCallbacks>();
+
+    /**
+     * Conditions on whether this page should be used.
+     */
+    protected List<Conditional.Condition> mConditions = new ArrayList<Conditional.Condition>();
+    /**
+     * Should all conditions be satisfied, or any of them?
+     */
+    protected boolean mConditionAnd = false;
+    /**
+     * The last condition status.
+     */
+    protected boolean mSatisfied = true;
+
     /**
      * Current wizard values/selections.
      */
@@ -54,8 +73,30 @@ public abstract class Page implements PageTreeNode {
         return mTitle;
     }
 
+    public boolean isSatisfied() {
+        boolean ret = true;
+        if (mConditions.size() > 0) {
+            ret = false;
+            for (Conditional.Condition c : mConditions) {
+                if (c.isSatisfied()) {
+                    ret = true;
+                    if (!mConditionAnd) break;
+                } else if (mConditionAnd) {
+                    ret = false;
+                    break;
+                }
+            }
+        }
+        // If the conditions have changed, update the page tree.
+        if (!(mSatisfied == ret)) {
+            mSatisfied = ret;
+            mCallbacks.onPageTreeChanged();
+        }
+        return mSatisfied;
+    }
+
     public boolean isRequired() {
-        return mRequired;
+        return isSatisfied() && mRequired;
     }
 
     void setParentKey(String parentKey) {
@@ -67,7 +108,8 @@ public abstract class Page implements PageTreeNode {
     }
 
     public void flattenCurrentPageSequence(ArrayList<Page> dest) {
-        dest.add(this);
+        if (isSatisfied())
+            dest.add(this);
     }
 
     public abstract Fragment createFragment();
@@ -88,6 +130,9 @@ public abstract class Page implements PageTreeNode {
     }
 
     public void notifyDataChanged() {
+        for (ModelCallbacks c : mConditionals) {
+            c.onPageDataChanged(this);
+        }
         mCallbacks.onPageDataChanged(this);
     }
 
@@ -95,4 +140,20 @@ public abstract class Page implements PageTreeNode {
         mRequired = required;
         return this;
     }
+
+    public Page makeConditional(Conditional conditional) {
+        mConditionals.add(conditional);
+        return this;
+    }
+
+    public <T> Page setEqualCondition(Conditional conditional, T comp) {
+        Conditional.Condition c = conditional.new EqualCondition<T>(this, comp);
+        mConditions.add(c);
+        return this;
+    }
+
+    public Page satisfyAllConditions(boolean conditionAnd) {
+        mConditionAnd = conditionAnd;
+        return this;
+    }
 }
-- 
GitLab