]> matita.cs.unibo.it Git - logicplayer.git/commitdiff
The applet.
authorClaudio Sacerdoti Coen <claudio@zenone.casamia.org>
Tue, 9 Dec 2014 13:24:27 +0000 (14:24 +0100)
committerClaudio Sacerdoti Coen <claudio@zenone.casamia.org>
Tue, 9 Dec 2014 13:24:27 +0000 (14:24 +0100)
112 files changed:
mainActivity/._AndroidManifest.xml [new file with mode: 0755]
mainActivity/.classpath [new file with mode: 0644]
mainActivity/.project [new file with mode: 0644]
mainActivity/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
mainActivity/AndroidManifest.xml [new file with mode: 0755]
mainActivity/bin/AndroidManifest.xml [new file with mode: 0644]
mainActivity/bin/classes.dex [new file with mode: 0644]
mainActivity/bin/dexedLibs/android-support-v4-70fb0600066156aa2b6d08c87cc768e7.jar [new file with mode: 0644]
mainActivity/bin/mainActivity.apk [new file with mode: 0644]
mainActivity/bin/res/crunch/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
mainActivity/bin/res/crunch/drawable-mdpi/ic_launcher.png [new file with mode: 0644]
mainActivity/bin/res/crunch/drawable-xhdpi/ic_launcher.png [new file with mode: 0644]
mainActivity/bin/res/crunch/drawable-xxhdpi/ic_launcher.png [new file with mode: 0644]
mainActivity/bin/resources.ap_ [new file with mode: 0644]
mainActivity/libs/android-support-v4.jar [new file with mode: 0644]
mainActivity/lint.xml [new file with mode: 0644]
mainActivity/project.properties [new file with mode: 0644]
mainActivity/res/._drawable-hdpi [new file with mode: 0755]
mainActivity/res/._drawable-mdpi [new file with mode: 0755]
mainActivity/res/._drawable-xxhdpi [new file with mode: 0755]
mainActivity/res/._values [new file with mode: 0755]
mainActivity/res/drawable-hdpi/._ic_launcher.png [new file with mode: 0755]
mainActivity/res/drawable-hdpi/def.jpg [new file with mode: 0644]
mainActivity/res/drawable-hdpi/ic_launcher.png [new file with mode: 0755]
mainActivity/res/drawable-mdpi/._ic_launcher.png [new file with mode: 0755]
mainActivity/res/drawable-mdpi/def.jpg [new file with mode: 0644]
mainActivity/res/drawable-mdpi/ic_launcher.png [new file with mode: 0755]
mainActivity/res/drawable-xhdpi/._ic_launcher.png [new file with mode: 0755]
mainActivity/res/drawable-xhdpi/def.jpg [new file with mode: 0644]
mainActivity/res/drawable-xhdpi/ic_launcher.png [new file with mode: 0755]
mainActivity/res/drawable-xxhdpi/._ic_launcher.png [new file with mode: 0755]
mainActivity/res/drawable-xxhdpi/def.jpg [new file with mode: 0644]
mainActivity/res/drawable-xxhdpi/ic_launcher.png [new file with mode: 0755]
mainActivity/res/layout-land/download.xml [new file with mode: 0755]
mainActivity/res/layout/.activity_my.xml.swp [new file with mode: 0644]
mainActivity/res/layout/activity_login.xml [new file with mode: 0755]
mainActivity/res/layout/activity_my.xml [new file with mode: 0755]
mainActivity/res/layout/aggiornamento.xml [new file with mode: 0755]
mainActivity/res/layout/download.xml [new file with mode: 0755]
mainActivity/res/layout/reimpostapass.xml [new file with mode: 0644]
mainActivity/res/layout/ruledialog.xml [new file with mode: 0755]
mainActivity/res/layout/string_layout.xml [new file with mode: 0755]
mainActivity/res/layout/textviewgeneral.xml [new file with mode: 0644]
mainActivity/res/menu/._my.xml [new file with mode: 0755]
mainActivity/res/menu/login_set.xml [new file with mode: 0755]
mainActivity/res/menu/menu_dow.xml [new file with mode: 0755]
mainActivity/res/menu/my.xml [new file with mode: 0755]
mainActivity/res/raw/._halloween.crt [new file with mode: 0755]
mainActivity/res/raw/._keystore.bks [new file with mode: 0755]
mainActivity/res/raw/halloween.crt [new file with mode: 0755]
mainActivity/res/raw/keystore.bks [new file with mode: 0755]
mainActivity/res/values-w820dp/._dimens.xml [new file with mode: 0755]
mainActivity/res/values-w820dp/dimens.xml [new file with mode: 0755]
mainActivity/res/values/._dimens.xml [new file with mode: 0755]
mainActivity/res/values/._strings.xml [new file with mode: 0755]
mainActivity/res/values/._styles.xml [new file with mode: 0755]
mainActivity/res/values/dimens.xml [new file with mode: 0755]
mainActivity/res/values/strings.xml [new file with mode: 0755]
mainActivity/res/values/styles.xml [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/Border.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/BorderedTextView.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/CopyPasteDialog.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/DialogTouchHandler.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/DrawActivity.java [new file with mode: 0644]
mainActivity/src/com/example/furt/myapplication/EliminationRule.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/FView.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/Formula.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/FormulaAnd.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/FormulaBOT.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/FormulaImpl.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/FormulaNot.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/FormulaOr.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/FormulaTOP.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/GenericFormula.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/Hypothesis.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/IntroductionRule.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/Literal.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/LongHPClick.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/MD5.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/MyService.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/Node.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/RuleAndElimination.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/RuleBotElimination.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/RuleDialog.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/RuleImplElimination.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/RuleIntroduction.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/RuleNotElimination.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/RuleOrElimination.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/ServerData.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/Tree.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/TwoDScrollView.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/UndefinedFormula.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/aggiorna.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/aggiornamento.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/askFormula.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/download_page.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/global.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/listElem.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/mainActivity.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/operandClick.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/parser.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/parserDialog.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/personalDBHelper.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/personalTrackerContract.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/recuperaPass.java [new file with mode: 0644]
mainActivity/src/com/example/furt/myapplication/serverComunication.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/suString.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/touchHPHandler.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/touchParserHandler.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/touchRuleHandler.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/touchnodeHandler.java [new file with mode: 0755]
mainActivity/src/com/example/furt/myapplication/valutazione.java [new file with mode: 0644]

diff --git a/mainActivity/._AndroidManifest.xml b/mainActivity/._AndroidManifest.xml
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/._AndroidManifest.xml differ
diff --git a/mainActivity/.classpath b/mainActivity/.classpath
new file mode 100644 (file)
index 0000000..5176974
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="src" path="gen"/>
+       <classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/mainActivity/.project b/mainActivity/.project
new file mode 100644 (file)
index 0000000..53dc2e1
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>mainActivity</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/mainActivity/.settings/org.eclipse.jdt.core.prefs b/mainActivity/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..7341ab1
--- /dev/null
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/mainActivity/AndroidManifest.xml b/mainActivity/AndroidManifest.xml
new file mode 100755 (executable)
index 0000000..1e93667
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.furt.myapplication" >
+    <uses-sdk
+        android:minSdkVersion="19"
+        android:targetSdkVersion="19" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/def"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".mainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".DrawActivity"
+            android:label="@string/app_name"
+            android:configChanges="orientation|screenSize">
+
+        </activity>
+        <service
+            android:name=".MyService"
+            android:exported="false"/>
+        <activity
+            android:name=".download_page"
+            android:label="@string/listEs" >
+        </activity>
+        <activity
+            android:name=".aggiornamento"
+            android:label="@string/app_name" >
+        </activity>
+        <activity
+            android:name=".recuperaPass"
+            android:label="@string/app_name" >
+        </activity>
+    </application>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+</manifest>
diff --git a/mainActivity/bin/AndroidManifest.xml b/mainActivity/bin/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..1e93667
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.furt.myapplication" >
+    <uses-sdk
+        android:minSdkVersion="19"
+        android:targetSdkVersion="19" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/def"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".mainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".DrawActivity"
+            android:label="@string/app_name"
+            android:configChanges="orientation|screenSize">
+
+        </activity>
+        <service
+            android:name=".MyService"
+            android:exported="false"/>
+        <activity
+            android:name=".download_page"
+            android:label="@string/listEs" >
+        </activity>
+        <activity
+            android:name=".aggiornamento"
+            android:label="@string/app_name" >
+        </activity>
+        <activity
+            android:name=".recuperaPass"
+            android:label="@string/app_name" >
+        </activity>
+    </application>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+</manifest>
diff --git a/mainActivity/bin/classes.dex b/mainActivity/bin/classes.dex
new file mode 100644 (file)
index 0000000..6c65325
Binary files /dev/null and b/mainActivity/bin/classes.dex differ
diff --git a/mainActivity/bin/dexedLibs/android-support-v4-70fb0600066156aa2b6d08c87cc768e7.jar b/mainActivity/bin/dexedLibs/android-support-v4-70fb0600066156aa2b6d08c87cc768e7.jar
new file mode 100644 (file)
index 0000000..03919cb
Binary files /dev/null and b/mainActivity/bin/dexedLibs/android-support-v4-70fb0600066156aa2b6d08c87cc768e7.jar differ
diff --git a/mainActivity/bin/mainActivity.apk b/mainActivity/bin/mainActivity.apk
new file mode 100644 (file)
index 0000000..d3f871c
Binary files /dev/null and b/mainActivity/bin/mainActivity.apk differ
diff --git a/mainActivity/bin/res/crunch/drawable-hdpi/ic_launcher.png b/mainActivity/bin/res/crunch/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..bcfa058
Binary files /dev/null and b/mainActivity/bin/res/crunch/drawable-hdpi/ic_launcher.png differ
diff --git a/mainActivity/bin/res/crunch/drawable-mdpi/ic_launcher.png b/mainActivity/bin/res/crunch/drawable-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..85848ff
Binary files /dev/null and b/mainActivity/bin/res/crunch/drawable-mdpi/ic_launcher.png differ
diff --git a/mainActivity/bin/res/crunch/drawable-xhdpi/ic_launcher.png b/mainActivity/bin/res/crunch/drawable-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..916901e
Binary files /dev/null and b/mainActivity/bin/res/crunch/drawable-xhdpi/ic_launcher.png differ
diff --git a/mainActivity/bin/res/crunch/drawable-xxhdpi/ic_launcher.png b/mainActivity/bin/res/crunch/drawable-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..b36186f
Binary files /dev/null and b/mainActivity/bin/res/crunch/drawable-xxhdpi/ic_launcher.png differ
diff --git a/mainActivity/bin/resources.ap_ b/mainActivity/bin/resources.ap_
new file mode 100644 (file)
index 0000000..15a9ba0
Binary files /dev/null and b/mainActivity/bin/resources.ap_ differ
diff --git a/mainActivity/libs/android-support-v4.jar b/mainActivity/libs/android-support-v4.jar
new file mode 100644 (file)
index 0000000..a7e9919
Binary files /dev/null and b/mainActivity/libs/android-support-v4.jar differ
diff --git a/mainActivity/lint.xml b/mainActivity/lint.xml
new file mode 100644 (file)
index 0000000..ee0eead
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+</lint>
\ No newline at end of file
diff --git a/mainActivity/project.properties b/mainActivity/project.properties
new file mode 100644 (file)
index 0000000..4ab1256
--- /dev/null
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-19
diff --git a/mainActivity/res/._drawable-hdpi b/mainActivity/res/._drawable-hdpi
new file mode 100755 (executable)
index 0000000..2f4e437
Binary files /dev/null and b/mainActivity/res/._drawable-hdpi differ
diff --git a/mainActivity/res/._drawable-mdpi b/mainActivity/res/._drawable-mdpi
new file mode 100755 (executable)
index 0000000..2f4e437
Binary files /dev/null and b/mainActivity/res/._drawable-mdpi differ
diff --git a/mainActivity/res/._drawable-xxhdpi b/mainActivity/res/._drawable-xxhdpi
new file mode 100755 (executable)
index 0000000..2f4e437
Binary files /dev/null and b/mainActivity/res/._drawable-xxhdpi differ
diff --git a/mainActivity/res/._values b/mainActivity/res/._values
new file mode 100755 (executable)
index 0000000..2f4e437
Binary files /dev/null and b/mainActivity/res/._values differ
diff --git a/mainActivity/res/drawable-hdpi/._ic_launcher.png b/mainActivity/res/drawable-hdpi/._ic_launcher.png
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/res/drawable-hdpi/._ic_launcher.png differ
diff --git a/mainActivity/res/drawable-hdpi/def.jpg b/mainActivity/res/drawable-hdpi/def.jpg
new file mode 100644 (file)
index 0000000..e81ddc1
Binary files /dev/null and b/mainActivity/res/drawable-hdpi/def.jpg differ
diff --git a/mainActivity/res/drawable-hdpi/ic_launcher.png b/mainActivity/res/drawable-hdpi/ic_launcher.png
new file mode 100755 (executable)
index 0000000..96a442e
Binary files /dev/null and b/mainActivity/res/drawable-hdpi/ic_launcher.png differ
diff --git a/mainActivity/res/drawable-mdpi/._ic_launcher.png b/mainActivity/res/drawable-mdpi/._ic_launcher.png
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/res/drawable-mdpi/._ic_launcher.png differ
diff --git a/mainActivity/res/drawable-mdpi/def.jpg b/mainActivity/res/drawable-mdpi/def.jpg
new file mode 100644 (file)
index 0000000..39cdd6e
Binary files /dev/null and b/mainActivity/res/drawable-mdpi/def.jpg differ
diff --git a/mainActivity/res/drawable-mdpi/ic_launcher.png b/mainActivity/res/drawable-mdpi/ic_launcher.png
new file mode 100755 (executable)
index 0000000..359047d
Binary files /dev/null and b/mainActivity/res/drawable-mdpi/ic_launcher.png differ
diff --git a/mainActivity/res/drawable-xhdpi/._ic_launcher.png b/mainActivity/res/drawable-xhdpi/._ic_launcher.png
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/res/drawable-xhdpi/._ic_launcher.png differ
diff --git a/mainActivity/res/drawable-xhdpi/def.jpg b/mainActivity/res/drawable-xhdpi/def.jpg
new file mode 100644 (file)
index 0000000..47e817d
Binary files /dev/null and b/mainActivity/res/drawable-xhdpi/def.jpg differ
diff --git a/mainActivity/res/drawable-xhdpi/ic_launcher.png b/mainActivity/res/drawable-xhdpi/ic_launcher.png
new file mode 100755 (executable)
index 0000000..71c6d76
Binary files /dev/null and b/mainActivity/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/mainActivity/res/drawable-xxhdpi/._ic_launcher.png b/mainActivity/res/drawable-xxhdpi/._ic_launcher.png
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/res/drawable-xxhdpi/._ic_launcher.png differ
diff --git a/mainActivity/res/drawable-xxhdpi/def.jpg b/mainActivity/res/drawable-xxhdpi/def.jpg
new file mode 100644 (file)
index 0000000..8d7903d
Binary files /dev/null and b/mainActivity/res/drawable-xxhdpi/def.jpg differ
diff --git a/mainActivity/res/drawable-xxhdpi/ic_launcher.png b/mainActivity/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755 (executable)
index 0000000..4df1894
Binary files /dev/null and b/mainActivity/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/mainActivity/res/layout-land/download.xml b/mainActivity/res/layout-land/download.xml
new file mode 100755 (executable)
index 0000000..73858f8
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/dlglobal">
+
+    <Button
+        style="?android:attr/buttonStyleSmall"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="aggiorna"
+        android:paddingRight="10dp"
+        android:layout_marginRight="10dp"
+        android:id="@+id/aggiorna" />
+
+    <Button
+        style="?android:attr/buttonStyleSmall"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="logout"
+        android:id="@+id/logout"
+        android:layout_alignParentTop="true"
+        android:layout_toRightOf="@+id/aggiorna"
+        android:layout_toEndOf="@+id/aggiorna" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/startEs"
+        android:text="Lista degli Esercizi:"
+        android:textSize="30sp"
+        android:layout_below="@+id/aggiorna"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentStart="true" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/mainActivity/res/layout/.activity_my.xml.swp b/mainActivity/res/layout/.activity_my.xml.swp
new file mode 100644 (file)
index 0000000..477157c
Binary files /dev/null and b/mainActivity/res/layout/.activity_my.xml.swp differ
diff --git a/mainActivity/res/layout/activity_login.xml b/mainActivity/res/layout/activity_login.xml
new file mode 100755 (executable)
index 0000000..0a37209
--- /dev/null
@@ -0,0 +1,72 @@
+<RelativeLayout
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <ScrollView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/scrollView3">
+        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+            xmlns:tools="http://schemas.android.com/tools"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:paddingLeft="@dimen/activity_horizontal_margin"
+            android:paddingRight="@dimen/activity_horizontal_margin"
+            android:paddingTop="@dimen/activity_vertical_margin"
+            android:paddingBottom="@dimen/activity_vertical_margin"
+            tools:context=".activity_login">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Inserisci le tue credenziali:"
+                android:id="@+id/login"/>
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/invia"
+                android:id="@+id/logout"
+                android:layout_below="@+id/oldPass"
+                android:layout_centerHorizontal="true"
+                android:layout_marginTop="61dp"
+                android:width="120dp" />
+
+            <EditText
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:inputType="textPassword"
+                android:ems="10"
+                android:id="@+id/oldPass"
+                android:hint="@string/pass"
+                android:layout_below="@+id/userId"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentEnd="true"
+                android:layout_marginTop="29dp"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true" />
+            <EditText
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:inputType="textEmailAddress"
+                android:ems="10"
+                android:id="@+id/userId"
+                android:hint="nome.cognome@studio.unibo.it"
+                android:layout_alignParentTop="true"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_marginTop="31dp"
+                android:layout_alignRight="@+id/oldPass"
+                android:layout_alignEnd="@+id/oldPass"
+                android:autoText="false" />
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/registrati"
+                android:id="@+id/button2"
+                android:layout_below="@+id/logout"
+                android:layout_centerHorizontal="true"
+                android:layout_marginTop="31dp"
+                android:width="120dp" />
+        </RelativeLayout>
+    </ScrollView>
+</RelativeLayout>
\ No newline at end of file
diff --git a/mainActivity/res/layout/activity_my.xml b/mainActivity/res/layout/activity_my.xml
new file mode 100755 (executable)
index 0000000..8dd0ae8
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:tools="http://schemas.android.com/tools"
+        android:layout_width="match_parent"
+        android:background="@android:color/holo_blue_light"
+        android:id="@+id/hpscroll"
+        android:layout_height="wrap_content"
+        tools:context=".MyActivity">
+    </RelativeLayout>
+    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:id="@+id/vscroll"
+        xmlns:tools="http://schemas.android.com/tools"
+        android:layout_height="fill_parent"
+        android:fillViewport="false"
+        tools:context=".MainActivity">
+
+        <HorizontalScrollView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:id="@+id/window"
+            android:fillViewport="true">
+            <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                xmlns:tools="http://schemas.android.com/tools"
+                android:layout_width="wrap_content"
+                android:layout_height="7000dp"
+                android:id="@+id/global"
+                tools:context=".MyActivity">
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_centerHorizontal="true" />
+            </RelativeLayout>
+        </HorizontalScrollView>
+    </ScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/mainActivity/res/layout/aggiornamento.xml b/mainActivity/res/layout/aggiornamento.xml
new file mode 100755 (executable)
index 0000000..9b55ff3
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/glob_agg">
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/aggiornamento"
+        android:textSize="20sp"
+        android:id="@+id/loading"
+        android:layout_gravity="center_horizontal"
+        android:layout_alignParentTop="true"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="192dp" />
+
+    <ProgressBar
+        style="?android:attr/progressBarStyleLarge"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/progressBar"
+        android:layout_marginTop="39dp"
+        android:layout_centerHorizontal="true" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/mainActivity/res/layout/download.xml b/mainActivity/res/layout/download.xml
new file mode 100755 (executable)
index 0000000..daa59fa
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ListView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/listView"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentStart="true" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/mainActivity/res/layout/reimpostapass.xml b/mainActivity/res/layout/reimpostapass.xml
new file mode 100644 (file)
index 0000000..5a44271
--- /dev/null
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        xmlns:tools="http://schemas.android.com/tools"
+        android:layout_height="fill_parent"
+        android:fillViewport="false"
+        tools:context=".recuperaPass">
+        <RelativeLayout
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            xmlns:android="http://schemas.android.com/apk/res/android">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Inserisci le tue credenziali:"
+                android:id="@+id/passreim"
+                android:layout_alignParentTop="true"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:textSize="24dp" />
+
+            <EditText
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:inputType="textEmailAddress"
+                android:ems="10"
+                android:id="@+id/userId"
+                android:hint="nome.cognome@studio.unibo.it"
+                android:layout_below="@+id/passreim"
+                android:layout_marginTop="69dp"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentEnd="true" />
+
+            <EditText
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:inputType="textPassword"
+                android:ems="10"
+                android:id="@+id/oldPass"
+                android:hint="vecchia password"
+                android:layout_below="@+id/userId"
+                android:layout_marginTop="50dp"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentEnd="true" />
+
+            <EditText
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:inputType="textPassword"
+                android:ems="10"
+                android:id="@+id/newPass"
+                android:layout_below="@+id/oldPass"
+                android:layout_marginTop="56dp"
+                android:hint="nuova password"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentEnd="true" />
+
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Invia"
+                android:id="@+id/invia"
+                android:layout_marginTop="30dp"
+                android:width="120dp"
+                android:layout_below="@+id/newPass"
+                android:layout_centerHorizontal="true" />
+
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="annulla"
+                android:id="@+id/annulla"
+                android:layout_below="@+id/invia"
+                android:layout_alignLeft="@+id/invia"
+                android:layout_alignStart="@+id/invia"
+                android:layout_marginTop="30dp"
+                android:width="120dp" />
+        </RelativeLayout>
+    </ScrollView>
+</RelativeLayout>
\ No newline at end of file
diff --git a/mainActivity/res/layout/ruledialog.xml b/mainActivity/res/layout/ruledialog.xml
new file mode 100755 (executable)
index 0000000..d2eaea9
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_height="fill_parent"
+    android:fillViewport="false"
+    tools:context=".MainActivity">
+
+    <HorizontalScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:id="@+id/window"
+        android:fillViewport="true">
+        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+            xmlns:tools="http://schemas.android.com/tools"
+            android:layout_width="wrap_content"
+            android:layout_height="1dp"
+            android:id="@+id/global"
+            tools:context=".MyActivity">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerHorizontal="true" />
+        </RelativeLayout>
+    </HorizontalScrollView>
+
+</ScrollView>
\ No newline at end of file
diff --git a/mainActivity/res/layout/string_layout.xml b/mainActivity/res/layout/string_layout.xml
new file mode 100755 (executable)
index 0000000..833a712
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <HorizontalScrollView
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        android:background="@android:color/holo_blue_light"
+        android:fillViewport="true">
+        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+            xmlns:tools="http://schemas.android.com/tools"
+            android:layout_width="wrap_content"
+            android:id="@+id/literals"
+            android:layout_height="match_parent">
+        </RelativeLayout>
+    </HorizontalScrollView>
+        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+            xmlns:tools="http://schemas.android.com/tools"
+            android:layout_width="match_parent"
+            android:background="@android:color/holo_orange_light"
+            android:id="@+id/operators"
+            android:layout_height="40dp"
+            tools:context=".MyActivity">
+        </RelativeLayout>
+
+        <HorizontalScrollView
+            android:layout_width="match_parent"
+            android:layout_height="100dp"
+            android:fillViewport="true">
+            <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                xmlns:tools="http://schemas.android.com/tools"
+                android:layout_width="wrap_content"
+                android:layout_height="100dp"
+                android:id="@+id/formulaLayout"
+                tools:context=".MyActivity">
+            </RelativeLayout>
+        </HorizontalScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/mainActivity/res/layout/textviewgeneral.xml b/mainActivity/res/layout/textviewgeneral.xml
new file mode 100644 (file)
index 0000000..818d2d7
--- /dev/null
@@ -0,0 +1,9 @@
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/rowTextView"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:padding="10dp"
+    android:textSize="20sp"
+    android:textColor="@android:color/black">
+</TextView>
\ No newline at end of file
diff --git a/mainActivity/res/menu/._my.xml b/mainActivity/res/menu/._my.xml
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/res/menu/._my.xml differ
diff --git a/mainActivity/res/menu/login_set.xml b/mainActivity/res/menu/login_set.xml
new file mode 100755 (executable)
index 0000000..2c4a06b
--- /dev/null
@@ -0,0 +1,12 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".MyActivity" >
+    <item android:id="@+id/recupera"
+        android:title="@string/recuperapass"
+        android:orderInCategory="100"
+        android:showAsAction="never" />
+    <item android:id="@+id/reimposta"
+        android:title="@string/reimposta"
+        android:orderInCategory="100"
+        android:showAsAction="never" />
+</menu>
diff --git a/mainActivity/res/menu/menu_dow.xml b/mainActivity/res/menu/menu_dow.xml
new file mode 100755 (executable)
index 0000000..4a7a73e
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<menu
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".MyActivity" >
+    <item android:id="@+id/aggiorna"
+    android:title="@string/sync"
+    android:orderInCategory="100"
+    android:showAsAction="never" />
+    <item android:id="@+id/esci"
+    android:title="@string/esci"
+    android:orderInCategory="100"
+    android:showAsAction="never" />
+</menu>
\ No newline at end of file
diff --git a/mainActivity/res/menu/my.xml b/mainActivity/res/menu/my.xml
new file mode 100755 (executable)
index 0000000..371dbf8
--- /dev/null
@@ -0,0 +1,12 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".MyActivity" >
+    <item android:id="@+id/action_paste"
+        android:title="Incolla sottoalbero"
+        android:orderInCategory="100"
+        android:showAsAction="never" />
+    <item android:id="@+id/abandon"
+        android:title="Abbandona esercizio"
+        android:orderInCategory="100"
+        android:showAsAction="never" />
+</menu>
diff --git a/mainActivity/res/raw/._halloween.crt b/mainActivity/res/raw/._halloween.crt
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/res/raw/._halloween.crt differ
diff --git a/mainActivity/res/raw/._keystore.bks b/mainActivity/res/raw/._keystore.bks
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/res/raw/._keystore.bks differ
diff --git a/mainActivity/res/raw/halloween.crt b/mainActivity/res/raw/halloween.crt
new file mode 100755 (executable)
index 0000000..e60e9db
Binary files /dev/null and b/mainActivity/res/raw/halloween.crt differ
diff --git a/mainActivity/res/raw/keystore.bks b/mainActivity/res/raw/keystore.bks
new file mode 100755 (executable)
index 0000000..1d03af4
Binary files /dev/null and b/mainActivity/res/raw/keystore.bks differ
diff --git a/mainActivity/res/values-w820dp/._dimens.xml b/mainActivity/res/values-w820dp/._dimens.xml
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/res/values-w820dp/._dimens.xml differ
diff --git a/mainActivity/res/values-w820dp/dimens.xml b/mainActivity/res/values-w820dp/dimens.xml
new file mode 100755 (executable)
index 0000000..63fc816
--- /dev/null
@@ -0,0 +1,6 @@
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/mainActivity/res/values/._dimens.xml b/mainActivity/res/values/._dimens.xml
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/res/values/._dimens.xml differ
diff --git a/mainActivity/res/values/._strings.xml b/mainActivity/res/values/._strings.xml
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/res/values/._strings.xml differ
diff --git a/mainActivity/res/values/._styles.xml b/mainActivity/res/values/._styles.xml
new file mode 100755 (executable)
index 0000000..0dfce20
Binary files /dev/null and b/mainActivity/res/values/._styles.xml differ
diff --git a/mainActivity/res/values/dimens.xml b/mainActivity/res/values/dimens.xml
new file mode 100755 (executable)
index 0000000..47c8224
--- /dev/null
@@ -0,0 +1,5 @@
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/mainActivity/res/values/strings.xml b/mainActivity/res/values/strings.xml
new file mode 100755 (executable)
index 0000000..c956b22
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">LogicPlayer</string>
+    <string name="hello_world">inserisci una stringa</string>
+    <string name="action_settings">Settings</string>
+    <string name="invia">accedi</string>
+    <string name="pass">password</string>
+    <string name="sync">Aggiorna</string>
+    <string name="esci">Esci</string>
+    <string name="user">Username</string>
+    <string name="listEs">Lista esercizi:</string>
+    <string name="registrati">registrati</string>
+    <string name="recuperapass">recupera password</string>
+    <string name="first">download disponibili:</string>
+    <string name="reimposta">Reimposta password</string>
+    <string name="listaEsercizi">Lista esercizi:</string>
+    <string name="Credenziali">Inserisci le tue credenziali:</string>
+    <string name="aggiornamento">sto aggiornando</string>
+
+</resources>
diff --git a/mainActivity/res/values/styles.xml b/mainActivity/res/values/styles.xml
new file mode 100755 (executable)
index 0000000..ff6c9d2
--- /dev/null
@@ -0,0 +1,8 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+    </style>
+
+</resources>
diff --git a/mainActivity/src/com/example/furt/myapplication/Border.java b/mainActivity/src/com/example/furt/myapplication/Border.java
new file mode 100755 (executable)
index 0000000..532b11a
--- /dev/null
@@ -0,0 +1,43 @@
+package com.example.furt.myapplication;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.os.Bundle;
+
+public  class Border {
+    private int orientation;
+    private int width;
+    private int color = Color.BLACK;
+    private int style;
+    public int getWidth() {
+        return width;
+    }
+    public void setWidth(int width) {
+        this.width = width;
+    }
+    public int getColor() {
+        return color;
+    }
+    public void setColor(int color) {
+        this.color = color;
+    }
+    public int getStyle() {
+        return style;
+    }
+    public void setStyle(int style) {
+        this.style = style;
+    }
+    public int getOrientation() {
+        return orientation;
+    }
+    public void setOrientation(int orientation) {
+        this.orientation = orientation;
+    }
+    public Border(int Style) {
+        this.style = Style;
+    }
+}
+
diff --git a/mainActivity/src/com/example/furt/myapplication/BorderedTextView.java b/mainActivity/src/com/example/furt/myapplication/BorderedTextView.java
new file mode 100755 (executable)
index 0000000..846aeb1
--- /dev/null
@@ -0,0 +1,68 @@
+package com.example.furt.myapplication;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.widget.TextView;
+
+public class BorderedTextView extends TextView {
+    private Paint paint = new Paint();
+    public static final int BORDER_TOP = 0x00000001;
+    public static final int BORDER_RIGHT = 0x00000002;
+    public static final int BORDER_BOTTOM = 0x00000004;
+    public static final int BORDER_LEFT = 0x00000008;
+    private Border[] borders;
+
+    public BorderedTextView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init();
+    }
+
+    public BorderedTextView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public BorderedTextView(Context context) {
+        super(context);
+        init();
+    }
+    private void init(){
+        paint.setStyle(Paint.Style.STROKE);
+        paint.setColor(Color.BLACK);
+        paint.setStrokeWidth(4);
+    }
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        if(borders == null) return;
+        for(Border border : borders){
+            paint.setColor(border.getColor());
+            paint.setStrokeWidth(border.getWidth());
+
+            if(border.getStyle() == BORDER_TOP){
+                canvas.drawLine(0, 0, getWidth(), 0, paint);
+            } else
+            if(border.getStyle() == BORDER_RIGHT){
+                canvas.drawLine(getWidth(), 0, getWidth(), getHeight(), paint);
+            } else
+            if(border.getStyle() == BORDER_BOTTOM){
+                canvas.drawLine(0, getHeight(), getWidth(), getHeight(), paint);
+            } else
+            if(border.getStyle() == BORDER_LEFT){
+                canvas.drawLine(0, 0, 0, getHeight(), paint);
+            }
+        }
+    }
+
+    public Border[] getBorders() {
+        return borders;
+    }
+
+    public void setBorders(Border[] borders) {
+        this.borders = borders;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/CopyPasteDialog.java b/mainActivity/src/com/example/furt/myapplication/CopyPasteDialog.java
new file mode 100755 (executable)
index 0000000..520ec66
--- /dev/null
@@ -0,0 +1,41 @@
+package com.example.furt.myapplication;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+import java.util.ArrayList;
+
+public class CopyPasteDialog extends DialogFragment {
+    static Node thisNode;
+    public CopyPasteDialog(Node n)
+    {
+        thisNode=n;
+    }
+    @Override
+    public Dialog onCreateDialog(final Bundle savedInstanceState) {
+        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        builder.setMessage("Seleziona un'operazione:")
+                .setPositiveButton("Copia", new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int id) {
+                        DrawActivity.copiedNode=thisNode;
+                    }
+                });
+            builder.setNeutralButton("Cancella", new DialogInterface.OnClickListener() {
+                public void onClick(DialogInterface dialog, int id) {
+                    DrawActivity.selectedNode.Children = new ArrayList<Node>();
+                    DrawActivity.rootNode.Clean();
+                    DrawActivity.startDraw();
+                }
+            });
+        builder.setNegativeButton("Annulla", new DialogInterface.OnClickListener() {
+            public void onClick(DialogInterface dialog, int id) {
+                thisNode=null;
+            }
+        });
+        // Create the AlertDialog object and return it
+        return builder.create();
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/DialogTouchHandler.java b/mainActivity/src/com/example/furt/myapplication/DialogTouchHandler.java
new file mode 100755 (executable)
index 0000000..5e41f79
--- /dev/null
@@ -0,0 +1,32 @@
+package com.example.furt.myapplication;
+
+import android.graphics.Color;
+import android.view.View;
+import android.widget.TextView;
+
+public class DialogTouchHandler implements View.OnClickListener{
+    Node node;
+    DialogTouchHandler(Node n)
+    {
+        node=n;
+    }
+    public void onClick(View view)
+    {
+        if (RuleDialog.selectedRule!=null)
+            if (node==RuleDialog.selectedRule)
+                return;
+        Node sel=node;
+        while(sel.Father!=null)
+            sel=sel.Father;
+        sel.view.setTextColor(Color.RED);
+        for (Node n:sel.Children)
+            n.view.setTextColor(Color.RED);
+        if (RuleDialog.selectedRule!=null)
+        {
+            RuleDialog.selectedRule.view.setTextColor(Color.BLACK);
+            for (Node n:RuleDialog.selectedRule.Children)
+                n.view.setTextColor(Color.BLACK);
+        }
+        RuleDialog.selectedRule=sel;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/DrawActivity.java b/mainActivity/src/com/example/furt/myapplication/DrawActivity.java
new file mode 100644 (file)
index 0000000..fea3a50
--- /dev/null
@@ -0,0 +1,292 @@
+package com.example.furt.myapplication;
+
+import android.app.FragmentManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.RelativeLayout;
+import android.widget.ScrollView;
+import android.widget.Toast;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+
+public class DrawActivity extends FragmentActivity {
+
+    static RelativeLayout globalHP; //layout delle ipotesi cancellate
+    static ScaleGestureDetector scaleGestureDetector; //zoom listener
+    static float spaceSize; //dimensione della spaziatura tra i sottoalberi
+    static float textSize=40; //dimensione del font iniziale
+    static Node selectedNode; //Node su cui è attualmente il focus
+    static Node copiedNode;//nodo copiato
+    static boolean addFakes;//booleano che segnala se bisogna aggiungere delle regole fake
+    static Border[] b; //bordi per le borderedTextView
+    static FragmentManager fragmentManager;//per i dialog
+    static Node rootNode; //radice dell'albero corrente
+    static ScrollView scroll;
+    static int nmoves=0;//numero di mosse
+    static int nerrors=0;//nomero di errori
+    static long startTime;//tempo di inizio dell'esercizio
+    static RelativeLayout globalR; //layout globale contenente l'albero
+    static int globalId =10; //variabile incrementale per l'assegnazione di ID univoci
+    static DisplayMetrics v = new DisplayMetrics();//altezza lunghezza e densità dello schermo
+
+    static String user=null;
+    static String pass=null;
+    static String sessionKey=null;
+    static String nomeEs=null;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        //routine standard per la create
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_my);
+
+        //recupero e setto le variabili globali
+        getWindowManager().getDefaultDisplay().getMetrics(v);
+        globalHP = (RelativeLayout) findViewById(R.id.hpscroll);
+        globalR = (RelativeLayout) findViewById(R.id.global);
+        spaceSize = 2*(textSize/v.density);
+        fragmentManager=getFragmentManager();
+        copiedNode=null;
+        scroll=(ScrollView)findViewById(R.id.vscroll);
+        startTime=time();
+        b=new Border[1];
+        b[0]=new Border(BorderedTextView.BORDER_TOP);
+        b[0].setWidth(2);
+        Bundle dati=getIntent().getExtras();
+        nomeEs=dati.getString("nomeEs");
+        user=dati.getString("user");
+        pass=dati.getString("pass");
+        sessionKey=dati.getString("sessionKey");
+
+        //Creazione dell'albero: setto il rootNode e creo la Formula di partenza (F)
+        if(!populateTree())
+            return;
+
+        //Creazione dell'albero: setto i campi della view
+        BorderedTextView rootView=new BorderedTextView(this);
+        rootView.setId(globalId);
+        globalId++;
+        selectedNode=null;
+        addFakes=false; //di default non vengono aggiunte regole false
+        rootNode.setView(rootView,globalR);
+        rootNode.handler=new touchnodeHandler(rootNode);
+        startDraw();
+
+        //imposto il listener per il pinch zoom
+        scaleGestureDetector = new ScaleGestureDetector(this, new simpleOnScaleGestureListener());
+    }
+    @Override
+    public void onConfigurationChanged(Configuration configuration) //rotazione dello schermo: restore dell'albero
+    {
+        super.onConfigurationChanged(configuration);
+        getWindowManager().getDefaultDisplay().getMetrics(v);
+        DrawActivity.rootNode.Clean();
+        DrawActivity.startDraw();
+    }
+    public static void startDraw()
+    {
+        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        final int halfScreen=Math.round((v.widthPixels / 2) - rootNode.getBaseWidth() / 2); //calcolo la metà dello schermo per il calcolo dei margins della scrollView
+        int leftSubTree=(Math.round(rootNode.getLeftOffset() - rootNode.getUpLine() / 2 + (rootNode.getBaseWidth() / 2)) + 40); //sottoalbero sinistro del rootNode più un padding di 40px
+        lp.setMargins(Math.max(halfScreen,leftSubTree),0, 0, 0);
+        lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, rootNode.view.getId());
+        rootNode.view.setLayoutParams(lp);
+        rootNode.view.setBorders(b);
+        rootNode.view.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
+        rootNode.view.setWidth(Math.round(rootNode.getLineWidth())); //setto la larghezza della view al contenuto della linea
+        rootNode.view.setGravity(Gravity.CENTER); //formula al centro della sua overline
+        rootNode.view.setText(rootNode.F.toString()); //setta il contenuto della formula
+        globalR.addView(rootNode.view);
+        //inserisco un listener a rootView da attivare quando sono state fissate le coordinate nel RelativeLayout
+        rootNode.view.getViewTreeObserver().addOnGlobalLayoutListener(
+                new ViewTreeObserver.OnGlobalLayoutListener()
+                {
+                    @Override
+                    public void onGlobalLayout()
+                    {
+                        globalR.setPadding(0,0,(int)Math.max(rootNode.getRightOffset(),halfScreen),0);
+                        globalR.getLayoutParams().height=(int)Math.max((v.heightPixels),(rootNode.getMaxHeight()+rootNode.getMaxHeight()*0.10)); //altezza della view=max(h_screen,h_tree). Aggiungo un 10% all'altezza dell'albero per approssimazione dei calcoli.
+                        globalR.requestLayout(); //aggiorna i parametri e le dimensioni del RelativeLayout
+                        if (rootNode.treeHeight()< 3)
+                            scroll.fullScroll(ScrollView.FOCUS_DOWN);
+                        rootNode.view.setOnClickListener(rootNode.handler);
+                        rootNode.hasFocus=true; //di default, la radice ha inizialmente il focus.
+                        rootNode.view.getViewTreeObserver().removeOnGlobalLayoutListener(this); //rimuove il listener per evitare che la funzione parta nuovamente
+                        rootNode.Draw();
+
+                    }
+                });
+    }
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.my, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        // TODO Auto-generated method stub
+        scaleGestureDetector.onTouchEvent(event);
+        return true;
+    }
+
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        super.dispatchTouchEvent(event);
+        return (scaleGestureDetector.onTouchEvent(event));
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        int id = item.getItemId();
+        if(id==R.id.action_paste) //incolla sottoalbero
+        {
+            if (DrawActivity.copiedNode == null) //non ci sono nodi da copiare
+                return true;
+            else if (!checkHP(DrawActivity.copiedNode, DrawActivity.selectedNode)) //ipotesi incompatibili: impossibile incollare in questo punto
+                return true;
+            else {
+                Node tmp = duplicateNode(DrawActivity.copiedNode); //duplica il nodo copiato
+                DrawActivity.selectedNode.ruleName=tmp.ruleName;
+                DrawActivity.selectedNode.Children = new ArrayList<Node>();
+                for (Node c:tmp.Children)
+                    DrawActivity.selectedNode.addChild(c); //incolla il sottoalbero del nodo copiato nella posizione richiesta
+                DrawActivity.rootNode.Clean();
+                DrawActivity.startDraw();
+            }
+        }
+        else if(id==R.id.abandon)
+        {   //abbandona esercizio e torna alla view con la lista degli esercizi
+            Intent i = new Intent(globalHP.getContext(), aggiornamento.class);
+            i.putExtra("user", user);
+            i.putExtra("pass", pass);
+            i.putExtra("sessionKey", sessionKey);
+            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            globalHP.getContext().startActivity(i);
+        }
+        return true;
+    }
+
+
+    public boolean checkHP(Node source,Node target) //controlla se le ipotesi di source sono compatibili per una copia in target
+    {
+        boolean found=false;
+        if (!source.F.toString().equals(target.F.toString())) //se i nodi non hanno la stessa formula la copia è automaticamente impossibile
+            return false;
+        for (Hypothesis sourceHp:source.NodeHP) {
+            for (Hypothesis destHp : target.NodeHP) {
+                if (destHp.HP.toString().equals(sourceHp.HP.toString())) { //per ogni ipotesi nel nodo sorgente cerco se è disponibile nel nodo destinazione: in caso affermativo, proseguo il ciclo (found=true).
+                    found = true;
+                    break;
+                }
+            }
+            if (!found)
+                return false;
+            else found=false;
+        }
+        return true;
+    }
+
+    public Node duplicateNode(Node src) //metodo di supporto che duplica un nodo
+    {
+        Node tmp=new Node(src.F);
+        tmp.addHPList(src.NodeHP);
+        tmp.ruleName=src.ruleName;
+        for (Node n:src.Children) {
+            tmp.addChild(duplicateNode(n));
+        }
+        return tmp;
+    }
+
+    public class simpleOnScaleGestureListener extends
+            ScaleGestureDetector.SimpleOnScaleGestureListener {
+
+        @Override
+        public boolean onScale(ScaleGestureDetector detector) {
+            float factor=detector.getScaleFactor();
+            if (textSize>65 && factor>1) //font troppo grande: impedisco aumento
+                return true;
+            if (textSize<15 && factor<1) //font troppo piccolo: impedisco riduzione
+                return true;
+            rootNode.Refactor();  //risetta i campi dell'albero a FIELD_UNSET
+            RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            DrawActivity.spaceSize=(DrawActivity.spaceSize*factor);
+            DrawActivity.textSize=(DrawActivity.textSize*factor);
+            int halfScreen=Math.round((v.widthPixels / 2)-rootNode.getBaseWidth()/2);
+            int leftSubTree=(Math.round(rootNode.getLeftOffset() - rootNode.getUpLine() / 2 + (rootNode.getBaseWidth() / 2)) + 40);
+            globalR.setPadding(0,0,(int)Math.max(rootNode.getRightOffset(),halfScreen),0);
+            lp.setMargins(Math.max(halfScreen,leftSubTree),0, 0, 0);
+            lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, rootNode.view.getId());
+            rootNode.view.setLayoutParams(lp);
+            rootNode.view.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
+            rootNode.view.setWidth(Math.round(rootNode.getLineWidth())); //setto la larghezza della view al contenuto della linea
+            rootNode.Resize(); //ricorsivamente sistema i fontsize, le larghezze e le posizioni delle view nell'albero
+            return true;
+        }
+    }
+    public static void finishedTree(Context context) {
+        if (!rootNode.isCorrect()) {
+            Toast.makeText(context, "Esercizio errato! Ricontrolla i passaggi fatti e riprova", Toast.LENGTH_LONG).show();
+        } else {
+            long endTime = time();
+            int second= (int) ((endTime-startTime)/1000);
+            int minute=second/60;
+            Toast.makeText(context, "Esercizio completato in " + Integer.toString(nmoves) + " mosse!", Toast.LENGTH_LONG).show();
+            Toast.makeText(context, "Hai commesso " + Integer.toString(nerrors) + " errori!", Toast.LENGTH_LONG).show();
+            Toast.makeText(context, "Numero nodi dell'albero: " + Integer.toString(rootNode.count()), Toast.LENGTH_LONG).show();
+            Toast.makeText(context, "Tempo impiegato: " + Integer.toString(minute) + " minuti e " + Integer.toString(second-(minute*60)) + " secondi", Toast.LENGTH_LONG).show();
+            //aggiungo l'esercizio al database
+            int voto=valutazione.voto(nomeEs,nmoves,second,rootNode.count(),nerrors);
+            personalDBHelper db = new personalDBHelper(context);
+            db.add(user, nomeEs, MD5.digest(nomeEs), 0.0, voto, 0);
+            nmoves = 0;
+            Intent i = new Intent(context, aggiornamento.class);
+            i.putExtra("user", user);
+            i.putExtra("pass", pass);
+            i.putExtra("sessionKey", sessionKey);
+            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            context.startActivity(i);
+        }
+    }
+    public boolean populateTree() {
+
+        rootNode = parser.root(nomeEs);
+        if(rootNode==null)
+        {
+            Toast.makeText(this, "Errore nell'apertura del file", Toast.LENGTH_LONG).show();
+            Intent i = new Intent(this, aggiornamento.class);
+            i.putExtra("user", user);
+            i.putExtra("pass", pass);
+            i.putExtra("sessionKey", sessionKey);
+            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            this.startActivity(i);
+            return false;
+        }
+        for (Hypothesis h:rootNode.NodeHP)
+            h.fromNode=rootNode;
+        return true;
+    }
+    public static long time()
+    {
+        java.util.Date date= new java.util.Date();
+        Timestamp now=new Timestamp(date.getTime());
+        return now.getTime();
+    }
+
+}
+
diff --git a/mainActivity/src/com/example/furt/myapplication/EliminationRule.java b/mainActivity/src/com/example/furt/myapplication/EliminationRule.java
new file mode 100755 (executable)
index 0000000..7285a4a
--- /dev/null
@@ -0,0 +1,11 @@
+package com.example.furt.myapplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface EliminationRule
+{
+    public String getName();
+    public Node createNodes(Formula F, askFormula ask);
+}
+
diff --git a/mainActivity/src/com/example/furt/myapplication/FView.java b/mainActivity/src/com/example/furt/myapplication/FView.java
new file mode 100755 (executable)
index 0000000..479df78
--- /dev/null
@@ -0,0 +1,13 @@
+package com.example.furt.myapplication;
+
+public interface FView
+{
+    @Override
+    public String toString();
+    public String toStringDeleted();
+    String Draw(int priority);
+    public float size();
+    public float height();
+    public float sizeDeleted();
+
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/Formula.java b/mainActivity/src/com/example/furt/myapplication/Formula.java
new file mode 100755 (executable)
index 0000000..4209b58
--- /dev/null
@@ -0,0 +1,12 @@
+package com.example.furt.myapplication;
+
+import java.util.List;
+
+public interface Formula extends FView{
+    public List<IntroductionRule> introductionRules();
+    public List<EliminationRule> EliminationRules();
+    public boolean Fill(Formula F);
+    public boolean setCursor();
+    public Formula duplicate();
+}
+
diff --git a/mainActivity/src/com/example/furt/myapplication/FormulaAnd.java b/mainActivity/src/com/example/furt/myapplication/FormulaAnd.java
new file mode 100755 (executable)
index 0000000..2c81ee9
--- /dev/null
@@ -0,0 +1,74 @@
+package com.example.furt.myapplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FormulaAnd extends GenericFormula implements Formula
+{
+    Formula leftF;
+    Formula rightF;
+    int leftPriority;
+    int rightPriority;
+    FormulaAnd(Formula F1,Formula F2)
+    {
+        leftF=F1;
+        rightF=F2;
+        priority=15;
+        leftPriority=15;
+        rightPriority=16;
+    }
+    @Override
+    public String Draw(int p)
+    {
+        if (priority >= p)
+            return leftF.Draw(leftPriority)+"∧"+rightF.Draw(rightPriority);
+        else
+            return("(")+leftF.Draw(leftPriority)+"∧"+rightF.Draw(rightPriority)+")";
+    }
+
+    @Override
+    public List<IntroductionRule> introductionRules()
+    {
+        List<IntroductionRule> rules=new ArrayList<IntroductionRule>();
+        rules.addAll(super.introductionRules());
+        RuleIntroduction andIntroduction=new RuleIntroduction("∧i",5);
+        Node Left=new Node(leftF);
+        Node Right=new Node(rightF);
+        Node thisNode=new Node(this);
+        thisNode.addChild(Left);
+        thisNode.addChild(Right);
+        andIntroduction.tempRule=thisNode;
+        rules.add(andIntroduction);
+        return rules;
+    }
+    public List<EliminationRule> EliminationRules()
+    {
+        List<EliminationRule> nodes=new ArrayList<EliminationRule>();
+        nodes.add(new RuleAndElimination(this));
+        return nodes;
+    }
+
+    @Override
+    public boolean Fill(Formula Filler) {
+        if(leftF.toString().equals("_")) {
+            this.leftF = Filler;
+            return true;
+        }
+        else if(rightF.toString().equals("_")) {
+            this.rightF = Filler;
+            return true;
+        }
+        return leftF.Fill(Filler) || rightF.Fill(Filler);
+    }
+
+    @Override
+    public boolean setCursor() {
+        return leftF.setCursor() || rightF.setCursor();
+    }
+
+    @Override
+    public Formula duplicate() {
+        return new FormulaAnd(leftF.duplicate(),rightF.duplicate());
+    }
+}
+
diff --git a/mainActivity/src/com/example/furt/myapplication/FormulaBOT.java b/mainActivity/src/com/example/furt/myapplication/FormulaBOT.java
new file mode 100755 (executable)
index 0000000..6103bd8
--- /dev/null
@@ -0,0 +1,46 @@
+package com.example.furt.myapplication;
+
+import android.graphics.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FormulaBOT extends GenericFormula implements Formula{
+    Paint p=new Paint();
+    FormulaBOT()
+    {
+        priority=100;
+    }
+
+    @Override
+    public String Draw(int p)
+    {
+        return "⊥";
+    }
+
+    public List<IntroductionRule> introductionRules(){
+        List<IntroductionRule> nodes=new ArrayList<IntroductionRule>();
+        return nodes;
+    }
+    public List<EliminationRule> EliminationRules()
+    {
+        List<EliminationRule> nodes=new ArrayList<EliminationRule>();
+        nodes.add(new RuleBotElimination(this));
+        return nodes;
+    }
+
+    @Override
+    public boolean Fill(Formula F) {
+        return false;
+    }
+
+    @Override
+    public boolean setCursor() {
+        return false;
+    }
+
+    @Override
+    public Formula duplicate() {
+        return new FormulaBOT();
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/FormulaImpl.java b/mainActivity/src/com/example/furt/myapplication/FormulaImpl.java
new file mode 100755 (executable)
index 0000000..9761a0e
--- /dev/null
@@ -0,0 +1,71 @@
+package com.example.furt.myapplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FormulaImpl extends GenericFormula implements Formula
+{
+    Formula leftF;
+    Formula rightF;
+    int leftPriority;
+    int rightPriority;
+    FormulaImpl(Formula F1,Formula F2)
+    {
+        priority=10;
+        leftF=F1;
+        rightF=F2;
+        leftPriority=11;
+        rightPriority=10;
+    }
+    @Override
+    public String Draw(int p)
+    {
+        if (priority >= p)
+            return leftF.Draw(leftPriority)+"⇒"+rightF.Draw(rightPriority);
+        else
+            return("(")+leftF.Draw(leftPriority)+"⇒"+rightF.Draw(rightPriority)+")";
+    }
+
+    public List<IntroductionRule> introductionRules(){
+        List<IntroductionRule> nodes=new ArrayList<IntroductionRule>();
+        nodes.addAll(super.introductionRules());
+        RuleIntroduction implIntro=new RuleIntroduction("⇒i",10);
+        Node ImplN=new Node(rightF);
+        List<Formula> implHP=new ArrayList<Formula>();
+        implHP.add(leftF);
+        ImplN.addHPFormula(implHP,true);
+        Node thisNode=new Node(this);
+        thisNode.addChild(ImplN);
+        implIntro.tempRule=thisNode;
+        nodes.add(implIntro);
+        return nodes;
+    }
+    public List<EliminationRule> EliminationRules()
+    {
+        List<EliminationRule> nodes=new ArrayList<EliminationRule>();
+        nodes.add(new RuleImplElimination(this));
+        return nodes;
+    }
+    @Override
+    public boolean Fill(Formula Filler) {
+        if(leftF.toString().equals("_")) {
+            this.leftF = Filler;
+            return true;
+        }
+        else if(rightF.toString().equals("_")) {
+            this.rightF = Filler;
+            return true;
+        }
+        return leftF.Fill(Filler) || rightF.Fill(Filler);
+    }
+
+    @Override
+    public boolean setCursor() {
+        return leftF.setCursor() || rightF.setCursor();
+    }
+
+    @Override
+    public Formula duplicate() {
+        return new FormulaImpl(leftF.duplicate(),rightF.duplicate());
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/FormulaNot.java b/mainActivity/src/com/example/furt/myapplication/FormulaNot.java
new file mode 100755 (executable)
index 0000000..f8b0d37
--- /dev/null
@@ -0,0 +1,66 @@
+package com.example.furt.myapplication;
+
+import android.graphics.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FormulaNot extends GenericFormula implements Formula{
+    Paint p=new Paint();
+    Formula Operand;
+    int priority;
+    int argPriority;
+    FormulaNot(Formula F)
+    {
+        Operand=F;
+        priority=20;
+        argPriority=100;
+    }
+    @Override
+    public String Draw(int p)
+    {
+        if (priority >= p)
+            return "¬"+Operand.Draw(20);
+        else
+            return("¬("+Operand.Draw(20)+")");
+    }
+
+    public List<IntroductionRule> introductionRules(){
+        List<IntroductionRule> nodes=new ArrayList<IntroductionRule>();
+        RuleIntroduction notIntro=new RuleIntroduction("¬i",4);
+        Node notN=new Node(new FormulaBOT());
+        List<Formula> notHP=new ArrayList<Formula>();
+        notHP.add(Operand);
+        notN.addHPFormula(notHP,true);
+        Node thisNode=new Node(this);
+        thisNode.addChild(notN);
+        notIntro.tempRule=thisNode;
+        nodes.add(notIntro);
+        return nodes;
+    }
+    public List<EliminationRule> EliminationRules()
+    {
+        List<EliminationRule> nodes=new ArrayList<EliminationRule>();
+        nodes.add(new RuleNotElimination(this));
+        return nodes;
+    }
+
+    @Override
+    public boolean Fill(Formula Filler) {
+        if(Operand.toString().equals("_")) {
+            Operand = Filler;
+            return true;
+        }
+        return Operand.Fill(Filler);
+    }
+
+    @Override
+    public boolean setCursor() {
+        return Operand.setCursor();
+    }
+
+    @Override
+    public Formula duplicate() {
+        return new FormulaNot(Operand.duplicate());
+    }
+}
\ No newline at end of file
diff --git a/mainActivity/src/com/example/furt/myapplication/FormulaOr.java b/mainActivity/src/com/example/furt/myapplication/FormulaOr.java
new file mode 100755 (executable)
index 0000000..4a1794d
--- /dev/null
@@ -0,0 +1,79 @@
+package com.example.furt.myapplication;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FormulaOr extends GenericFormula implements Formula
+{
+    Formula leftF;
+    Formula rightF;
+    int leftPriority;
+    int rightPriority;
+    FormulaOr(Formula F1,Formula F2)
+    {
+        priority=13;
+        leftF=F1;
+        rightF=F2;
+        leftPriority=13;
+        rightPriority=14;
+    }
+
+    @Override
+    public String Draw(int p)
+    {
+        if (priority >= p)
+            return leftF.Draw(leftPriority)+"∨"+rightF.Draw(rightPriority);
+        else
+            return("(")+leftF.Draw(leftPriority)+"∨"+rightF.Draw(rightPriority)+")";
+    }
+
+    public List<IntroductionRule> introductionRules(){
+        List<IntroductionRule> nodes=new ArrayList<IntroductionRule>();
+        nodes.addAll(super.introductionRules());
+        RuleIntroduction orIntroductionLeft=new RuleIntroduction("∨i(L)",6);
+        Node orLeft=new Node(leftF);
+        Node thisNodeL=new Node(this);
+        thisNodeL.addChild(orLeft);
+        orIntroductionLeft.tempRule=thisNodeL;
+        nodes.add(orIntroductionLeft);
+        RuleIntroduction orIntroductionRight=new RuleIntroduction("∨i(R)",5);
+        Node orRight=new Node(rightF);
+        Node thisNodeR=new Node(this);
+        thisNodeR.addChild(orRight);
+        orIntroductionRight.tempRule=thisNodeR;
+        nodes.add(orIntroductionRight);
+        return nodes;
+    }
+
+    public List<EliminationRule> EliminationRules()
+    {
+        List<EliminationRule> nodes=new ArrayList<EliminationRule>();
+        nodes.add(new RuleOrElimination(this));
+        return nodes;
+    }
+
+    @Override
+    public boolean Fill(Formula Filler) {
+        if(leftF.toString().equals("_")) {
+            this.leftF = Filler;
+            return true;
+        }
+        else if(rightF.toString().equals("_")) {
+            this.rightF = Filler;
+            return true;
+        }
+        return leftF.Fill(Filler) || rightF.Fill(Filler);
+    }
+
+    @Override
+    public boolean setCursor() {
+        return leftF.setCursor() || rightF.setCursor();
+    }
+
+    @Override
+    public Formula duplicate() {
+        return new FormulaOr(leftF.duplicate(),rightF.duplicate());
+    }
+}
+
diff --git a/mainActivity/src/com/example/furt/myapplication/FormulaTOP.java b/mainActivity/src/com/example/furt/myapplication/FormulaTOP.java
new file mode 100755 (executable)
index 0000000..05cba71
--- /dev/null
@@ -0,0 +1,42 @@
+package com.example.furt.myapplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FormulaTOP extends GenericFormula implements Formula{
+
+    FormulaTOP()
+    {
+        priority=100;
+    }
+
+    @Override
+    public String Draw(int p){return "Ț";}
+
+    public List<IntroductionRule> introductionRules(){
+        List<IntroductionRule> nodes=new ArrayList<IntroductionRule>();
+        nodes.addAll(super.introductionRules());
+        return nodes;
+    }
+
+    @Override
+    public boolean Fill(Formula F) {
+        return false;
+    }
+
+    @Override
+    public boolean setCursor() {
+        return false;
+    }
+
+    @Override
+    public Formula duplicate() {
+        return new FormulaTOP();
+    }
+
+    public List<EliminationRule> eliminationRules(){
+        List<EliminationRule> nodes=new ArrayList<EliminationRule>();
+        return nodes;
+    }
+
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/GenericFormula.java b/mainActivity/src/com/example/furt/myapplication/GenericFormula.java
new file mode 100755 (executable)
index 0000000..5e063f5
--- /dev/null
@@ -0,0 +1,83 @@
+package com.example.furt.myapplication;
+
+import android.graphics.Paint;
+import android.graphics.Rect;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GenericFormula implements Formula
+{
+    Paint p=new Paint();
+    int priority;
+    public String Draw(int p)
+    {
+        return "";
+    }
+    public String toString(){return Draw(0);}
+    public float size(){
+        p.setTextSize(DrawActivity.textSize);
+        return p.measureText(toString())+(float)(p.measureText(toString())*0.20);
+    }
+    public float sizeDeleted()
+    {
+        p.setTextSize(DrawActivity.textSize);
+        return p.measureText(toStringDeleted())+(float)(p.measureText(toStringDeleted())*0.20);
+    }
+    public String toStringDeleted()
+    {
+        return "["+toString()+"]";
+    }
+    public float height()
+    {
+        p.setTextSize(DrawActivity.textSize);
+        Rect bounds=new Rect();
+        p.getTextBounds(toString(),0,toString().length(),bounds);
+        return (float)((bounds.height()+((float)0.20*bounds.height()))*1.5);
+    }
+    public List<IntroductionRule> introductionRules(){
+        List<IntroductionRule> rules=new ArrayList<IntroductionRule>();
+        Node thisNode=new Node(this);
+        RuleIntroduction RAA=new RuleIntroduction("RAA",0);                        //R.A.A.
+        Node RAAnode=new Node(new FormulaBOT());                            //Formula=Bottom
+        List<Formula> RAAhp=new ArrayList<Formula>();                             //Tutte le ipotesi del nodo precedente
+        RAAhp.add(new FormulaNot(this));                                    //Più la negazione del nodo attuale
+        RAAnode.addHPFormula(RAAhp,true);
+        thisNode.addChild(RAAnode);
+        RAA.tempRule=thisNode;
+        rules.add(RAA);
+        /*
+        Node thisFakeNode=new Node(this);
+        RuleIntroduction fakeRAA=new RuleIntroduction("RAA",0,true);                        //fake R.A.A.
+        Node fakeRAAnode=new Node(new FormulaNot(this));                            //Formula=!F
+        thisFakeNode.addChild(fakeRAAnode);
+        fakeRAA.tempRule=thisFakeNode;
+        rules.add(fakeRAA);
+        */
+        return rules;
+    }
+    public List<EliminationRule> EliminationRules(){
+        List<EliminationRule> nodes=new ArrayList<EliminationRule>();
+        return nodes;
+    }
+
+    @Override
+    public boolean Fill(Formula F) {
+        return false;
+    }
+
+    @Override
+    public boolean setCursor() {
+        return false;
+    }
+
+    @Override
+    public Formula duplicate() {
+        return null;
+    }
+
+    @Override
+    public Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/Hypothesis.java b/mainActivity/src/com/example/furt/myapplication/Hypothesis.java
new file mode 100755 (executable)
index 0000000..6a7d638
--- /dev/null
@@ -0,0 +1,14 @@
+package com.example.furt.myapplication;
+
+public class Hypothesis
+{
+    Formula HP;
+    boolean isDeleted;
+    Node fromNode;
+    Hypothesis(Formula F,boolean d)
+    {
+        HP=F;
+        isDeleted=d;
+        fromNode=null;
+    }
+}
\ No newline at end of file
diff --git a/mainActivity/src/com/example/furt/myapplication/IntroductionRule.java b/mainActivity/src/com/example/furt/myapplication/IntroductionRule.java
new file mode 100755 (executable)
index 0000000..880ca1a
--- /dev/null
@@ -0,0 +1,8 @@
+package com.example.furt.myapplication;
+
+public interface IntroductionRule
+{
+    int getPriority();
+    String getName();
+    public Node createNodes(askFormula ask);
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/Literal.java b/mainActivity/src/com/example/furt/myapplication/Literal.java
new file mode 100755 (executable)
index 0000000..d129975
--- /dev/null
@@ -0,0 +1,36 @@
+package com.example.furt.myapplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Literal extends GenericFormula implements Formula
+{
+    String L;
+    Literal(char c)
+    {
+        priority=100;
+        L=c+"";
+    }
+    @Override
+    public String Draw(int p){return L;}
+
+    public List<IntroductionRule> introductionRules(){
+        List<IntroductionRule> nodes=new ArrayList<IntroductionRule>();
+        nodes.addAll(super.introductionRules());
+        return nodes;
+    }
+
+    @Override
+    public boolean Fill(Formula F) {
+        return false;
+    }
+
+    public boolean isCompatible(Node n) {
+        return true;
+    }
+
+    @Override
+    public Formula duplicate() {
+        return new Literal(this.L.charAt(0));
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/LongHPClick.java b/mainActivity/src/com/example/furt/myapplication/LongHPClick.java
new file mode 100755 (executable)
index 0000000..fa59a8d
--- /dev/null
@@ -0,0 +1,26 @@
+package com.example.furt.myapplication;
+
+import android.graphics.Color;
+import android.os.Handler;
+import android.view.View;
+
+public class LongHPClick implements View.OnLongClickListener {
+
+    Node n;
+    LongHPClick(Node node)
+    {
+        n=node;
+    }
+    @Override
+    public boolean onLongClick(View v) {
+        n.view.setTextColor(Color.BLUE);
+        final Handler handler = new Handler();
+        handler.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                n.view.setTextColor(Color.BLACK);
+            }
+        }, 1000);
+        return true;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/MD5.java b/mainActivity/src/com/example/furt/myapplication/MD5.java
new file mode 100755 (executable)
index 0000000..8f7bdc0
--- /dev/null
@@ -0,0 +1,65 @@
+package com.example.furt.myapplication;
+
+import android.os.Environment;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.MessageDigest;
+
+
+public class MD5 {
+
+    MD5(){}
+
+    /*public static String digest(String fileName) throws NoSuchAlgorithmException, IOException
+    {
+
+        MessageDigest md = MessageDigest.getInstance("MD5");
+        return getDigest(new FileInputStream("/var/www/html/esercizi/"+fileName), md, 2048);
+    }
+
+    public static String getDigest(InputStream is, MessageDigest md, int byteArraySize) throws NoSuchAlgorithmException, IOException
+    {
+        md.reset();
+        byte[] bytes = new byte[byteArraySize];
+        int numBytes;
+        while ((numBytes = is.read(bytes)) != -1) {
+            md.update(bytes, 0, numBytes);
+        }
+        byte[] digest = md.digest();
+        String result = new String(Hex.encodeHex(digest));
+        return result;
+    }*/
+    public static String digest(String filePath) {
+        InputStream inputStream = null;
+        try {
+            inputStream = new FileInputStream(Environment.getExternalStorageDirectory()+"/tesiEs/"+filePath);
+            byte[] buffer = new byte[1024];
+            MessageDigest digest = MessageDigest.getInstance("MD5");
+            int numRead = 0;
+            while (numRead != -1) {
+                numRead = inputStream.read(buffer);
+                if (numRead > 0)
+                    digest.update(buffer, 0, numRead);
+            }
+            byte [] md5Bytes = digest.digest();
+            return convertHashToString(md5Bytes);
+        } catch (Exception e) {
+            return null;
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (Exception e) { }
+            }
+        }
+    }
+
+    private static String convertHashToString(byte[] md5Bytes) {
+        String returnVal = "";
+        for (int i = 0; i < md5Bytes.length; i++) {
+            returnVal += Integer.toString(( md5Bytes[i] & 0xff ) + 0x100, 16).substring(1);
+        }
+        return returnVal;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/MyService.java b/mainActivity/src/com/example/furt/myapplication/MyService.java
new file mode 100755 (executable)
index 0000000..acac481
--- /dev/null
@@ -0,0 +1,139 @@
+package com.example.furt.myapplication;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.Scanner;
+
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+public class MyService extends Service {
+
+    @Override
+    public int onStartCommand(final Intent intent, int flags, int startId)
+    {
+        final Context context=getApplicationContext();
+        /*System.setProperty("javax.net.ssl.trustStore", "mysrvkeystore");
+        //Log.e("onStartCommand",""+R.raw.mysrvkeystore);
+        System.setProperty("javax.net.ssl.trustStorePassword", "123456");
+
+
+
+        String inviotmp = intent.getStringExtra("code") + intent.getStringExtra("varInvio");
+
+        if(intent.getStringExtra("code").charAt(0)!='2')
+            inviotmp = inviotmp + intent.getStringExtra("varInvio2");
+        final String invio=inviotmp;
+        final Thread readthread;
+        readthread = new Thread(new Runnable() {
+            public void run() {
+                SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
+                //Socket socket = null;
+                SSLSocket socket = null;
+                try {
+                    int port = 25000;
+                   // socket = new Socket("10.0.0.2", port);
+                    socket=(SSLSocket) sslsocketfactory.createSocket("10.0.0.2", port);                    //Send the message to the server
+                    OutputStream os = socket.getOutputStream();
+                    OutputStreamWriter osw = new OutputStreamWriter(os);
+                    BufferedWriter bw = new BufferedWriter(osw);
+
+                    //String number = "2";
+
+                    String sendMessage = invio+"\n";
+                    bw.write(sendMessage+"\n");
+                    bw.flush();
+                    System.out.println("Message sent to the server : " + sendMessage);
+
+                    //Get the return message from the server
+                    InputStream is = socket.getInputStream();
+                    InputStreamReader isr = new InputStreamReader(is);
+                    BufferedReader br = new BufferedReader(isr);
+                    String message;
+                    message = br.readLine();
+                    System.out.println("Message received from the server : " + message);
+                } catch (Exception exception) {
+                    exception.printStackTrace();
+                } finally {
+                    //Closing the socket
+                    try {
+                        socket.close();
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        });
+
+        readthread.start();*/
+        final Thread readthread;
+        readthread = new Thread(new Runnable() {
+            public void run() {
+                InputStream certificato = getResources().openRawResource(R.raw.keystore);
+                KeyStore trustStore = null;
+                try
+                {
+                    trustStore = KeyStore.getInstance("BKS");
+                    trustStore.load(certificato, "123stella".toCharArray());
+                    SSLSocketFactory fs = (SSLSocketFactory) SSLSocketFactory.getDefault();
+                    SSLSocket socket = (SSLSocket) fs.createSocket("10.0.0.2", 25000);
+                    Log.e("", "miracolo");
+
+                    InputStream inputstream = System.in;
+                    InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
+                    BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
+
+                    OutputStream os = socket.getOutputStream();
+                    OutputStreamWriter osw = new OutputStreamWriter(os);
+                    BufferedWriter bw = new BufferedWriter(osw);
+
+                    String sendMessage ="brova";
+                    bw.write(sendMessage+"\n");
+                    bw.flush();
+
+                    System.out.println("Message sent to the server : " + sendMessage);
+                }
+                catch (KeyStoreException e)
+                {
+                    e.printStackTrace();
+                }
+                catch (CertificateException e)
+                {
+                    e.printStackTrace();
+                }
+                catch (NoSuchAlgorithmException e)
+                {
+                    e.printStackTrace();
+                }
+                catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+        readthread.start();
+        return 0;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/Node.java b/mainActivity/src/com/example/furt/myapplication/Node.java
new file mode 100755 (executable)
index 0000000..9b724ff
--- /dev/null
@@ -0,0 +1,439 @@
+package com.example.furt.myapplication;
+
+import android.graphics.Color;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class Node implements Tree {
+
+    static int FIELD_UNSET = -1;
+    static int OPEN=0;
+    static int FAKE=1;
+    static int CLOSED=2;
+    static int FAKE_CLOSED=3;
+    static int CANCELED=4;
+    static int FAKE_CANCELED=5;
+
+    Formula F; //formula legata al nodo
+    String ruleName; //nome della regola associata a questo nodo
+    List<Node> Children = new ArrayList<Node>(); //Nodi figli
+    List<Hypothesis> NodeHP = new ArrayList<Hypothesis>(); //ipotesi associate
+    Node Father; //puntatore al padre
+    View.OnClickListener handler; //touchHandler per far comparire il pop-up delle regole
+    boolean hasFocus; //indica se questo nodo è quello selezionato
+    int status; //stato del nodo (chiuso, aperto,fake...)
+    RelativeLayout global; //layout in cui si trova l'albero
+    BorderedTextView view; //view contenente questo oggetto
+    TextView ruleView; //view contenente l'intestazione della regola
+
+    float baseLine;
+    float leftOffset;
+    float rightOffset;
+    float maxWidth;
+
+    Node(Formula F) {
+        this.F = F;
+        view = null;
+        handler = null;
+        ruleName="";
+        Father = null;
+        status=OPEN;
+        hasFocus = false;
+        leftOffset = 0;
+        rightOffset = 0;
+        baseLine = getBaseWidth();
+        maxWidth = baseLine;
+    }
+
+    /**************SetView**************+*****/
+    /*****************************************/
+    /*******Setta la TextView del node  ******/
+    /** e il layout in cui deve comparire  ***/
+    /*****************************************/
+
+    public void setView(BorderedTextView t,RelativeLayout r) {
+        view = t;
+        ruleView =new TextView(t.getContext());
+        global=r;
+    }
+
+
+    /**************Count****************+*****/
+    /*****************************************/
+    /*******Restituisce il numero di    ******/
+    /*************nodi dell'albero ***********/
+    /*****************************************/
+
+    int count()
+    {
+        int ris=1;
+        for (Node n:Children)
+            ris+=n.count();
+        return ris;
+    }
+
+    public void addHPFormula(List<Formula>List,boolean deleted) {
+        loop:for (Formula newHp:List) {
+            for (Hypothesis oldHp: NodeHP) {
+                if (oldHp.HP.toString().equals(newHp.toString())) {
+                    continue loop;
+                }
+            }
+            NodeHP.add(new Hypothesis(newHp, deleted));
+        }
+    }
+
+    public void addHPList(List<Hypothesis>List) {
+        loop:for (Hypothesis newHp:List) {
+            for (Hypothesis oldHp: NodeHP) {
+                if (oldHp.HP.toString().equals(newHp.HP.toString())) {
+                    continue loop;
+                }
+            }
+            Hypothesis copyHP=new Hypothesis(newHp.HP, newHp.isDeleted);
+            copyHP.fromNode=newHp.fromNode;
+            NodeHP.add(copyHP);
+        }
+    }
+
+    public boolean searchFocus(Node caller)
+    {
+        if (Children.size()==0) //caso base: controllo se il focus può essere su di me
+        {
+            if (status!=OPEN && status!=FAKE) //nodo chiuso: il focus non può essere su di me
+                return false;
+            hasFocus=true;                             //posso assumere il focus
+            if (handler!=null)
+                handler.onClick(view);
+            return true;
+        }
+        //passo induttivo: vado su tutti i miei figli, poi su mio padre. Termino se il padre è null.
+        for (Node n:Children) {
+            if (caller != null)
+                if (n == caller) //per ogni figlio diverso dal chiamante
+                {
+                    continue;
+                }
+            if(n.searchFocus(null))
+                return true;
+        }
+        if (caller==null) //ero stato chiamato da mio padre: è inutile richiamarlo
+            return false;
+        else if (Father==null)
+            return false; //padre null: l'albero è dimostrato e non ci sono nodi a cui dare il focus.
+        else
+            return Father.searchFocus(this); //propaga il searchFocus sul padre
+    }
+    public void addChild(Node N) {
+        N.Father = this;
+        Children.add(N);
+        Node tmp=Father;
+        baseLine=FIELD_UNSET;
+        maxWidth=FIELD_UNSET;
+        leftOffset=FIELD_UNSET;
+        rightOffset=FIELD_UNSET;
+        while (tmp!=null)
+        {
+            tmp.baseLine=FIELD_UNSET;
+            tmp.leftOffset=FIELD_UNSET;
+            tmp.rightOffset=FIELD_UNSET;
+            tmp.maxWidth=FIELD_UNSET;
+            tmp=tmp.Father;
+        }
+    }
+
+    public float getBaseWidth() {
+        return F.size();
+    }
+
+    public float getMaxWidth() //ritorna la larghezza massima del sottoalbero
+    {
+        if (maxWidth!=FIELD_UNSET)
+            return maxWidth;
+        else
+            maxWidth=getLeftOffset()+getBaseWidth()+getRightOffset();
+        return (maxWidth);
+    }
+
+    public float getLineWidth()
+    {
+        if (baseLine!=FIELD_UNSET)
+            return baseLine;
+        else
+        {
+            float spaceSize = DrawActivity.spaceSize;
+            if (Children.size() == 0)
+                return (getBaseWidth());
+            int res = 0;
+            for (Node n:Children)
+                res += (n.getMaxWidth()) + spaceSize;
+            res -= spaceSize;
+            res -= Children.get(0).getLeftOffset();
+            res -= Children.get(Children.size() - 1).getRightOffset();
+            baseLine=Math.max(res,getBaseWidth());
+            return baseLine;
+        }
+    }
+    public float getUpLine()
+    {
+        float spaceSize= DrawActivity.spaceSize;
+        if (Children.size()==0)
+            return(getBaseWidth());
+        int res=0;
+        for(Node n:Children)
+            res+=(n.getMaxWidth())+spaceSize;
+        res-=spaceSize;
+        res-=Children.get(0).getLeftOffset();
+        res-=Children.get(Children.size()-1).getRightOffset();
+        return res;
+    }
+    public float getLeftOffset() {
+        if (leftOffset != FIELD_UNSET) {
+            return leftOffset;
+        }
+        else {
+            if (Children.size() == 0) //foglia
+                leftOffset=0;
+            else
+                leftOffset=Math.max(Children.get(0).getLeftOffset() + ((getUpLine() - getBaseWidth()) / 2),0);
+            return leftOffset;
+        }
+    }
+
+    public float getMaxHeight()
+    {
+        float baseRes=F.height();
+        float res=baseRes;
+        for (Node n:Children)
+        {
+            float tempH=n.getMaxHeight()+baseRes;
+            if(tempH>res)
+                res=tempH;
+        }
+        return res;
+    }
+    public float getRightOffset()
+    {
+        if (rightOffset!=FIELD_UNSET)
+            return rightOffset;
+        else {
+            if (Children.size() == 0) //foglia
+                rightOffset=0;
+            else
+                rightOffset=Math.max(Children.get(Children.size() - 1).getRightOffset() + ((getUpLine() - getBaseWidth()) / 2),0);
+            return rightOffset;
+        }
+    }
+    void Refactor()
+    {
+        baseLine=FIELD_UNSET;
+        leftOffset=FIELD_UNSET;
+        rightOffset=FIELD_UNSET;
+        maxWidth=FIELD_UNSET;
+        for(Node n:Children)
+            n.Refactor();
+    }
+
+    void Resize()
+    {
+        int i;
+        float interval=0; //intervallo di spazio da sommare nella creazione dei figli
+        float spaceSize= DrawActivity.spaceSize;
+        int childNo=Children.size();
+        if (childNo!=0)
+        {
+
+            ruleView.setText(ruleName);
+            ruleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, DrawActivity.textSize / 2);
+            RelativeLayout.LayoutParams intlp=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            intlp.addRule(RelativeLayout.RIGHT_OF,view.getId());
+            int sum=0;
+            sum+=F.height();
+            Node tmp=Father;
+            while (tmp!=null)
+            {
+                sum+=tmp.F.height();
+                tmp=tmp.Father;
+            }
+            intlp.setMargins(0,0,0,sum);
+            intlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
+            ruleView.setLayoutParams(intlp);
+        }
+        for (i=0;i<childNo;i++) {
+            Node newChild=Children.get(i);
+            RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            TextView childView=Children.get(i).view;
+            lp.addRule(RelativeLayout.ABOVE,view.getId());
+            if (i==0) //first child
+            {
+                float leftPos= view.getLeft()-Math.max((newChild.getLineWidth()-newChild.getBaseWidth())/2,0);
+                if (getLineWidth()>getUpLine())
+                    leftPos+=((getLineWidth()-getUpLine())/2);
+                lp.setMargins(Math.round(leftPos), 0, 0, 0);
+                childView.setLeft(Math.round(leftPos));
+            }
+            else {
+                lp.setMargins(Math.round(view.getLeft() + interval), 0, 0, 0);
+                childView.setLeft(Math.round(view.getLeft() + interval));
+            }
+            childView.setLayoutParams(lp);
+            childView.setTextSize(TypedValue.COMPLEX_UNIT_PX, DrawActivity.textSize);
+
+            if(newChild.status==CANCELED || newChild.status==FAKE_CANCELED)
+                childView.setWidth((int) ((newChild.F.sizeDeleted())));
+            else
+                childView.setWidth(Math.round(newChild.getLineWidth()));
+
+            newChild.Resize();
+
+            if (i!=childNo-1) //l'ultimo figlio non ha intervalli
+            {
+                float leftOverflow=(Children.get(i+1).getLineWidth()-Children.get(i+1).getBaseWidth())/2;
+                interval += (newChild.getBaseWidth()+newChild.getRightOffset()+Children.get(i+1).getLeftOffset()-(leftOverflow));
+                interval+=spaceSize;
+                if (i!=0) //devo sommare anche il leftOverflow del nuovo figlio
+                    interval+=newChild.getLeftOffset();
+            }
+
+        }
+
+    }
+
+    public int treeHeight()
+    {
+        int res=0,tmp;
+        for (Node n:Children)
+        {
+            tmp=n.treeHeight();
+            if (tmp>res)
+                res=tmp;
+        }
+        return res+1;
+    }
+    public boolean isCorrect()
+    {
+        if (status==FAKE || status==FAKE_CANCELED || status==FAKE_CLOSED)
+            return false;
+        else for (Node n:Children)
+            if (!n.isCorrect())
+                return false;
+        return true;
+
+    }
+    public void Clean()
+    {
+        global.removeAllViews();
+    }
+
+    public void Draw()
+    {
+        int i;
+        float interval=0; //intervallo di spazio da sommare nella creazione dei figli
+        float spaceSize= DrawActivity.spaceSize;
+        int childNo=Children.size();
+        if (childNo==0) //foglia: possibile ramo dimostrato
+        {
+            view.setBorders(null); //le foglie non hanno overline
+            if (status!=OPEN && status!=FAKE) { //nodo chiuso
+                view.setTextColor(Color.GRAY);
+                if (hasFocus) //avevo il focus: provo a darlo ad uno dei miei fratelli
+                {
+                    if (!(Father.searchFocus(this))) {
+                        DrawActivity.finishedTree(view.getContext());
+                        return;
+                    }
+                    hasFocus = false;
+                }
+                if (status==CANCELED || status==FAKE_CANCELED) { //nodo cancellato
+                    view.setWidth((int) F.sizeDeleted());
+                    view.setText("[" + view.getText() + "]");
+                    view.setOnClickListener(null); //rimuove eventuali listener per evitare il proseguimento dell'albero
+                }
+                return;
+            }
+            if (hasFocus && DrawActivity.selectedNode!=this)
+                handler.onClick(view);
+            else if (hasFocus) //hasFocus: must be colored red anyway
+                view.setTextColor(Color.RED);
+            return;
+        }
+
+        ruleView.setText(ruleName);
+        ruleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, DrawActivity.textSize / 2);
+        RelativeLayout.LayoutParams intlp=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        intlp.addRule(RelativeLayout.RIGHT_OF,view.getId());
+        int sum=0;
+        sum+=F.height();
+        Node tmp=Father;
+        while (tmp!=null)
+        {
+            sum+=tmp.F.height();
+            tmp=tmp.Father;
+        }
+        intlp.setMargins(0,0,0,sum);
+        intlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
+        ruleView.setLayoutParams(intlp);
+        global.addView(ruleView);
+
+        /////////////////
+
+
+        hasFocus=false;
+        for (i=0;i<childNo;i++) {
+            final Node newChild=Children.get(i);
+            RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            final BorderedTextView childView=new BorderedTextView(view.getContext());
+            childView.setBorders(DrawActivity.b);
+            lp.addRule(RelativeLayout.ABOVE, view.getId());
+            if (i==0) //first child
+            {
+                float leftPos= view.getLeft()-Math.max((newChild.getLineWidth()-newChild.getBaseWidth())/2,0);
+                if (getLineWidth()>getUpLine())
+                    leftPos+=((getLineWidth()-getUpLine())/2);
+
+                lp.setMargins(Math.round(leftPos), 0, 0, 0);
+                childView.setLeft(Math.round(leftPos));
+            }
+            else {
+                lp.setMargins(Math.round(view.getLeft() + interval), 0, 0, 0);
+                childView.setLeft(Math.round(view.getLeft() + interval));
+            }
+            childView.setLayoutParams(lp);
+            childView.setId(DrawActivity.globalId++);
+            childView.setText(newChild.F.toString());
+            childView.setTextSize(TypedValue.COMPLEX_UNIT_PX, DrawActivity.textSize);
+            childView.setGravity(Gravity.CENTER); //formula al centro della sua overline
+            childView.setWidth(Math.round(newChild.getLineWidth()));
+            global.addView(childView);
+            childView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+                @Override
+                public void onGlobalLayout() {
+                    newChild.setView(childView,global);
+                    if(newChild.handler==null)
+                        newChild.handler=new touchnodeHandler(newChild);
+                    newChild.view.setOnClickListener(newChild.handler);
+                    childView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                    newChild.Draw();
+                }
+            });
+            if (i!=childNo-1) //l'ultimo figlio non ha intervalli
+            {
+                float leftOverflow=Math.max((Children.get(i+1).getLineWidth()-Children.get(i+1).getBaseWidth())/2,0);
+                interval += (newChild.getBaseWidth()+newChild.getRightOffset()+Children.get(i+1).getLeftOffset()-(leftOverflow));
+                interval+=spaceSize;
+                if (i!=0) //devo sommare anche il leftOverflow del nuovo figlio
+                    interval+=newChild.getLeftOffset();
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/mainActivity/src/com/example/furt/myapplication/RuleAndElimination.java b/mainActivity/src/com/example/furt/myapplication/RuleAndElimination.java
new file mode 100755 (executable)
index 0000000..5b2c5d4
--- /dev/null
@@ -0,0 +1,43 @@
+package com.example.furt.myapplication;
+
+import java.util.ArrayList;
+import java.util.List;
+public class RuleAndElimination implements EliminationRule
+{
+    String ruleName;
+    public String getName()
+    {
+        return ruleName;
+    }
+    FormulaAnd Fn;
+    RuleAndElimination(FormulaAnd F){
+        Fn=F;
+        ruleName="∧e";
+    }
+    public Node createNodes(Formula F,askFormula ask)
+    {
+            Formula C;
+            if (F==null)
+                C=ask.Ask();
+            else
+                C=F;
+            Node cNode=new Node(C);
+            if ((C.toString().equals(Fn.leftF.toString())) || (C.toString().equals(Fn.rightF.toString()))) //I can return leftAnd rule or rightAnd rule
+            {
+                cNode.addChild(new Node(Fn));
+                return cNode;
+            }
+            Node elNode=new Node(Fn);
+            List<Formula> HP=new ArrayList<Formula>();
+            HP.add(Fn.leftF);
+            HP.add(Fn.rightF);
+            cNode.addHPFormula(HP,true);
+            Node rNode=new Node(C);
+            rNode.addChild(elNode);
+            rNode.addChild(cNode);
+            rNode.ruleName=ruleName;
+            return rNode;
+    }
+}
+
+
diff --git a/mainActivity/src/com/example/furt/myapplication/RuleBotElimination.java b/mainActivity/src/com/example/furt/myapplication/RuleBotElimination.java
new file mode 100755 (executable)
index 0000000..83a54fd
--- /dev/null
@@ -0,0 +1,25 @@
+package com.example.furt.myapplication;
+
+public class RuleBotElimination implements EliminationRule
+{
+    String ruleName;
+    public String getName()
+    {
+        return ruleName;
+    }
+    FormulaBOT Fn;
+    RuleBotElimination(FormulaBOT F)
+    {
+        Fn=F;
+        ruleName="⊥e";
+    }
+    public Node createNodes(Formula F,askFormula ask)
+    {
+        Formula C=ask.Ask();
+        Node elNode=new Node(Fn);
+        Node rNode=new Node(C);
+        rNode.addChild(elNode);
+        rNode.ruleName=ruleName;
+        return rNode;
+    }
+}
\ No newline at end of file
diff --git a/mainActivity/src/com/example/furt/myapplication/RuleDialog.java b/mainActivity/src/com/example/furt/myapplication/RuleDialog.java
new file mode 100755 (executable)
index 0000000..6bcd7bb
--- /dev/null
@@ -0,0 +1,131 @@
+package com.example.furt.myapplication;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+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.view.ViewTreeObserver;
+import android.widget.RelativeLayout;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RuleDialog extends DialogFragment {
+    List<IntroductionRule> rules;
+    static Node selectedRule;
+    boolean showAllRules;
+    public RuleDialog(List<IntroductionRule> r)
+    {
+        selectedRule=null;
+        rules=new ArrayList<IntroductionRule>();
+        rules.addAll(r);
+        showAllRules=false;
+    }
+    @Override
+    public Dialog onCreateDialog(final Bundle savedInstanceState) {
+        // Use the Builder class for convenient dialog construction
+        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        LayoutInflater inflater=getActivity().getLayoutInflater();
+        View view=inflater.inflate(R.layout.ruledialog,null);
+        RelativeLayout layout=(RelativeLayout)((ViewGroup)((ViewGroup)view).getChildAt(0)).getChildAt(0);
+        int ruleInterval=50;
+        int i=0;
+        for (i=0;i<rules.size();i++) {
+            IntroductionRule rule=rules.get(i);
+            if (!showAllRules && rule.getPriority()==0)
+                continue; //only high priority: skip this node
+            final Node drawNode = rule.createNodes(new askFormula());
+            BorderedTextView t = new BorderedTextView(layout.getContext());
+            t.setId(DrawActivity.globalId);
+            DrawActivity.globalId++;
+            drawNode.setView(t, layout);
+            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            lp.setMargins(ruleInterval, 0, 0, 0);
+            ruleInterval+=2*drawNode.getMaxWidth();
+            lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, drawNode.view.getId());
+            drawNode.view.setLayoutParams(lp);
+            drawNode.view.setBorders(DrawActivity.b);
+            drawNode.view.setTextSize(TypedValue.COMPLEX_UNIT_PX, DrawActivity.textSize);
+            drawNode.view.setWidth(Math.round(drawNode.getLineWidth())); //setto la larghezza della view al contenuto della linea
+            drawNode.view.setGravity(Gravity.CENTER); //formula al centro della sua overline
+            drawNode.view.setText(drawNode.F.toString()); //setta il contenuto della formula
+            drawNode.global.addView(drawNode.view);
+            drawNode.handler=new DialogTouchHandler(drawNode);
+            for (Node n:drawNode.Children) {
+                n.handler = new DialogTouchHandler(drawNode);
+            }
+            //inserisco un listener a rootView da attivare quando sono state fissate le coordinate nel RelativeLayout
+            drawNode.view.getViewTreeObserver().addOnGlobalLayoutListener(
+                    new ViewTreeObserver.OnGlobalLayoutListener() {
+                        @Override
+                        public void onGlobalLayout() {
+                            drawNode.global.setPadding(0, 0, (int) Math.max(drawNode.getRightOffset(), 50), 0); //MAXWIDTH non provoca lo scroll involontario dello schermo.
+                            drawNode.global.getLayoutParams().height = (int) Math.max(100, drawNode.getMaxHeight());
+                            drawNode.global.requestLayout();
+                            drawNode.view.setOnClickListener(drawNode.handler);
+                            drawNode.hasFocus = true;
+                            drawNode.view.getViewTreeObserver().removeOnGlobalLayoutListener(this); //rimuove il listener per evitare che l'albero sia creato ad ogni modifica del layout
+                            drawNode.Draw();
+                        }
+                    });
+        }
+        builder.setView(view);
+        builder.setTitle("Scegli una regola:")
+                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int id) {
+                        if (selectedRule == null) return;
+                        for (Node n : selectedRule.Children) {
+                            for (Hypothesis hp : n.NodeHP)
+                                hp.fromNode = DrawActivity.selectedNode; //le ipotesi dei nuovi figli provengono dal nodo in cui stanno per essere inserite
+                            n.addHPList(DrawActivity.selectedNode.NodeHP);
+                            n.handler = null;
+                            DrawActivity.selectedNode.addChild(n);
+                        }
+                        DrawActivity.selectedNode.hasFocus = false;
+                        DrawActivity.selectedNode.ruleName = selectedRule.Children.get(0).ruleName;
+                        DrawActivity.selectedNode.Children.get(0).hasFocus = true;
+                        DrawActivity.nmoves++;
+                        DrawActivity.rootNode.Clean();
+                        DrawActivity.startDraw();
+                        selectedRule=null;
+                    }
+                });
+        if (!showAllRules) {
+            builder.setNeutralButton("Mostra tutte", new DialogInterface.OnClickListener() {
+                public void onClick(DialogInterface dialog, int id) {
+                    showAllRules = true;
+                    reboot();
+                }
+            });
+        }
+        else {
+            builder.setNeutralButton("Nascondi", new DialogInterface.OnClickListener() {
+                public void onClick(DialogInterface dialog, int id) {
+                    showAllRules = false;
+                    reboot();
+                }
+            });
+        }
+        builder.setNegativeButton("Annulla", new DialogInterface.OnClickListener() {
+            public void onClick(DialogInterface dialog, int id) {
+                selectedRule=null;
+            }
+        });
+        // Create the AlertDialog object and return it
+        return builder.create();
+    }
+    void reboot()
+    {
+        selectedRule=null;
+        RuleDialog ruleDialog=new RuleDialog(rules);
+        ruleDialog.showAllRules=showAllRules;
+        ruleDialog.show(DrawActivity.fragmentManager, "CIAO");
+    }
+}
+
diff --git a/mainActivity/src/com/example/furt/myapplication/RuleImplElimination.java b/mainActivity/src/com/example/furt/myapplication/RuleImplElimination.java
new file mode 100755 (executable)
index 0000000..0c266dd
--- /dev/null
@@ -0,0 +1,35 @@
+package com.example.furt.myapplication;
+
+public class RuleImplElimination implements EliminationRule
+{
+    String ruleName;
+    public String getName()
+    {
+        return ruleName;
+    }
+    FormulaImpl Fn;
+    RuleImplElimination(FormulaImpl F)
+    {
+        Fn=F;
+        ruleName="⇒e";
+    }
+    public Node createNodes(Formula F,askFormula ask)
+    {
+        Formula C;
+        if (F==null) {
+            C=ask.Ask();
+            if (!(C.toString().equals(Fn.rightF.toString())))
+                return null;
+        }
+        else
+            if (!(F.toString().equals(Fn.rightF.toString())))
+                return null;
+            Node elNode=new Node(Fn);
+            Node lNode=new Node(Fn.leftF);
+            Node bNode=new Node(Fn.rightF);
+            bNode.addChild(elNode);
+            bNode.addChild(lNode);
+            bNode.ruleName=ruleName;
+            return bNode;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/RuleIntroduction.java b/mainActivity/src/com/example/furt/myapplication/RuleIntroduction.java
new file mode 100755 (executable)
index 0000000..67301e0
--- /dev/null
@@ -0,0 +1,34 @@
+package com.example.furt.myapplication;
+
+//Regole di introduzione per la deduzione top-down: la formula è sempre applicabile, per cui la regola si limita
+//a chiamare la callback e restituire il sottoalbero di nodi conseguente all'applicazione della regola
+public class RuleIntroduction implements IntroductionRule
+{
+    int priority;
+    Node tempRule;
+    String ruleName;
+    public RuleIntroduction(String name,int p)
+    {
+        ruleName=name; priority=p;
+    }
+    public String getName()
+    {
+        return ruleName;
+    }
+    public Node createNodes(askFormula ask)
+    {
+        Formula C=ask.Ask();
+        for (Node n:tempRule.Children)
+        {
+            if (n.F.toString().equals(" ")) //undefined formula
+                n.F=C;
+            n.ruleName=ruleName;
+        }
+        tempRule.ruleName=ruleName;
+        return tempRule;
+    }
+    public int getPriority()
+    {
+        return priority;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/RuleNotElimination.java b/mainActivity/src/com/example/furt/myapplication/RuleNotElimination.java
new file mode 100755 (executable)
index 0000000..ec5034b
--- /dev/null
@@ -0,0 +1,33 @@
+package com.example.furt.myapplication;
+
+public class RuleNotElimination implements EliminationRule
+{
+    String ruleName;
+    public String getName()
+    {
+        return ruleName;
+    }
+    FormulaNot Fn;
+    RuleNotElimination(FormulaNot F)
+    {
+        Fn=F;
+        ruleName="¬e";
+    }
+    public Node createNodes(Formula F,askFormula ask)
+    {
+        Formula C=ask.Ask();
+        if ((C.toString().equals("⊥"))&&(F==null ||F==Fn.Operand)) //top-down con nodo attuale bottom o bottom-up con nodi attuali Fn e !Fn
+        {
+            Node elNode=new Node(Fn);
+            Node cNode=new Node(Fn.Operand);
+            Node rNode=new Node(C);
+            rNode.addChild(elNode);
+            rNode.addChild(cNode);
+            rNode.ruleName=ruleName;
+            return rNode;
+        }
+        else
+            return null;
+    }
+}
+
diff --git a/mainActivity/src/com/example/furt/myapplication/RuleOrElimination.java b/mainActivity/src/com/example/furt/myapplication/RuleOrElimination.java
new file mode 100755 (executable)
index 0000000..3d678b7
--- /dev/null
@@ -0,0 +1,42 @@
+package com.example.furt.myapplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RuleOrElimination implements EliminationRule
+{
+    String ruleName;
+    public String getName()
+    {
+        return ruleName;
+    }
+    FormulaOr Fn;
+    RuleOrElimination(FormulaOr F)
+    {
+        Fn=F;
+        ruleName="∨e";
+    }
+    public Node createNodes(Formula F,askFormula ask)
+    {
+        Formula C;
+        if (F==null)
+            C=ask.Ask();
+        else
+            C=F;
+            Node elNode=new Node(Fn);
+            Node c1Node=new Node(C);
+            Node c2Node=new Node(C);
+            List<Formula> HP1=new ArrayList<Formula>();
+            List<Formula> HP2=new ArrayList<Formula>();
+            HP1.add(Fn.leftF);
+            HP2.add(Fn.rightF);
+            c1Node.addHPFormula(HP1,true);
+            c2Node.addHPFormula(HP2,true);
+            Node rNode=new Node(C);
+            rNode.addChild(elNode);
+            rNode.addChild(c1Node);
+            rNode.addChild(c2Node);
+            rNode.ruleName=ruleName;
+            return rNode;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/ServerData.java b/mainActivity/src/com/example/furt/myapplication/ServerData.java
new file mode 100755 (executable)
index 0000000..2466f27
--- /dev/null
@@ -0,0 +1,40 @@
+package com.example.furt.myapplication;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+// simple class that just has one member property as an example
+public class ServerData implements Parcelable {
+    private static List<String> L;
+
+    ServerData(List<String> List)
+    {
+        L=List;
+    }
+    /* everything below here is for implementing Parcelable */
+
+    // 99.9% of the time you can just ignore this
+    public int describeContents() {
+        return 0;
+    }
+
+    // write your object's data to the passed-in Parcel
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeList(L);
+    }
+
+    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
+    public static final Creator<ServerData> CREATOR = new Creator<ServerData>() {
+        public ServerData createFromParcel(Parcel in) {
+            return new ServerData(L);
+        }
+
+        public ServerData[] newArray(int size) {
+            return new ServerData[size];
+        }
+    };
+
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/Tree.java b/mainActivity/src/com/example/furt/myapplication/Tree.java
new file mode 100755 (executable)
index 0000000..87c2b28
--- /dev/null
@@ -0,0 +1,12 @@
+package com.example.furt.myapplication;
+
+public interface Tree
+{
+        float getBaseWidth();
+        float getMaxWidth();
+        float getLineWidth();
+        float getUpLine();
+        float getLeftOffset() ;
+        float getRightOffset();
+        void Draw();
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/TwoDScrollView.java b/mainActivity/src/com/example/furt/myapplication/TwoDScrollView.java
new file mode 100755 (executable)
index 0000000..8108428
--- /dev/null
@@ -0,0 +1,1129 @@
+package com.example.furt.myapplication;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.FocusFinder;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.animation.AnimationUtils;
+import android.widget.FrameLayout;
+import android.widget.Scroller;
+
+import java.util.List;
+
+
+/**
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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.
+ *
+*
+ * Revised 5/19/2010 by GORGES
+ * Now supports two-dimensional view scrolling
+ * http://GORGES.us
+ */
+
+/**
+ * Layout container for a view hierarchy that can be scrolled by the user,
+ * allowing it to be larger than the physical display.  A TwoDScrollView
+ * is a {@link android.widget.FrameLayout}, meaning you should place one child in it
+ * containing the entire contents to scroll; this child may itself be a layout
+ * manager with a complex hierarchy of objects.  A child that is often used
+ * is a {@link android.widget.LinearLayout} in a vertical orientation, presenting a vertical
+ * array of top-level items that the user can scroll through.
+ *
+ * <p>The {@link android.widget.TextView} class also
+ * takes care of its own scrolling, so does not require a TwoDScrollView, but
+ * using the two together is possible to achieve the effect of a text view
+ * within a larger container.
+ */
+
+public class TwoDScrollView extends FrameLayout {
+    static final int ANIMATED_SCROLL_GAP = 250;
+    static final float MAX_SCROLL_FACTOR = 0.5f;
+
+    private long mLastScroll;
+
+    private final Rect mTempRect = new Rect();
+    private Scroller mScroller;
+
+    /*
+     * Flag to indicate that we are moving focus ourselves. This is so the
+     * code that watches for focus changes initiated outside this TwoDScrollView
+     * knows that it does not have to do anything.
+     */
+    private boolean mTwoDScrollViewMovedFocus;
+
+    /*
+     * Position of the last motion event.
+     */
+    private float mLastMotionY;
+    private float mLastMotionX;
+
+    /*
+     * True when the layout has changed but the traversal has not come through yet.
+     * Ideally the view hierarchy would keep track of this for us.
+     */
+    private boolean mIsLayoutDirty = true;
+
+    /*
+     * The child to give focus to in the event that a child has requested focus while the
+     * layout is dirty. This prevents the scroll from being wrong if the child has not been
+     * laid out before requesting focus.
+     */
+    private View mChildToScrollTo = null;
+
+    /*
+     * True if the user is currently dragging this TwoDScrollView around. This is
+     * not the same as 'is being flinged', which can be checked by
+     * mScroller.isFinished() (flinging begins when the user lifts his finger).
+     */
+    private boolean mIsBeingDragged = false;
+
+    /*
+     * Determines speed during touch scrolling
+     */
+    private VelocityTracker mVelocityTracker;
+
+    /*
+     * Whether arrow scrolling is animated.
+     */
+    private int mTouchSlop;
+    private int mMinimumVelocity;
+    private int mMaximumVelocity;
+
+    public TwoDScrollView(Context context) {
+        super(context);
+        initTwoDScrollView();
+    }
+
+    public TwoDScrollView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        initTwoDScrollView();
+    }
+
+    public TwoDScrollView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        initTwoDScrollView();
+    }
+
+    @Override
+    protected float getTopFadingEdgeStrength() {
+        if (getChildCount() == 0) {
+            return 0.0f;
+        }
+        final int length = getVerticalFadingEdgeLength();
+        if (getScrollY() < length) {
+            return getScrollY() / (float) length;
+        }
+        return 1.0f;
+    }
+
+    @Override
+    protected float getBottomFadingEdgeStrength() {
+        if (getChildCount() == 0) {
+            return 0.0f;
+        }
+        final int length = getVerticalFadingEdgeLength();
+        final int bottomEdge = getHeight() - getPaddingBottom();
+        final int span = getChildAt(0).getBottom() - getScrollY() - bottomEdge;
+        if (span < length) {
+            return span / (float) length;
+        }
+        return 1.0f;
+    }
+
+    @Override
+    protected float getLeftFadingEdgeStrength() {
+        if (getChildCount() == 0) {
+            return 0.0f;
+        }
+        final int length = getHorizontalFadingEdgeLength();
+        if (getScrollX() < length) {
+            return getScrollX() / (float) length;
+        }
+        return 1.0f;
+    }
+
+    @Override
+    protected float getRightFadingEdgeStrength() {
+        if (getChildCount() == 0) {
+            return 0.0f;
+        }
+        final int length = getHorizontalFadingEdgeLength();
+        final int rightEdge = getWidth() - getPaddingRight();
+        final int span = getChildAt(0).getRight() - getScrollX() - rightEdge;
+        if (span < length) {
+            return span / (float) length;
+        }
+        return 1.0f;
+    }
+
+    /**
+     * @return The maximum amount this scroll view will scroll in response to
+     *   an arrow event.
+     */
+    public int getMaxScrollAmountVertical() {
+        return (int) (MAX_SCROLL_FACTOR * getHeight());
+    }
+    public int getMaxScrollAmountHorizontal() {
+        return (int) (MAX_SCROLL_FACTOR * getWidth());
+    }
+
+    private void initTwoDScrollView() {
+        mScroller = new Scroller(getContext());
+        setFocusable(true);
+        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
+        setWillNotDraw(false);
+        final ViewConfiguration configuration = ViewConfiguration.get(getContext());
+        mTouchSlop = configuration.getScaledTouchSlop();
+        mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
+        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
+    }
+
+    @Override
+    public void addView(View child) {
+        if (getChildCount() > 0) {
+            throw new IllegalStateException("TwoDScrollView can host only one direct child");
+        }
+        super.addView(child);
+    }
+
+    @Override
+    public void addView(View child, int index) {
+        if (getChildCount() > 0) {
+            throw new IllegalStateException("TwoDScrollView can host only one direct child");
+        }
+        super.addView(child, index);
+    }
+
+    @Override
+    public void addView(View child, ViewGroup.LayoutParams params) {
+        if (getChildCount() > 0) {
+            throw new IllegalStateException("TwoDScrollView can host only one direct child");
+        }
+        super.addView(child, params);
+    }
+
+    @Override
+    public void addView(View child, int index, ViewGroup.LayoutParams params) {
+        if (getChildCount() > 0) {
+            throw new IllegalStateException("TwoDScrollView can host only one direct child");
+        }
+        super.addView(child, index, params);
+    }
+
+    /**
+     * @return Returns true this TwoDScrollView can be scrolled
+     */
+    private boolean canScroll() {
+        View child = getChildAt(0);
+        if (child != null) {
+            int childHeight = child.getHeight();
+            int childWidth = child.getWidth();
+            return (getHeight() < childHeight + getPaddingTop() + getPaddingBottom()) ||
+                    (getWidth() < childWidth + getPaddingLeft() + getPaddingRight());
+        }
+        return false;
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        // Let the focused view and/or our descendants get the key first
+        boolean handled = super.dispatchKeyEvent(event);
+        if (handled) {
+            return true;
+        }
+        return executeKeyEvent(event);
+    }
+
+    /**
+     * You can call this function yourself to have the scroll view perform
+     * scrolling from a key event, just as if the event had been dispatched to
+     * it by the view hierarchy.
+     *
+     * @param event The key event to execute.
+     * @return Return true if the event was handled, else false.
+     */
+    public boolean executeKeyEvent(KeyEvent event) {
+        mTempRect.setEmpty();
+        if (!canScroll()) {
+            if (isFocused()) {
+                View currentFocused = findFocus();
+                if (currentFocused == this) currentFocused = null;
+                View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, View.FOCUS_DOWN);
+                return nextFocused != null && nextFocused != this && nextFocused.requestFocus(View.FOCUS_DOWN);
+            }
+            return false;
+        }
+        boolean handled = false;
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            switch (event.getKeyCode()) {
+                case KeyEvent.KEYCODE_DPAD_UP:
+                    if (!event.isAltPressed()) {
+                        handled = arrowScroll(View.FOCUS_UP, false);
+                    } else {
+                        handled = fullScroll(View.FOCUS_UP, false);
+                    }
+                    break;
+                case KeyEvent.KEYCODE_DPAD_DOWN:
+                    if (!event.isAltPressed()) {
+                        handled = arrowScroll(View.FOCUS_DOWN, false);
+                    } else {
+                        handled = fullScroll(View.FOCUS_DOWN, false);
+                    }
+                    break;
+                case KeyEvent.KEYCODE_DPAD_LEFT:
+                    if (!event.isAltPressed()) {
+                        handled = arrowScroll(View.FOCUS_LEFT, true);
+                    } else {
+                        handled = fullScroll(View.FOCUS_LEFT, true);
+                    }
+                    break;
+                case KeyEvent.KEYCODE_DPAD_RIGHT:
+                    if (!event.isAltPressed()) {
+                        handled = arrowScroll(View.FOCUS_RIGHT, true);
+                    } else {
+                        handled = fullScroll(View.FOCUS_RIGHT, true);
+                    }
+                    break;
+            }
+        }
+        return handled;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+   /*
+   * This method JUST determines whether we want to intercept the motion.
+   * If we return true, onMotionEvent will be called and we do the actual
+   * scrolling there.
+   *
+   * Shortcut the most recurring case: the user is in the dragging
+   * state and he is moving his finger.  We want to intercept this
+   * motion.
+   */
+        final int action = ev.getAction();
+        if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) {
+            return true;
+        }
+        if (!canScroll()) {
+            mIsBeingDragged = false;
+            return false;
+        }
+        final float y = ev.getY();
+        final float x = ev.getX();
+        switch (action) {
+            case MotionEvent.ACTION_MOVE:
+       /*
+       * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
+       * whether the user has moved far enough from his original down touch.
+       */
+       /*
+       * Locally do absolute value. mLastMotionY is set to the y value
+       * of the down event.
+       */
+                final int yDiff = (int) Math.abs(y - mLastMotionY);
+                final int xDiff = (int) Math.abs(x - mLastMotionX);
+                if (yDiff > mTouchSlop || xDiff > mTouchSlop) {
+                    mIsBeingDragged = true;
+                }
+                break;
+
+            case MotionEvent.ACTION_DOWN:
+       /* Remember location of down touch */
+                mLastMotionY = y;
+                mLastMotionX = x;
+
+       /*
+       * If being flinged and user touches the screen, initiate drag;
+       * otherwise don't.  mScroller.isFinished should be false when
+       * being flinged.
+       */
+                mIsBeingDragged = !mScroller.isFinished();
+                break;
+
+            case MotionEvent.ACTION_CANCEL:
+            case MotionEvent.ACTION_UP:
+       /* Release the drag */
+                mIsBeingDragged = false;
+                break;
+        }
+
+   /*
+   * The only time we want to intercept motion events is if we are in the
+   * drag mode.
+   */
+        return mIsBeingDragged;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+
+        if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
+            // Don't handle edge touches immediately -- they may actually belong to one of our
+            // descendants.
+            return false;
+        }
+
+        if (!canScroll()) {
+            return false;
+        }
+
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+        mVelocityTracker.addMovement(ev);
+
+        final int action = ev.getAction();
+        final float y = ev.getY();
+        final float x = ev.getX();
+
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+       /*
+       * If being flinged and user touches, stop the fling. isFinished
+       * will be false if being flinged.
+       */
+                if (!mScroller.isFinished()) {
+                    mScroller.abortAnimation();
+                }
+
+                // Remember where the motion event started
+                mLastMotionY = y;
+                mLastMotionX = x;
+                break;
+            case MotionEvent.ACTION_MOVE:
+                // Scroll to follow the motion event
+                int deltaX = (int) (mLastMotionX - x);
+                int deltaY = (int) (mLastMotionY - y);
+                mLastMotionX = x;
+                mLastMotionY = y;
+
+                if (deltaX < 0) {
+                    if (getScrollX() < 0) {
+                        deltaX = 0;
+                    }
+                } else if (deltaX > 0) {
+                    final int rightEdge = getWidth() - getPaddingRight();
+                    final int availableToScroll = getChildAt(0).getRight() - getScrollX() - rightEdge;
+                    if (availableToScroll > 0) {
+                        deltaX = Math.min(availableToScroll, deltaX);
+                    } else {
+                        deltaX = 0;
+                    }
+                }
+                if (deltaY < 0) {
+                    if (getScrollY() < 0) {
+                        deltaY = 0;
+                    }
+                } else if (deltaY > 0) {
+                    final int bottomEdge = getHeight() - getPaddingBottom();
+                    final int availableToScroll = getChildAt(0).getBottom() - getScrollY() - bottomEdge;
+                    if (availableToScroll > 0) {
+                        deltaY = Math.min(availableToScroll, deltaY);
+                    } else {
+                        deltaY = 0;
+                    }
+                }
+                if (deltaY != 0 || deltaX != 0)
+                    scrollBy(deltaX, deltaY);
+                break;
+            case MotionEvent.ACTION_UP:
+                final VelocityTracker velocityTracker = mVelocityTracker;
+                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+                int initialXVelocity = (int) velocityTracker.getXVelocity();
+                int initialYVelocity = (int) velocityTracker.getYVelocity();
+                if ((Math.abs(initialXVelocity) + Math.abs(initialYVelocity) > mMinimumVelocity) && getChildCount() > 0) {
+                    fling(-initialXVelocity, -initialYVelocity);
+                }
+                if (mVelocityTracker != null) {
+                    mVelocityTracker.recycle();
+                    mVelocityTracker = null;
+                }
+        }
+        return true;
+    }
+
+    /**
+     * Finds the next focusable component that fits in this View's bounds
+     * (excluding fading edges) pretending that this View's top is located at
+     * the parameter top.
+     *
+     * @param topFocus           look for a candidate is the one at the top of the bounds
+     *                           if topFocus is true, or at the bottom of the bounds if topFocus is
+     *                           false
+     * @param top                the top offset of the bounds in which a focusable must be
+     *                           found (the fading edge is assumed to start at this position)
+     * @param preferredFocusable the View that has highest priority and will be
+     *                           returned if it is within my bounds (null is valid)
+     * @return the next focusable component in the bounds or null if none can be
+     *         found
+     */
+    private View findFocusableViewInMyBounds(final boolean topFocus, final int top, final boolean leftFocus, final int left, View preferredFocusable) {
+   /*
+   * The fading edge's transparent side should be considered for focus
+   * since it's mostly visible, so we divide the actual fading edge length
+   * by 2.
+   */
+        final int verticalFadingEdgeLength = getVerticalFadingEdgeLength() / 2;
+        final int topWithoutFadingEdge = top + verticalFadingEdgeLength;
+        final int bottomWithoutFadingEdge = top + getHeight() - verticalFadingEdgeLength;
+        final int horizontalFadingEdgeLength = getHorizontalFadingEdgeLength() / 2;
+        final int leftWithoutFadingEdge = left + horizontalFadingEdgeLength;
+        final int rightWithoutFadingEdge = left + getWidth() - horizontalFadingEdgeLength;
+
+        if ((preferredFocusable != null)
+                && (preferredFocusable.getTop() < bottomWithoutFadingEdge)
+                && (preferredFocusable.getBottom() > topWithoutFadingEdge)
+                && (preferredFocusable.getLeft() < rightWithoutFadingEdge)
+                && (preferredFocusable.getRight() > leftWithoutFadingEdge)) {
+            return preferredFocusable;
+        }
+        return findFocusableViewInBounds(topFocus, topWithoutFadingEdge, bottomWithoutFadingEdge, leftFocus, leftWithoutFadingEdge, rightWithoutFadingEdge);
+    }
+
+    /**
+     * Finds the next focusable component that fits in the specified bounds.
+     * </p>
+     *
+     * @param topFocus look for a candidate is the one at the top of the bounds
+     *                 if topFocus is true, or at the bottom of the bounds if topFocus is
+     *                 false
+     * @param top      the top offset of the bounds in which a focusable must be
+     *                 found
+     * @param bottom   the bottom offset of the bounds in which a focusable must
+     *                 be found
+     * @return the next focusable component in the bounds or null if none can
+     *         be found
+     */
+    private View findFocusableViewInBounds(boolean topFocus, int top, int bottom, boolean leftFocus, int left, int right) {
+        List<View> focusables = getFocusables(View.FOCUS_FORWARD);
+        View focusCandidate = null;
+
+   /*
+   * A fully contained focusable is one where its top is below the bound's
+   * top, and its bottom is above the bound's bottom. A partially
+   * contained focusable is one where some part of it is within the
+   * bounds, but it also has some part that is not within bounds.  A fully contained
+   * focusable is preferred to a partially contained focusable.
+   */
+        boolean foundFullyContainedFocusable = false;
+
+        int count = focusables.size();
+        for (int i = 0; i < count; i++) {
+            View view = focusables.get(i);
+            int viewTop = view.getTop();
+            int viewBottom = view.getBottom();
+            int viewLeft = view.getLeft();
+            int viewRight = view.getRight();
+
+            if (top < viewBottom && viewTop < bottom && left < viewRight && viewLeft < right) {
+       /*
+       * the focusable is in the target area, it is a candidate for
+       * focusing
+       */
+                final boolean viewIsFullyContained = (top < viewTop) && (viewBottom < bottom) && (left < viewLeft) && (viewRight < right);
+                if (focusCandidate == null) {
+         /* No candidate, take this one */
+                    focusCandidate = view;
+                    foundFullyContainedFocusable = viewIsFullyContained;
+                } else {
+                    final boolean viewIsCloserToVerticalBoundary =
+                            (topFocus && viewTop < focusCandidate.getTop()) ||
+                                    (!topFocus && viewBottom > focusCandidate.getBottom());
+                    final boolean viewIsCloserToHorizontalBoundary =
+                            (leftFocus && viewLeft < focusCandidate.getLeft()) ||
+                                    (!leftFocus && viewRight > focusCandidate.getRight());
+                    if (foundFullyContainedFocusable) {
+                        if (viewIsFullyContained && viewIsCloserToVerticalBoundary && viewIsCloserToHorizontalBoundary) {
+             /*
+              * We're dealing with only fully contained views, so
+              * it has to be closer to the boundary to beat our
+              * candidate
+              */
+                            focusCandidate = view;
+                        }
+                    } else {
+                        if (viewIsFullyContained) {
+             /* Any fully contained view beats a partially contained view */
+                            focusCandidate = view;
+                            foundFullyContainedFocusable = true;
+                        } else if (viewIsCloserToVerticalBoundary && viewIsCloserToHorizontalBoundary) {
+             /*
+              * Partially contained view beats another partially
+              * contained view if it's closer
+              */
+                            focusCandidate = view;
+                        }
+                    }
+                }
+            }
+        }
+        return focusCandidate;
+    }
+
+    /**
+     * <p>Handles scrolling in response to a "home/end" shortcut press. This
+     * method will scroll the view to the top or bottom and give the focus
+     * to the topmost/bottommost component in the new visible area. If no
+     * component is a good candidate for focus, this scrollview reclaims the
+     * focus.</p>
+     *
+     * @param direction the scroll direction: {@link android.view.View#FOCUS_UP}
+     *                  to go the top of the view or
+     *                  {@link android.view.View#FOCUS_DOWN} to go the bottom
+     * @return true if the key event is consumed by this method, false otherwise
+     */
+    public boolean fullScroll(int direction, boolean horizontal) {
+        if (!horizontal) {
+            boolean down = direction == View.FOCUS_DOWN;
+            int height = getHeight();
+            mTempRect.top = 0;
+            mTempRect.bottom = height;
+            if (down) {
+                int count = getChildCount();
+                if (count > 0) {
+                    View view = getChildAt(count - 1);
+                    mTempRect.bottom = view.getBottom();
+                    mTempRect.top = mTempRect.bottom - height;
+                }
+            }
+            return scrollAndFocus(direction, mTempRect.top, mTempRect.bottom, 0, 0, 0);
+        } else {
+            boolean right = direction == View.FOCUS_DOWN;
+            int width = getWidth();
+            mTempRect.left = 0;
+            mTempRect.right = width;
+            if (right) {
+                int count = getChildCount();
+                if (count > 0) {
+                    View view = getChildAt(count - 1);
+                    mTempRect.right = view.getBottom();
+                    mTempRect.left = mTempRect.right - width;
+                }
+            }
+            return scrollAndFocus(0, 0, 0, direction, mTempRect.top, mTempRect.bottom);
+        }
+    }
+
+    /**
+     * <p>Scrolls the view to make the area defined by <code>top</code> and
+     * <code>bottom</code> visible. This method attempts to give the focus
+     * to a component visible in this area. If no component can be focused in
+     * the new visible area, the focus is reclaimed by this scrollview.</p>
+     *
+     * @param direction the scroll direction: {@link android.view.View#FOCUS_UP}
+     *                  to go upward
+     *                  {@link android.view.View#FOCUS_DOWN} to downward
+     * @param top       the top offset of the new area to be made visible
+     * @param bottom    the bottom offset of the new area to be made visible
+     * @return true if the key event is consumed by this method, false otherwise
+     */
+    private boolean scrollAndFocus(int directionY, int top, int bottom, int directionX, int left, int right) {
+        boolean handled = true;
+        int height = getHeight();
+        int containerTop = getScrollY();
+        int containerBottom = containerTop + height;
+        boolean up = directionY == View.FOCUS_UP;
+        int width = getWidth();
+        int containerLeft = getScrollX();
+        int containerRight = containerLeft + width;
+        boolean leftwards = directionX == View.FOCUS_UP;
+        View newFocused = findFocusableViewInBounds(up, top, bottom, leftwards, left, right);
+        if (newFocused == null) {
+            newFocused = this;
+        }
+        if ((top >= containerTop && bottom <= containerBottom) || (left >= containerLeft && right <= containerRight)) {
+            handled = false;
+        } else {
+            int deltaY = up ? (top - containerTop) : (bottom - containerBottom);
+            int deltaX = leftwards ? (left - containerLeft) : (right - containerRight);
+            doScroll(deltaX, deltaY);
+        }
+        if (newFocused != findFocus() && newFocused.requestFocus(directionY)) {
+            mTwoDScrollViewMovedFocus = true;
+            mTwoDScrollViewMovedFocus = false;
+        }
+        return handled;
+    }
+
+    /**
+     * Handle scrolling in response to an up or down arrow click.
+     *
+     * @param direction The direction corresponding to the arrow key that was
+     *                  pressed
+     * @return True if we consumed the event, false otherwise
+     */
+    public boolean arrowScroll(int direction, boolean horizontal) {
+        View currentFocused = findFocus();
+        if (currentFocused == this) currentFocused = null;
+        View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction);
+        final int maxJump = horizontal ? getMaxScrollAmountHorizontal() : getMaxScrollAmountVertical();
+
+        if (!horizontal) {
+            if (nextFocused != null) {
+                nextFocused.getDrawingRect(mTempRect);
+                offsetDescendantRectToMyCoords(nextFocused, mTempRect);
+                int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+                doScroll(0, scrollDelta);
+                nextFocused.requestFocus(direction);
+            } else {
+                // no new focus
+                int scrollDelta = maxJump;
+                if (direction == View.FOCUS_UP && getScrollY() < scrollDelta) {
+                    scrollDelta = getScrollY();
+                } else if (direction == View.FOCUS_DOWN) {
+                    if (getChildCount() > 0) {
+                        int daBottom = getChildAt(0).getBottom();
+                        int screenBottom = getScrollY() + getHeight();
+                        if (daBottom - screenBottom < maxJump) {
+                            scrollDelta = daBottom - screenBottom;
+                        }
+                    }
+                }
+                if (scrollDelta == 0) {
+                    return false;
+                }
+                doScroll(0, direction == View.FOCUS_DOWN ? scrollDelta : -scrollDelta);
+            }
+        } else {
+            if (nextFocused != null) {
+                nextFocused.getDrawingRect(mTempRect);
+                offsetDescendantRectToMyCoords(nextFocused, mTempRect);
+                int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+                doScroll(scrollDelta, 0);
+                nextFocused.requestFocus(direction);
+            } else {
+                // no new focus
+                int scrollDelta = maxJump;
+                if (direction == View.FOCUS_UP && getScrollY() < scrollDelta) {
+                    scrollDelta = getScrollY();
+                } else if (direction == View.FOCUS_DOWN) {
+                    if (getChildCount() > 0) {
+                        int daBottom = getChildAt(0).getBottom();
+                        int screenBottom = getScrollY() + getHeight();
+                        if (daBottom - screenBottom < maxJump) {
+                            scrollDelta = daBottom - screenBottom;
+                        }
+                    }
+                }
+                if (scrollDelta == 0) {
+                    return false;
+                }
+                doScroll(direction == View.FOCUS_DOWN ? scrollDelta : -scrollDelta, 0);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Smooth scroll by a Y delta
+     *
+     * @param delta the number of pixels to scroll by on the Y axis
+     */
+    private void doScroll(int deltaX, int deltaY) {
+        if (deltaX != 0 || deltaY != 0) {
+            smoothScrollBy(deltaX, deltaY);
+        }
+    }
+
+    /**
+     * Like {@link android.view.View#scrollBy}, but scroll smoothly instead of immediately.
+     *
+     * @param dx the number of pixels to scroll by on the X axis
+     * @param dy the number of pixels to scroll by on the Y axis
+     */
+    public final void smoothScrollBy(int dx, int dy) {
+        long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
+        if (duration > ANIMATED_SCROLL_GAP) {
+            mScroller.startScroll(getScrollX(), getScrollY(), dx, dy);
+            awakenScrollBars(mScroller.getDuration());
+            invalidate();
+        } else {
+            if (!mScroller.isFinished()) {
+                mScroller.abortAnimation();
+            }
+            scrollBy(dx, dy);
+        }
+        mLastScroll = AnimationUtils.currentAnimationTimeMillis();
+    }
+
+    /**
+     * Like {@link #scrollTo}, but scroll smoothly instead of immediately.
+     *
+     * @param x the position where to scroll on the X axis
+     * @param y the position where to scroll on the Y axis
+     */
+    public final void smoothScrollTo(int x, int y) {
+        smoothScrollBy(x - getScrollX(), y - getScrollY());
+    }
+
+    /**
+     * <p>The scroll range of a scroll view is the overall height of all of its
+     * children.</p>
+     */
+    @Override
+    protected int computeVerticalScrollRange() {
+        int count = getChildCount();
+        return count == 0 ? getHeight() : (getChildAt(0)).getBottom();
+    }
+    @Override
+    protected int computeHorizontalScrollRange() {
+        int count = getChildCount();
+        return count == 0 ? getWidth() : (getChildAt(0)).getRight();
+    }
+
+    @Override
+    protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
+        ViewGroup.LayoutParams lp = child.getLayoutParams();
+        int childWidthMeasureSpec;
+        int childHeightMeasureSpec;
+
+        childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, getPaddingLeft() + getPaddingRight(), lp.width);
+        childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+
+        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+    }
+
+    @Override
+    protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
+        final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
+        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
+                getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin + widthUsed, lp.width);
+        final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.topMargin + lp.bottomMargin, MeasureSpec.UNSPECIFIED);
+
+        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+    }
+
+    @Override
+    public void computeScroll() {
+        if (mScroller.computeScrollOffset()) {
+            // This is called at drawing time by ViewGroup.  We don't want to
+            // re-show the scrollbars at this point, which scrollTo will do,
+            // so we replicate most of scrollTo here.
+            //
+            //         It's a little odd to call onScrollChanged from inside the drawing.
+            //
+            //         It is, except when you remember that computeScroll() is used to
+            //         animate scrolling. So unless we want to defer the onScrollChanged()
+            //         until the end of the animated scrolling, we don't really have a
+            //         choice here.
+            //
+            //         I agree.  The alternative, which I think would be worse, is to post
+            //         something and tell the subclasses later.  This is bad because there
+            //         will be a window where mScrollX/Y is different from what the app
+            //         thinks it is.
+            //
+            int oldX = getScrollX();
+            int oldY = getScrollY();
+            int x = mScroller.getCurrX();
+            int y = mScroller.getCurrY();
+            if (getChildCount() > 0) {
+                View child = getChildAt(0);
+                scrollTo(clamp(x, getWidth() - getPaddingRight() - getPaddingLeft(), child.getWidth()),
+                        clamp(y, getHeight() - getPaddingBottom() - getPaddingTop(), child.getHeight()));
+            } else {
+                scrollTo(x, y);
+            }
+            if (oldX != getScrollX() || oldY != getScrollY()) {
+                onScrollChanged(getScrollX(), getScrollY(), oldX, oldY);
+            }
+
+            // Keep on drawing until the animation has finished.
+            postInvalidate();
+        }
+    }
+
+    /**
+     * Scrolls the view to the given child.
+     *
+     * @param child the View to scroll to
+     */
+    private void scrollToChild(View child) {
+        child.getDrawingRect(mTempRect);
+   /* Offset from child's local coordinates to TwoDScrollView coordinates */
+        offsetDescendantRectToMyCoords(child, mTempRect);
+        int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+        if (scrollDelta != 0) {
+            scrollBy(0, scrollDelta);
+        }
+    }
+
+    /**
+     * If rect is off screen, scroll just enough to get it (or at least the
+     * first screen size chunk of it) on screen.
+     *
+     * @param rect      The rectangle.
+     * @param immediate True to scroll immediately without animation
+     * @return true if scrolling was performed
+     */
+    private boolean scrollToChildRect(Rect rect, boolean immediate) {
+        final int delta = computeScrollDeltaToGetChildRectOnScreen(rect);
+        final boolean scroll = delta != 0;
+        if (scroll) {
+            if (immediate) {
+                scrollBy(0, delta);
+            } else {
+                smoothScrollBy(0, delta);
+            }
+        }
+        return scroll;
+    }
+
+    /**
+     * Compute the amount to scroll in the Y direction in order to get
+     * a rectangle completely on the screen (or, if taller than the screen,
+     * at least the first screen size chunk of it).
+     *
+     * @param rect The rect.
+     * @return The scroll delta.
+     */
+    protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
+        if (getChildCount() == 0) return 0;
+        int height = getHeight();
+        int screenTop = getScrollY();
+        int screenBottom = screenTop + height;
+        int fadingEdge = getVerticalFadingEdgeLength();
+        // leave room for top fading edge as long as rect isn't at very top
+        if (rect.top > 0) {
+            screenTop += fadingEdge;
+        }
+
+        // leave room for bottom fading edge as long as rect isn't at very bottom
+        if (rect.bottom < getChildAt(0).getHeight()) {
+            screenBottom -= fadingEdge;
+        }
+        int scrollYDelta = 0;
+        if (rect.bottom > screenBottom && rect.top > screenTop) {
+            // need to move down to get it in view: move down just enough so
+            // that the entire rectangle is in view (or at least the first
+            // screen size chunk).
+            if (rect.height() > height) {
+                // just enough to get screen size chunk on
+                scrollYDelta += (rect.top - screenTop);
+            } else {
+                // get entire rect at bottom of screen
+                scrollYDelta += (rect.bottom - screenBottom);
+            }
+
+            // make sure we aren't scrolling beyond the end of our content
+            int bottom = getChildAt(0).getBottom();
+            int distanceToBottom = bottom - screenBottom;
+            scrollYDelta = Math.min(scrollYDelta, distanceToBottom);
+
+        } else if (rect.top < screenTop && rect.bottom < screenBottom) {
+            // need to move up to get it in view: move up just enough so that
+            // entire rectangle is in view (or at least the first screen
+            // size chunk of it).
+
+            if (rect.height() > height) {
+                // screen size chunk
+                scrollYDelta -= (screenBottom - rect.bottom);
+            } else {
+                // entire rect at top
+                scrollYDelta -= (screenTop - rect.top);
+            }
+
+            // make sure we aren't scrolling any further than the top our content
+            scrollYDelta = Math.max(scrollYDelta, -getScrollY());
+        }
+        return scrollYDelta;
+    }
+
+    @Override
+    public void requestChildFocus(View child, View focused) {
+        if (!mTwoDScrollViewMovedFocus) {
+            if (!mIsLayoutDirty) {
+                scrollToChild(focused);
+            } else {
+                // The child may not be laid out yet, we can't compute the scroll yet
+                mChildToScrollTo = focused;
+            }
+        }
+        super.requestChildFocus(child, focused);
+    }
+
+    /**
+     * When looking for focus in children of a scroll view, need to be a little
+     * more careful not to give focus to something that is scrolled off screen.
+     *
+     * This is more expensive than the default {@link android.view.ViewGroup}
+     * implementation, otherwise this behavior might have been made the default.
+     */
+    @Override
+    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+        // convert from forward / backward notation to up / down / left / right
+        // (ugh).
+        if (direction == View.FOCUS_FORWARD) {
+            direction = View.FOCUS_DOWN;
+        } else if (direction == View.FOCUS_BACKWARD) {
+            direction = View.FOCUS_UP;
+        }
+
+        final View nextFocus = previouslyFocusedRect == null ?
+                FocusFinder.getInstance().findNextFocus(this, null, direction) :
+                FocusFinder.getInstance().findNextFocusFromRect(this,
+                        previouslyFocusedRect, direction);
+
+        if (nextFocus == null) {
+            return false;
+        }
+
+        return nextFocus.requestFocus(direction, previouslyFocusedRect);
+    }
+
+    @Override
+    public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
+        // offset into coordinate space of this scroll view
+        rectangle.offset(child.getLeft() - child.getScrollX(), child.getTop() - child.getScrollY());
+        return scrollToChildRect(rectangle, immediate);
+    }
+
+    @Override
+    public void requestLayout() {
+        mIsLayoutDirty = true;
+        super.requestLayout();
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+        mIsLayoutDirty = false;
+        // Give a child focus if it needs it
+        if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
+            scrollToChild(mChildToScrollTo);
+        }
+        mChildToScrollTo = null;
+
+        // Calling this with the present values causes it to re-clam them
+        scrollTo(getScrollX(), getScrollY());
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+
+        View currentFocused = findFocus();
+        if (null == currentFocused || this == currentFocused)
+            return;
+
+        // If the currently-focused view was visible on the screen when the
+        // screen was at the old height, then scroll the screen to make that
+        // view visible with the new screen height.
+        currentFocused.getDrawingRect(mTempRect);
+        offsetDescendantRectToMyCoords(currentFocused, mTempRect);
+        int scrollDeltaX = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+        int scrollDeltaY = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+        doScroll(scrollDeltaX, scrollDeltaY);
+    }
+
+    /**
+     * Return true if child is an descendant of parent, (or equal to the parent).
+     */
+    private boolean isViewDescendantOf(View child, View parent) {
+        if (child == parent) {
+            return true;
+        }
+
+        final ViewParent theParent = child.getParent();
+        return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent);
+    }
+
+    /**
+     * Fling the scroll view
+     *
+     * @param velocityY The initial velocity in the Y direction. Positive
+     *                  numbers mean that the finger/curor is moving down the screen,
+     *                  which means we want to scroll towards the top.
+     */
+    public void fling(int velocityX, int velocityY) {
+        if (getChildCount() > 0) {
+            int height = getHeight() - getPaddingBottom() - getPaddingTop();
+            int bottom = getChildAt(0).getHeight();
+            int width = getWidth() - getPaddingRight() - getPaddingLeft();
+            int right = getChildAt(0).getWidth();
+
+            mScroller.fling(getScrollX(), getScrollY(), velocityX, velocityY, 0, right - width, 0, bottom - height);
+
+            final boolean movingDown = velocityY > 0;
+            final boolean movingRight = velocityX > 0;
+
+            View newFocused = findFocusableViewInMyBounds(movingRight, mScroller.getFinalX(), movingDown, mScroller.getFinalY(), findFocus());
+            if (newFocused == null) {
+                newFocused = this;
+            }
+
+            if (newFocused != findFocus() && newFocused.requestFocus(movingDown ? View.FOCUS_DOWN : View.FOCUS_UP)) {
+                mTwoDScrollViewMovedFocus = true;
+                mTwoDScrollViewMovedFocus = false;
+            }
+
+            awakenScrollBars(mScroller.getDuration());
+            invalidate();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This version also clamps the scrolling to the bounds of our child.
+     */
+    public void scrollTo(int x, int y) {
+        // we rely on the fact the View.scrollBy calls scrollTo.
+        if (getChildCount() > 0) {
+            View child = getChildAt(0);
+            x = clamp(x, getWidth() - getPaddingRight() - getPaddingLeft(), child.getWidth());
+            y = clamp(y, getHeight() - getPaddingBottom() - getPaddingTop(), child.getHeight());
+            if (x != getScrollX() || y != getScrollY()) {
+                super.scrollTo(x, y);
+            }
+        }
+    }
+
+    private int clamp(int n, int my, int child) {
+        if (my >= child || n < 0) {
+     /* my >= child is this case:
+      *                    |--------------- me ---------------|
+      *     |------ child ------|
+      * or
+      *     |--------------- me ---------------|
+      *            |------ child ------|
+      * or
+      *     |--------------- me ---------------|
+      *                                  |------ child ------|
+      *
+      * n < 0 is this case:
+      *     |------ me ------|
+      *                    |-------- child --------|
+      *     |-- mScrollX --|
+      */
+            return 0;
+        }
+        if ((my+n) > child) {
+     /* this case:
+      *                    |------ me ------|
+      *     |------ child ------|
+      *     |-- mScrollX --|
+      */
+            return child-my;
+        }
+        return n;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/UndefinedFormula.java b/mainActivity/src/com/example/furt/myapplication/UndefinedFormula.java
new file mode 100755 (executable)
index 0000000..309cb4c
--- /dev/null
@@ -0,0 +1,59 @@
+package com.example.furt.myapplication;
+
+import android.graphics.Paint;
+
+import java.util.List;
+
+public class UndefinedFormula implements Formula{
+
+    Paint p=new Paint();
+    int priority;
+    boolean currentF;
+    UndefinedFormula()
+    {
+        priority=100;
+        currentF=false;
+    }
+    public String Draw(int x)
+    {
+        if(currentF)
+            return "_";
+        else
+           return " ";
+    }
+    public String toString(){return Draw(0);}
+    public String toStringDeleted(){return null;} //UndefinedFormula should never be deleted
+    public float size(){
+        p.setTextSize(DrawActivity.textSize);
+        return p.measureText(toString());
+    }
+    public float height()
+    {
+        return 0;
+    }
+    public float sizeDeleted(){return(0);}
+    public List<IntroductionRule> introductionRules(){
+        return null;
+    } //UndefinedFormula accepts no rules
+    public List<EliminationRule> EliminationRules(){
+        return null;
+    }
+
+    @Override
+    public boolean Fill(Formula F) {
+        return false;
+    }
+
+    @Override
+    public boolean setCursor() {
+        currentF=true;
+        return true;
+    }
+
+    @Override
+    public Formula duplicate() {
+        UndefinedFormula tmp=new UndefinedFormula();
+        tmp.currentF=this.currentF;
+        return tmp;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/aggiorna.java b/mainActivity/src/com/example/furt/myapplication/aggiorna.java
new file mode 100755 (executable)
index 0000000..a97220e
--- /dev/null
@@ -0,0 +1,241 @@
+package com.example.furt.myapplication;
+
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+public class aggiorna {
+
+    aggiorna(){}
+
+    public String sincronizza(String sessionKey,String user,String pass) {
+        String ritorno = null;
+        String login = "1/" + user + "/" + pass;
+        while (ritorno == null || ritorno.contains("request-login"))
+        {
+            ritorno = serverSync(sessionKey, user);
+            if(ritorno == null || ritorno.contains("request-login"))
+            {
+                sessionKey= serverComunication.connessione(login);
+            }
+            else if(ritorno.contains("error"))
+                Toast.makeText(aggiornamento.t.getContext().getApplicationContext(), "errore di connessione", Toast.LENGTH_SHORT).show();
+        }
+        ritorno=null;
+        while (ritorno == null || ritorno.contains("request-login"))
+        {
+            ritorno = syncLocaldb(sessionKey, user);
+            if(ritorno == null || ritorno.contains("request-login"))
+            {
+                sessionKey= serverComunication.connessione(login);
+            }
+            else if(ritorno.contains("error"))
+                Toast.makeText(aggiornamento.t.getContext().getApplicationContext(), "errore di connessione", Toast.LENGTH_SHORT).show();
+        }
+        ritorno=null;
+        while (ritorno == null || ritorno.contains("request-login"))
+        {
+            ritorno=downloadEX(sessionKey);
+            if(ritorno == null || ritorno.contains("request-login"))
+            {
+                sessionKey= serverComunication.connessione(login);
+            }
+            else if(ritorno.contains("error"))
+                Toast.makeText(aggiornamento.t.getContext().getApplicationContext(), "errore di connessione", Toast.LENGTH_SHORT).show();
+        }
+        return sessionKey;
+    }
+
+    public String serverSync(String sessionKey, String user)
+    {
+        personalDBHelper connessione = new personalDBHelper(aggiornamento.t.getContext());
+        List<listElem> esercizi=connessione.getElem(user);
+        if(esercizi!=null && !esercizi.isEmpty()) {
+            for (listElem esercizio : esercizi) {
+                Log.e("",esercizio.getEsercizio());}
+            for (listElem esercizio : esercizi) {
+                String richiesta = "8/" + sessionKey + "/" + esercizio.getEsercizio() + "/" + esercizio.getMd5() + "/" + esercizio.getTime() + "/" + esercizio.getClick();
+                String ritorno = serverComunication.connessione(richiesta);
+                if (ritorno.contains("es-ok"))
+                    connessione.updateElem(esercizio.getMd5(), user, esercizio.getTime());
+                else if (ritorno.contains("request-login") || ritorno.contains("es-err")){
+                   if(ritorno.contains("es-err"))
+                        connessione.remove(esercizio.getUtente(),esercizio.getTime());
+                    return ritorno;
+                 }
+            }
+        }
+        return "sync-ok";
+    }
+
+    public String syncLocaldb(String sessionKey, String utente)
+    {
+        String richiesta = "9/" + sessionKey;
+        String ritorno = serverComunication.connessione(richiesta);
+        if(ritorno.contains("request-login"))
+            return ritorno;
+        else
+        {
+            personalDBHelper connessione=new personalDBHelper(aggiornamento.t.getContext().getApplicationContext());
+            ArrayList<String> allExercise=suString.stringToMultiArray(ritorno);
+            List<listElem> localExercise=connessione.getAllElem(utente);
+            if(localExercise!=null && !localExercise.isEmpty()) {
+                for (String ex : allExercise) {
+                    ArrayList<String> tmp = suString.stringToArrayList(ex);
+                    boolean add = true;
+                    for (listElem elem : localExercise) {
+                        if (tmp.get(0).equals(elem.getEsercizio()) && Double.valueOf(tmp.get(2)) == elem.getTime()) {
+                            if (elem.getCheck() == 0)
+                                connessione.updateElem(tmp.get(1), utente, Double.valueOf(tmp.get(2)));
+                            add = false;
+                        }
+                    }
+                    if (add)
+                        if(tmp.size()>3)
+                            connessione.add(utente, tmp.get(0), tmp.get(1), Double.valueOf(tmp.get(2)), Integer.valueOf(tmp.get(3)), 1);
+                }
+            }
+            else{
+                for (String ex : allExercise) {
+                    ArrayList<String> tmp = suString.stringToArrayList(ex);
+                    if(tmp.size()>3)
+                        connessione.add(utente, tmp.get(0), tmp.get(1), Double.valueOf(tmp.get(2)), Integer.valueOf(tmp.get(3)), 1);
+                }
+            }
+        }
+        return "local-sync-ok";
+    }
+
+    public String downloadEX(String sessionKey)
+    {
+        Context context = aggiornamento.t.getContext();
+        File SDCardRoot = Environment.getExternalStorageDirectory();
+        String[] names = SDCardRoot.list();
+        String ritorno=null;
+        boolean go = true;
+        for (String name : names) {
+            if (name.compareTo("tesiEs") == 0) {
+                go = false;
+                break;
+            }
+        }
+        if (go) {
+            File dir = new File(global.esDir);
+            dir.mkdir();
+        }
+        try {
+            ritorno = serverComunication.connessione("7/" + sessionKey);
+            if (!ritorno.contains("error") && !ritorno.contains("request-login"))
+            {
+                ArrayList<String> esercizi= suString.stringToMultiArray(ritorno);
+                File dir = new File(global.esDir);
+                String[] presenti = dir.list();
+                boolean tmp = true;
+                for(String esercizio : esercizi)
+                {
+                    ArrayList<String> es=suString.stringToArrayList(esercizio);
+                    tmp = true;
+                    for (String nome : presenti) {
+                        if (nome.contentEquals(es.get(0))) {
+                            if ((MD5.digest(nome)).contentEquals(es.get(1))) {
+                                tmp = false;
+                            }
+                            else {
+                                File file = new File(global.esDir + nome);
+                                file.delete();
+                            }
+                        }
+                    }
+                    if (tmp) {
+                        String request = new download().execute(es.get(0)).get();
+                    }
+                }
+            }
+        }catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        return ritorno;
+    }
+}
+class download extends AsyncTask<String,String,String>
+{
+    @Override
+    protected String doInBackground(String... params)
+    {
+        try {
+            //set the download URL, a url that points to a file on the internet
+            //this is the file to be downloaded
+            URL url = new URL(global.httpHost+params[0]);
+
+            //create the new connection
+            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+
+            //set up some things on the connection
+            urlConnection.setRequestMethod("GET");
+            urlConnection.setDoOutput(true);
+
+            //and connect!
+            urlConnection.connect();
+
+            //set the path where we want to save the file
+            //in this case, going to save it on the root directory of the
+            //sd card.
+            File SDCardRoot = Environment.getExternalStorageDirectory();
+            File esDir = new File(global.esDir);
+            //create a new file, specifying the path, and the filename
+            //which we want to save the file as.
+
+
+            File file = new File(esDir,params[0]);
+            //this will be used to write the downloaded data into the file we created
+            FileOutputStream fileOutput = new FileOutputStream(file);
+
+            //this will be used in reading the data from the internet
+            InputStream inputStream = urlConnection.getInputStream();
+
+            //this is the total size of the file
+            int totalSize = urlConnection.getContentLength();
+            //variable to store total downloaded bytes
+            int downloadedSize = 0;
+
+            //create a buffer...
+            byte[] buffer = new byte[1024];
+            int bufferLength = 0; //used to store a temporary size of the buffer
+
+            //now, read through the input buffer and write the contents to the file
+            while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
+                //add the data in the buffer to the file in the file output stream (the file on the sd card
+                fileOutput.write(buffer, 0, bufferLength);
+                //add up the size so we know how much is downloaded
+                downloadedSize += bufferLength;
+                //this is where you would do something to report the prgress, like this maybe
+                //updateProgress(downloadedSize, totalSize);
+
+            }
+            //close the output stream when done
+            fileOutput.close();
+
+//catch some possible errors...
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
+
diff --git a/mainActivity/src/com/example/furt/myapplication/aggiornamento.java b/mainActivity/src/com/example/furt/myapplication/aggiornamento.java
new file mode 100755 (executable)
index 0000000..c3893fe
--- /dev/null
@@ -0,0 +1,53 @@
+package com.example.furt.myapplication;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.RelativeLayout;
+
+
+public class aggiornamento extends Activity
+{
+    static RelativeLayout t; //for context
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.aggiornamento);
+        t=(RelativeLayout)findViewById(R.id.glob_agg);
+        Bundle dati=getIntent().getExtras();
+        String user=dati.getString("user");
+        String pass=dati.getString("pass");
+        String sessionKey=dati.getString("sessionKey");
+        if(sessionKey.contentEquals("000000000"))//controllo se le credenziali memorizzate sono corrette
+        {
+            sessionKey = serverComunication.connessione("1/" + user + "/" + pass);
+            if(sessionKey.contentEquals("request-login") || sessionKey.contains("err"))
+            {
+                Log.e("", "ciao");
+                Intent i = new Intent(getApplicationContext(), mainActivity.class);
+                i.putExtra("logout", "si");
+                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                getApplicationContext().startActivity(i);
+                return;
+            }
+        }
+        aggiorna agg=new aggiorna();
+        sessionKey=agg.sincronizza(sessionKey,user,pass);
+        if(sessionKey.contains("err") || sessionKey.contentEquals("000000000"))
+        {
+            Intent i = new Intent(getApplicationContext(), mainActivity.class);
+            i.putExtra("logout", "si");
+            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            getApplicationContext().startActivity(i);
+        }
+        else {
+            Intent i = new Intent(getApplicationContext(), download_page.class);
+            i.putExtra("user", user);
+            i.putExtra("pass", pass);
+            i.putExtra("sessionKey", sessionKey);
+            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            getApplicationContext().startActivity(i);
+        }
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/askFormula.java b/mainActivity/src/com/example/furt/myapplication/askFormula.java
new file mode 100755 (executable)
index 0000000..a6fb161
--- /dev/null
@@ -0,0 +1,5 @@
+package com.example.furt.myapplication;
+
+public class askFormula{
+    public Formula Ask(){return DrawActivity.selectedNode.F;};
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/download_page.java b/mainActivity/src/com/example/furt/myapplication/download_page.java
new file mode 100755 (executable)
index 0000000..1193815
--- /dev/null
@@ -0,0 +1,125 @@
+package com.example.furt.myapplication;
+
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.io.File;
+import java.util.List;
+
+public class download_page extends Activity
+{
+    static String user=null;
+    static String pass=null;
+    static String sessionKey=null;
+    static RelativeLayout globalDownload;
+    static TextView rootDownload;
+    static TextView dw;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        dw=(TextView)findViewById(R.id.startEs);
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.download);
+        final Context context=getApplicationContext();
+        Bundle dati=getIntent().getExtras();
+        globalDownload=(RelativeLayout)findViewById(R.id.dlglobal);
+        rootDownload=(TextView)findViewById(R.id.startEs);
+        user=dati.getString("user");
+        pass=dati.getString("pass");
+        sessionKey=dati.getString("sessionKey");
+        File dir = new File(global.esDir);
+        String[] presenti = dir.list();
+        ArrayAdapter<String> vievList=new ArrayAdapter<String>(this,R.layout.textviewgeneral);
+        ListView lista= (ListView) findViewById(R.id.listView);
+        for (String nome : presenti) {
+            String aggiungi="non risolto";
+            boolean min=false;
+            boolean check=false;
+            personalDBHelper db=new personalDBHelper(context);
+            List<listElem> risolti=db.getElemForName(user, nome);
+            if(risolti!=null && !risolti.isEmpty()) {
+
+                for (listElem elem : risolti) {
+                    if (!min && elem.getCheck() == 0) {
+                        min = true;
+                        aggiungi = "da confermare: " + elem.getClick() + "/30";
+                    } else if (!check && elem.getCheck() == 1) {
+                        min = true;
+                        check = true;
+                        aggiungi = elem.getClick() + "/30";
+                    }
+
+                }
+            }
+            vievList.add(nome+"\n"+aggiungi);
+        }
+        lista.setAdapter(vievList);
+        lista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                TextView t=(TextView)view;
+                String valore=t.getText().toString();
+                String nomeEs = null;
+                for(int i=0;i<valore.length();i++)
+                {
+                    if(valore.charAt(i)=='.')
+                    {
+                        nomeEs=valore.substring(0,i)+".xml";
+                        i=valore.length();
+                    }
+                }
+                Intent i = new Intent(getApplicationContext(), DrawActivity.class);
+                i.putExtra("nomeEs", nomeEs);
+                i.putExtra("user",user);
+                i.putExtra("pass",pass);
+                i.putExtra("sessionKey",sessionKey);
+                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                getApplicationContext().startActivity(i);
+            }
+        });
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.menu_dow, menu);
+        return true;
+    }
+
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        // Handle action bar item clicks here. The action bar will
+        // automatically handle clicks on the Home/Up button, so long
+        // as you specify a parent activity in AndroidManifest.xml.
+        int id = item.getItemId();
+        if(id==R.id.aggiorna)
+        {
+            Intent i = new Intent(getApplicationContext(), aggiornamento.class);
+            i.putExtra("user", user);
+            i.putExtra("pass", pass);
+            i.putExtra("sessionKey", sessionKey);
+            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            getApplicationContext().startActivity(i);
+        }
+        else if (id==R.id.esci)
+        {
+            Intent i = new Intent(getApplicationContext(), mainActivity.class);
+            i.putExtra("logout","si");
+            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            getApplicationContext().startActivity(i);
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/global.java b/mainActivity/src/com/example/furt/myapplication/global.java
new file mode 100755 (executable)
index 0000000..ccfe2fb
--- /dev/null
@@ -0,0 +1,12 @@
+package com.example.furt.myapplication;
+
+
+import android.os.Environment;
+
+public class global {
+    public static String hostName = "130.136.129.1";
+    public static String esDir= Environment.getExternalStorageDirectory()+"/tesiEs/";
+    public static String httpHost="http://logicplayer.helm.cs.unibo.it/esercizi/";
+    public static int port=25000;
+
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/listElem.java b/mainActivity/src/com/example/furt/myapplication/listElem.java
new file mode 100755 (executable)
index 0000000..bbedd8a
--- /dev/null
@@ -0,0 +1,49 @@
+package com.example.furt.myapplication;
+
+
+public class listElem {
+    private String esercizio;
+    private double time;
+    private int check;
+    private  String md5;
+    private String utente;
+    private int click;
+
+    listElem()
+    {}
+
+    public void setEsercizio(String esercizio)
+    {
+        this.esercizio=esercizio;
+    }
+    public void setTime(double time)
+    {
+        this.time=time;
+    }
+    public void setCheck(int check)
+    {
+        this.check=check;
+    }
+    public void setMd5(String md5){this.md5=md5;}
+    public void setUtente(String utente){this.utente=utente;}
+    public void setClick(int click){this.click=click;}
+
+    public String getUtente(){return  this.utente;}
+    public String getEsercizio()
+    {
+        return this.esercizio;
+    }
+    public String getMd5()
+    {
+        return this.md5;
+    }
+    public double getTime()
+    {
+        return this.time;
+    }
+    public int getCheck()
+    {
+        return this.check;
+    }
+    public int getClick(){return this.click;}
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/mainActivity.java b/mainActivity/src/com/example/furt/myapplication/mainActivity.java
new file mode 100755 (executable)
index 0000000..1c68148
--- /dev/null
@@ -0,0 +1,151 @@
+package com.example.furt.myapplication;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/*possiamo chiavare la mainActiviti in due casi, il primo è aprendo l'applicazione, il secondo è effettuando il
+* logout. nel primo caso viene controllato se sono state memorizzate delle credenziali e nel caso, il login viene
+* efetttuato direttamente. nel caso in cui si effettua il logout o non sono state memorizzate le credenziali,
+* viene data la possibilità di registrarsi o loggarsi, è possibile tramite il menù recuperare la password o aggiornarla
+* una volta effettuato il login viene passato il controllo ad "aggiorna.java"*/
+
+public class mainActivity extends Activity {
+
+    static TextView t;
+    public static final String PREFS_NAME = "MyPrefsFile";
+    private static final String PREF_USERNAME = "username";
+    private static final String PREF_PASSWORD = "password";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_login);
+        t = (TextView) findViewById(R.id.login);
+        SharedPreferences pref = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);//recupero le ultime credenziali valide inserite
+        String username = pref.getString(PREF_USERNAME, null);
+        String password = pref.getString(PREF_PASSWORD, null);
+        String logout=null;
+        Bundle dati=getIntent().getExtras();
+        if(dati!=null)//controllo se la mainActivity è stata chiamata dopo un logout
+            logout=dati.getString("logout");
+        if(logout!=null)
+        {
+            username=null;
+            password=null;
+        }
+
+        if (username == null && password == null) {//viene effettuato solo se ci sono delle credenziali memorizzate e se mainActivity non è stata chiamata da un logout
+            Button b = (Button) findViewById(R.id.logout);
+            b.setOnClickListener(new View.OnClickListener() {//routin di gestione del login
+                @Override
+                public void onClick(View v) {
+                    try {
+                        EditText txt = (EditText) findViewById(R.id.userId);//recupero username inserito
+                        EditText txt2 = (EditText) findViewById(R.id.oldPass);//recupero la password inserita
+                        String testo = txt.getText().toString();
+                        String testo2 = txt2.getText().toString();
+                        if(testo.contains("/") || testo2.contains("/"))//controllo che non siano inseriti valori vietati
+                            Toast.makeText(getApplicationContext(),"il carattere '/' non è consentito", Toast.LENGTH_SHORT).show();
+                        else if(testo.isEmpty() || testo2.isEmpty())//controllo che tutti i campi siano completati
+                            Toast.makeText(getApplicationContext(),"riempi i campi", Toast.LENGTH_SHORT).show();
+                        else {//login effettuato con successo
+                            String request = serverComunication.connessioneMain("1/" + testo + "/" + testo2);//richiedo il login al server
+                            if (!request.contains("error")) {
+                                getSharedPreferences(PREFS_NAME, MODE_PRIVATE)//salvo username e password per i prossimi accessi
+                                        .edit()
+                                        .putString(PREF_USERNAME, testo)
+                                        .putString(PREF_PASSWORD, testo2)
+                                        .commit();
+                                Intent i = new Intent(getApplicationContext(), aggiornamento.class);
+                                i.putExtra("user", testo);
+                                i.putExtra("pass", testo2);
+                                i.putExtra("sessionKey", request);
+                                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                                getApplicationContext().startActivity(i);//avvio la "aggiornamento.class"
+                            }
+                        }
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            });
+            Button b2 = (Button) findViewById(R.id.button2);
+            b2.setOnClickListener(new View.OnClickListener() {//routine di gestione della registrazione
+                @Override
+                public void onClick(View v) {
+
+                    EditText txt = (EditText) findViewById(R.id.userId);
+                    EditText txt2 = (EditText) findViewById(R.id.oldPass);
+                    String testo = txt.getText().toString();
+                    String testo2 = txt2.getText().toString();
+                    if(testo.isEmpty() || testo2.isEmpty())
+                        Toast.makeText(getApplicationContext(),"riempi i campi", Toast.LENGTH_SHORT).show();
+                    else {
+                        try {
+                            serverComunication connect = new serverComunication();
+                            String request = connect.connessioneMain("0/" + testo + "/" + testo2);
+                            Toast.makeText(getApplicationContext(), request, Toast.LENGTH_SHORT).show();
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            });
+        } else {
+            Intent i = new Intent(getApplicationContext(), aggiornamento.class);
+            i.putExtra("user", username);
+            i.putExtra("pass", password);
+            i.putExtra("sessionKey", "000000000");
+            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            getApplicationContext().startActivity(i);
+        }
+    }
+
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.login_set, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        // Handle action bar item clicks here. The action bar will
+        // automatically handle clicks on the Home/Up button, so long
+        // as you specify a parent activity in AndroidManifest.xml.
+        int id = item.getItemId();
+        if(id==R.id.recupera)//routine di gestione di recupero password
+        {
+            EditText txt = (EditText) findViewById(R.id.userId);
+            String testo = txt.getText().toString();
+            if(testo.isEmpty())
+                Toast.makeText(getApplicationContext(),"inserisci l'indirizzo email", Toast.LENGTH_SHORT).show();
+            else {
+                try {
+                    serverComunication connect = new serverComunication();
+                    String request = connect.connessioneMain("2/" + testo);
+                    Toast.makeText(getApplicationContext(), request, Toast.LENGTH_SHORT).show();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        if(id==R.id.reimposta)
+        {
+            Intent i = new Intent(getApplicationContext(), recuperaPass.class);
+            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            getApplicationContext().startActivity(i);
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/operandClick.java b/mainActivity/src/com/example/furt/myapplication/operandClick.java
new file mode 100755 (executable)
index 0000000..d5f26e3
--- /dev/null
@@ -0,0 +1,32 @@
+package com.example.furt.myapplication;
+
+import android.view.View;
+
+public class operandClick implements View.OnClickListener
+{
+    Node L;
+    operandClick(Node n)
+    {
+        L=n;
+    }
+    public void onClick(View view)
+    {
+        if (DrawActivity.selectedNode.Children.size()!=0) //not a leaf: can't add children
+            return;
+        if (L==null) //incompatible elimination
+            return;
+        for (Node n:L.Children) {
+            for (Hypothesis hp:n.NodeHP)
+                hp.fromNode= DrawActivity.selectedNode; //le ipotesi dei nuovi figli provengono dal nodo in cui stanno per essere inserite
+            n.addHPList(DrawActivity.selectedNode.NodeHP);
+            DrawActivity.selectedNode.addChild(n);
+        }
+        DrawActivity.selectedNode.hasFocus=false;
+        DrawActivity.selectedNode.Children.get(0).hasFocus=true;
+        DrawActivity.selectedNode.hasFocus=false;
+        DrawActivity.selectedNode.ruleName=L.ruleName;
+        DrawActivity.nmoves++;
+        DrawActivity.rootNode.Clean();
+        DrawActivity.startDraw();
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/parser.java b/mainActivity/src/com/example/furt/myapplication/parser.java
new file mode 100755 (executable)
index 0000000..0722a30
--- /dev/null
@@ -0,0 +1,246 @@
+package com.example.furt.myapplication;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathFactory;
+
+public class parser {
+    parser(){}
+
+    protected static Node root(String esercizio)
+    {
+        Node returnNode=null;
+        try {
+            String cartellaEs=global.esDir;
+            FileInputStream file = new FileInputStream(new File(cartellaEs+esercizio));
+            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = builderFactory.newDocumentBuilder();
+            Document xmlDocument = builder.parse(file);
+            returnNode=new Node(createFormula(xmlDocument,"/esercizio/tesi/formula[1]"));
+            returnNode.addHPList(ipotesi(xmlDocument));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return returnNode;
+    }
+
+    static public ArrayList<String> getLiteral(String esercizio)
+    {
+        String cartellaEs=global.esDir;
+        ArrayList<String> listValue=new ArrayList<String>();
+        ArrayList<String> returnValue=new ArrayList<String>();
+        try {
+            FileInputStream file = new FileInputStream(new File(cartellaEs + esercizio));
+            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = builderFactory.newDocumentBuilder();
+            Document xmlDocument = builder.parse(file);
+            listValue.add("Ț");
+            listValue.add("⊥");
+            listValue.addAll(getLiteralAtFormula(xmlDocument, "/esercizio/tesi/formula[1]"));
+            listValue.addAll(getLiteralAtHypotesis(xmlDocument));
+            for(String elem : listValue)
+            {
+                if(!returnValue.isEmpty())
+                {
+                    if(!returnValue.contains(elem))
+                        returnValue.add(elem);
+                }
+                else
+                    returnValue.add(elem);
+            }
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (ParserConfigurationException e) {
+            e.printStackTrace();
+        } catch (SAXException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return returnValue;
+    }
+
+    static public ArrayList<String> getLiteralAtFormula(Document xmlDocument, String position)
+    {
+        ArrayList<String> returnList=new ArrayList<String>();
+        try {
+            XPath xPath = XPathFactory.newInstance().newXPath();
+            if(Integer.parseInt(xPath.compile("count(" + position + ")").evaluate(xmlDocument))==1) {
+                String type = xPath.compile(position + "/@type").evaluate(xmlDocument);
+                int numbOfElements = 5;
+                if (type.contentEquals("and") || type.contentEquals("or") || type.contentEquals("impl"))
+                    numbOfElements = 2;
+                else if (type.contentEquals("not"))
+                    numbOfElements = 1;
+                else if (type.contentEquals("literal") || type.contentEquals("atomic"))
+                    numbOfElements = 0;
+                int count = Integer.parseInt(xPath.compile("count(" + position + "/formula)").evaluate(xmlDocument));
+                if (count == numbOfElements) {
+                    if (numbOfElements == 2) {
+                        returnList.addAll(getLiteralAtFormula(xmlDocument, position + "/formula[1]"));
+                        returnList.addAll(getLiteralAtFormula(xmlDocument, position + "/formula[2]"));
+
+                        return returnList;
+                    } else if (numbOfElements == 1) {
+                        return getLiteralAtFormula(xmlDocument, position + "/formula[1]");
+                    } else if (numbOfElements == 0) {
+                        String child = xPath.compile(position).evaluate(xmlDocument);
+                        if (child == null || child.isEmpty())
+                            return null;
+                        else if (child.contentEquals("top")) {
+                            returnList.add("Ț");
+                            return returnList;
+                        }
+                        else if (child.contentEquals("bot")){
+                            returnList.add("⊥");
+                            return returnList;
+                        }
+                        else{
+                            returnList.add(String.valueOf(child.charAt(0)));
+                            return returnList;
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    static public Formula createFormula(Document xmlDocument, String position) {
+        try {
+            XPath xPath = XPathFactory.newInstance().newXPath();
+            if(Integer.parseInt(xPath.compile("count(" + position + ")").evaluate(xmlDocument))==1) {
+                String type = xPath.compile(position + "/@type").evaluate(xmlDocument);
+                int numbOfElements = 5;
+                if (type.contentEquals("and") || type.contentEquals("or") || type.contentEquals("impl"))
+                    numbOfElements = 2;
+                else if (type.contentEquals("not"))
+                    numbOfElements = 1;
+                else if (type.contentEquals("literal") || type.contentEquals("atomic"))
+                    numbOfElements = 0;
+                int count = Integer.parseInt(xPath.compile("count(" + position + "/formula)").evaluate(xmlDocument));
+                if (count == numbOfElements) {
+                    if (numbOfElements == 2) {
+                        Formula firstChild = createFormula(xmlDocument, position + "/formula[1]");
+                        Formula secondChild = createFormula(xmlDocument, position + "/formula[2]");
+                        if (firstChild == null || secondChild == null)
+                            return null;
+                        else if (type.contentEquals("and"))
+                            return new FormulaAnd(createFormula(xmlDocument, position + "/formula[1]"), createFormula(xmlDocument, position + "/formula[2]"));
+                        else if (type.contentEquals("or"))
+                            return new FormulaOr(createFormula(xmlDocument, position + "/formula[1]"), createFormula(xmlDocument, position + "/formula[2]"));
+                        else if (type.contentEquals("impl"))
+                            return new FormulaImpl(createFormula(xmlDocument, position + "/formula[1]"), createFormula(xmlDocument, position + "/formula[2]"));
+                    } else if (numbOfElements == 1) {
+                        Formula child = createFormula(xmlDocument, position + "/formula[1]");
+                        if (child == null)
+                            return null;
+                        return new FormulaNot(createFormula(xmlDocument, position + "/formula[1]"));
+                    } else if (numbOfElements == 0) {
+                        String child = xPath.compile(position).evaluate(xmlDocument);
+                        if (child == null || child.isEmpty())
+                            return null;
+                        else if (child.length()>=3 && child.substring(0,3).equals("top"))
+                            return new FormulaTOP();
+                        else if (child.length()>=3 && child.substring(0,3).equals("bot"))
+                            return new FormulaBOT();
+                        else
+                            return new Literal(child.charAt(0));
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    static public List<Hypothesis> ipotesi(Document xmlDocument)
+    {
+        List<Hypothesis> returnValue=new ArrayList<Hypothesis>();
+        XPath xPath = XPathFactory.newInstance().newXPath();
+        try
+        {
+            int count = Integer.parseInt(xPath.compile("count(/esercizio/ipotesi/formula)").evaluate(xmlDocument));
+            for(int i=1;i<=count;i++)
+            {
+                Formula F=createFormula(xmlDocument,"/esercizio/ipotesi/formula["+i+"]");
+                Hypothesis valore;
+                if(F==null)
+                    valore=null;
+                else
+                    valore=new Hypothesis(F,false);
+                if(valore!=null)
+                    returnValue.add(valore);
+            }
+        }catch (Exception e) {
+            e.printStackTrace();
+        }
+        return returnValue;
+    }
+
+    static public ArrayList<String> getLiteralAtHypotesis(Document xmlDocument)
+    {
+        ArrayList<String> returnValue=new ArrayList<String>();
+        XPath xPath = XPathFactory.newInstance().newXPath();
+        try
+        {
+            int count = Integer.parseInt(xPath.compile("count(/esercizio/ipotesi/formula)").evaluate(xmlDocument));
+            for(int i=1;i<=count;i++)
+                returnValue.addAll(getLiteralAtFormula(xmlDocument, "/esercizio/ipotesi/formula[" + i + "]"));
+        }catch (Exception e) {
+            e.printStackTrace();
+        }
+        return returnValue;
+    }
+
+    static public ArrayList<String> getParameters(String esercizio)
+    {
+        ArrayList<String> value=new ArrayList<String>();
+        try {
+            String cartellaEs=global.esDir;
+            FileInputStream file = new FileInputStream(new File(cartellaEs+esercizio));
+            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = builderFactory.newDocumentBuilder();
+            Document xmlDocument = builder.parse(file);
+            return parameters(xmlDocument);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return value;
+    }
+
+    static private ArrayList<String> parameters(Document xmlDocument)
+    {
+        ArrayList<String> returnValue= new ArrayList<String>();
+        XPath xPath = XPathFactory.newInstance().newXPath();
+        try
+        {
+             if(        Integer.parseInt(xPath.compile("count(/esercizio/valutazione/click)").evaluate(xmlDocument))==1 &&
+                        Integer.parseInt(xPath.compile("count(/esercizio/valutazione/tempo)").evaluate(xmlDocument))==1 &&
+                        Integer.parseInt(xPath.compile("count(/esercizio/valutazione/altezza)").evaluate(xmlDocument))==1)
+                {
+                    returnValue.add(xPath.compile("/esercizio/valutazione/click").evaluate(xmlDocument));
+                    returnValue.add(xPath.compile("/esercizio/valutazione/tempo").evaluate(xmlDocument));
+                    returnValue.add(xPath.compile("/esercizio/valutazione/altezza").evaluate(xmlDocument));
+                }
+        }catch (Exception e) {
+            e.printStackTrace();
+        }
+        return returnValue;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/parserDialog.java b/mainActivity/src/com/example/furt/myapplication/parserDialog.java
new file mode 100755 (executable)
index 0000000..e871b7f
--- /dev/null
@@ -0,0 +1,153 @@
+package com.example.furt.myapplication;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class parserDialog extends DialogFragment {
+    static Formula F=null; //formula che sto costruendo
+    static RelativeLayout formulaLayout;
+    static TextView FView; //View contenente la formula che sto visualizzando
+    static Button dismissButton;
+    static boolean reload=false;
+    static ArrayList<String> esliter=new ArrayList<String>();
+    static ArrayList<Formula> undo=new ArrayList<Formula>();
+    public parserDialog()
+    {
+        esliter.removeAll(esliter);
+        if(!reload)
+            undo.removeAll(undo);
+        reload=false;
+        if(F==null) {
+            F = new UndefinedFormula();
+            F.setCursor();
+        }
+        esliter.addAll(parser.getLiteral(DrawActivity.nomeEs));
+        Log.e("","⊤");
+    }
+    @Override
+    public Dialog onCreateDialog(final Bundle savedInstanceState) {
+        // Use the Builder class for convenient dialog construction
+        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        LayoutInflater inflater=getActivity().getLayoutInflater();
+        View view=inflater.inflate(R.layout.string_layout, null);
+        RelativeLayout litersLayout=(RelativeLayout)((ViewGroup)((ViewGroup)view).getChildAt(0)).getChildAt(0);
+        RelativeLayout operatorsLayout=(RelativeLayout)(((ViewGroup)view).getChildAt(1));
+        formulaLayout=(RelativeLayout)((ViewGroup)((ViewGroup)view).getChildAt(2)).getChildAt(0);
+        FView=new TextView(formulaLayout.getContext());
+        FView.setText(F.toString());
+        FView.setTextSize(DrawActivity.textSize);
+        formulaLayout.addView(FView);
+        int leftId=0;
+        if(!esliter.isEmpty()) {
+            for (String liter : esliter) {
+                Button lit = new Button(litersLayout.getContext());
+                RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+                lit.setText(liter);
+                if (leftId != 0) {
+                    lp.addRule(RelativeLayout.RIGHT_OF, leftId);
+                }
+                lit.setLayoutParams(lp);
+                lit.setId(DrawActivity.globalId++);
+                leftId = lit.getId();
+                litersLayout.addView(lit);
+                lit.setOnClickListener(new touchParserHandler(4, liter.charAt(0)));
+            }
+        }
+        Button bImpl=new Button(operatorsLayout.getContext());
+        Button bAnd=new Button(operatorsLayout.getContext());
+        Button bOr=new Button(operatorsLayout.getContext());
+        Button bNot=new Button(operatorsLayout.getContext());
+        RelativeLayout.LayoutParams lpImpl=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        RelativeLayout.LayoutParams lpAnd=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        RelativeLayout.LayoutParams lpNot=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        RelativeLayout.LayoutParams lpOr=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+        bImpl.setText("⇒");
+        bImpl.setLayoutParams(lpImpl);
+        bImpl.setId(DrawActivity.globalId++);
+        leftId=bImpl.getId();
+
+        bOr.setText("∨");
+        lpOr.addRule(RelativeLayout.RIGHT_OF, leftId);
+        bOr.setLayoutParams(lpOr);
+        bOr.setId(DrawActivity.globalId++);
+        leftId=bOr.getId();
+
+        bAnd.setText("∧");
+        lpAnd.addRule(RelativeLayout.RIGHT_OF, leftId);
+        bAnd.setLayoutParams(lpAnd);
+        bAnd.setId(DrawActivity.globalId++);
+        leftId=bAnd.getId();
+
+        bNot.setText("¬");
+        lpNot.addRule(RelativeLayout.RIGHT_OF, leftId);
+        bNot.setLayoutParams(lpNot);
+        bNot.setId(DrawActivity.globalId++);
+
+        operatorsLayout.addView(bImpl);
+        operatorsLayout.addView(bAnd);
+        operatorsLayout.addView(bNot);
+        operatorsLayout.addView(bOr);
+        bImpl.setOnClickListener(new touchParserHandler(2,' '));
+        bAnd.setOnClickListener(new touchParserHandler(0,' '));
+        bNot.setOnClickListener(new touchParserHandler(3, ' '));
+        bOr.setOnClickListener(new touchParserHandler(1, ' '));
+        builder.setView(view);
+        builder.setTitle("Inserisci una formula").setPositiveButton("Ok", new DialogInterface.OnClickListener() {
+            public void onClick(DialogInterface dialog, int id) {
+                if(!F.toString().contains("_")) {
+                    List<EliminationRule> L = F.EliminationRules();
+                    if (L.size()==0)
+                        return;
+                    touchHPHandler t = new touchHPHandler(L.get(0).createNodes(null, new askFormula()),new Hypothesis(F,true));
+                    F = null;
+                    t.discard=false;
+                    t.onClick(null);
+                }
+                else
+                    reboot();
+            }
+        });
+        builder.setNeutralButton("Undo", new DialogInterface.OnClickListener() {
+            public void onClick(DialogInterface dialog, int id) {
+                if(undo.size()>1) {
+                    F = undo.remove(undo.size() - 1);
+                    /*for(int i=0;i<undo.size();i++) {
+                        Log.e(String.valueOf(i), undo.get(i).toString());
+                    }*/
+                }
+                else
+                    F=null;
+                reboot();
+            }
+        });
+        builder.setNegativeButton("Annulla", new DialogInterface.OnClickListener() {
+            public void onClick(DialogInterface dialog, int id) {
+                F=null;
+            }
+        });
+        // Create the AlertDialog object and return it
+        return builder.create();
+    }
+    static void reboot()
+    {
+        reload=true;
+        parserDialog p=new parserDialog();
+        p.F=F;
+        p.show(DrawActivity.fragmentManager, "CIAO");
+    }
+
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/personalDBHelper.java b/mainActivity/src/com/example/furt/myapplication/personalDBHelper.java
new file mode 100755 (executable)
index 0000000..2af2653
--- /dev/null
@@ -0,0 +1,189 @@
+package com.example.furt.myapplication;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.example.furt.myapplication.personalTrackerContract.DATABASE_NAME;
+import static com.example.furt.myapplication.personalTrackerContract.DATABASE_VERSION;
+import static com.example.furt.myapplication.personalTrackerContract.esercizi;
+import static com.example.furt.myapplication.personalTrackerContract.esercizi.COLUMN_CHECK;
+import static com.example.furt.myapplication.personalTrackerContract.esercizi.COLUMN_CLICK;
+import static com.example.furt.myapplication.personalTrackerContract.esercizi.COLUMN_ESERCIZIO;
+import static com.example.furt.myapplication.personalTrackerContract.esercizi.COLUMN_MD5;
+import static com.example.furt.myapplication.personalTrackerContract.esercizi.COLUMN_TIME;
+import static com.example.furt.myapplication.personalTrackerContract.esercizi.COLUMN_UTENTE;
+import static com.example.furt.myapplication.personalTrackerContract.esercizi.SQL_CREATE_ENTRIES;
+import static com.example.furt.myapplication.personalTrackerContract.esercizi.TABLE_NAME;
+
+
+
+public class personalDBHelper extends SQLiteOpenHelper{
+    public personalDBHelper(Context context) {
+        super(context, DATABASE_NAME, null, DATABASE_VERSION);
+    }
+
+    public void onCreate(SQLiteDatabase db) {
+
+        db.execSQL(SQL_CREATE_ENTRIES);
+        Log.e("dphelper", SQL_CREATE_ENTRIES);
+    }
+
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        // This database is only a cache for online data, so its upgrade policy is
+        // to simply to discard the data and start over
+        db.execSQL(SQL_CREATE_ENTRIES);
+        onCreate(db);
+    }
+
+    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        onUpgrade(db, oldVersion, newVersion);
+    }
+
+    public void add(String utente, String esercizio, String md5, Double time, int ckick, int check)
+    {
+        SQLiteDatabase db=this.getWritableDatabase();
+        ContentValues values=new ContentValues();
+        values.put(COLUMN_MD5,md5);
+        if(time==0)
+            values.put(COLUMN_TIME,(double)time());
+        else
+            values.put(COLUMN_TIME,(time));
+        values.put(COLUMN_CHECK,check);
+        values.put(COLUMN_UTENTE,utente);
+        values.put(COLUMN_ESERCIZIO,esercizio);
+        values.put(COLUMN_CLICK, ckick);
+        db.insert(TABLE_NAME, null, values);
+        db.close();
+    }
+
+    public void remove(String user, double time)
+    {
+        SQLiteDatabase db = this.getWritableDatabase();
+        String request=COLUMN_MD5 + "=? AND " + COLUMN_TIME + "=? AND " + COLUMN_UTENTE + "=?";
+        String[] condition=new String[]{
+                String.valueOf(time),
+                String.valueOf(user)
+        };
+        db.delete(TABLE_NAME,request,condition);
+        db.close();
+    }
+
+    public static Long time()
+    {
+        java.util.Date date= new java.util.Date();
+        Timestamp now=new Timestamp(date.getTime());
+        return now.getTime();
+    }
+
+    public void removeAll(){
+        SQLiteDatabase db=this.getWritableDatabase();
+        String request="TRUNCATE "+TABLE_NAME;
+    }
+
+    public List<listElem> getElem(String user)
+    {
+        List<listElem> elem=null;
+        SQLiteDatabase db=this.getReadableDatabase();
+        String[] tableColums={
+            esercizi.COLUMN_MD5,
+            esercizi.COLUMN_TIME,
+            esercizi.COLUMN_CLICK,
+            esercizi.COLUMN_ESERCIZIO
+        };
+        String whereClause= COLUMN_UTENTE +"=? AND " + COLUMN_CHECK +"=?";
+        String[] whereArgs=new String[]{
+                String.valueOf(user),
+                String.valueOf("0")
+        };
+        Cursor cursor=db.query(TABLE_NAME,tableColums,whereClause,whereArgs,null,null,null);
+        if(cursor.moveToFirst()) {
+            elem = new ArrayList<listElem>();
+            listElem el=new listElem();
+            do {
+                el.setMd5 (cursor.getString(0));
+                el.setTime(cursor.getDouble(1));
+                el.setClick(cursor.getInt(2));
+                el.setEsercizio(cursor.getString(3));
+                elem.add(el);
+            }while(cursor.moveToNext());
+        }
+        return elem;
+    }
+
+    public List<listElem> getElemForName(String user, String esName)
+    {
+        List<listElem> elem=null;
+        SQLiteDatabase db=this.getReadableDatabase();
+        String[] tableColums={
+                esercizi.COLUMN_MD5,
+                esercizi.COLUMN_TIME,
+                esercizi.COLUMN_CLICK,
+                esercizi.COLUMN_CHECK
+        };
+        String whereClause= COLUMN_UTENTE +"=? AND " + COLUMN_ESERCIZIO +"=? ORDER BY "+COLUMN_CLICK;
+        String[] whereArgs=new String[]{
+                String.valueOf(user),
+                String.valueOf(esName)
+        };
+        Cursor cursor=db.query(TABLE_NAME,tableColums,whereClause,whereArgs,null,null,null);
+        if(cursor.moveToFirst()) {
+            elem = new ArrayList<listElem>();
+            listElem el=new listElem();
+            do {
+                el.setMd5 (cursor.getString(0));
+                el.setTime(cursor.getDouble(1));
+                el.setClick(cursor.getInt(2));
+                el.setCheck(cursor.getInt(3));
+                elem.add(el);
+            }while(cursor.moveToNext());
+        }
+        return elem;
+    }
+
+    public List<listElem> getAllElem(String user)
+    {
+        List<listElem> elem=null;
+        SQLiteDatabase db=this.getReadableDatabase();
+        String[] tableColums={
+                esercizi.COLUMN_MD5,
+                esercizi.COLUMN_TIME,
+                esercizi.COLUMN_CLICK,
+                esercizi.COLUMN_ESERCIZIO,
+                esercizi.COLUMN_CHECK
+        };
+        String whereClause= COLUMN_UTENTE +"=?";
+        String[] whereArgs=new String[]{
+                String.valueOf(user)
+        };
+        Cursor cursor=db.query(TABLE_NAME,tableColums,whereClause,whereArgs,null,null,null);
+        if(cursor.moveToFirst()) {
+            elem = new ArrayList<listElem>();
+            listElem el=new listElem();
+            do {
+                el.setMd5 (cursor.getString(0));
+                el.setTime(cursor.getDouble(1));
+                el.setClick(cursor.getInt(2));
+                el.setEsercizio(cursor.getString(3));
+                el.setCheck(cursor.getInt(4));
+                elem.add(el);
+            }while(cursor.moveToNext());
+        }
+        return elem;
+    }
+
+    public void updateElem(String md5, String user, double time)
+    {
+        SQLiteDatabase db=this.getWritableDatabase();
+        String request="UPDATE "+TABLE_NAME+" set "+COLUMN_CHECK+"=1 WHERE "+COLUMN_UTENTE+"='"+user+"' AND "+COLUMN_MD5+"='"+md5+"' AND "+COLUMN_TIME+"="+time;
+        db.execSQL(request);
+    }
+
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/personalTrackerContract.java b/mainActivity/src/com/example/furt/myapplication/personalTrackerContract.java
new file mode 100755 (executable)
index 0000000..2b2d87e
--- /dev/null
@@ -0,0 +1,46 @@
+package com.example.furt.myapplication;
+
+import android.provider.BaseColumns;
+
+
+public final class personalTrackerContract {
+    // To prevent someone from accidentally instantiating the contract class,
+    // give it an empty constructor.
+    public personalTrackerContract() {
+    }
+
+    public static final int DATABASE_VERSION = 1;
+    public static final String DATABASE_NAME = "exercise.db";
+
+    private static final String TEXT_TYPE = " TEXT";
+    private static final String VALUE_TYPE=" DECIMAL";
+    private static final String COMMA_SEP = ",";
+    private static final String INT_TYPE = " INTEGER";
+    private static final String DOUBLE_TYPE=" DOUBLE";
+
+    /* Inner class that defines the table contents */
+    public static abstract class esercizi implements BaseColumns {
+
+        public static final String TABLE_NAME = " esercizi ";
+        public static final String COLUMN_ESERCIZIO = " esercizio ";
+        public static final String COLUMN_MD5 = " md5 ";
+        public static final String COLUMN_UTENTE = " utente ";
+        public static final String COLUMN_TIME = " time ";
+        public static final String COLUMN_CHECK = " checks ";
+        public static final String COLUMN_CLICK = " click ";
+
+        public static final String SQL_CREATE_ENTRIES =
+                "CREATE TABLE " + TABLE_NAME + " (" +
+                        COLUMN_UTENTE + TEXT_TYPE + COMMA_SEP +
+                        COLUMN_MD5 + TEXT_TYPE + COMMA_SEP +
+                        COLUMN_TIME + DOUBLE_TYPE + COMMA_SEP +
+                        COLUMN_CLICK + INT_TYPE + COMMA_SEP +
+                        COLUMN_ESERCIZIO + TEXT_TYPE + COMMA_SEP +
+                        COLUMN_CHECK + INT_TYPE +
+                        " )";
+
+        public static final String SQL_DELETE_ENTRIES =
+                "DROP TABLE IF EXISTS " + TABLE_NAME;
+
+    }
+}
\ No newline at end of file
diff --git a/mainActivity/src/com/example/furt/myapplication/recuperaPass.java b/mainActivity/src/com/example/furt/myapplication/recuperaPass.java
new file mode 100644 (file)
index 0000000..612af06
--- /dev/null
@@ -0,0 +1,60 @@
+package com.example.furt.myapplication;
+
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+public class recuperaPass extends Activity{
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.reimpostapass);
+        Button invia=(Button) findViewById(R.id.invia);
+        invia.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                EditText ut=(EditText) findViewById(R.id.userId);
+                EditText oP=(EditText) findViewById(R.id.oldPass);
+                EditText nP=(EditText) findViewById(R.id.newPass);
+                String utente=ut.getText().toString();
+                String oldPass=oP.getText().toString();
+                String newPass=nP.getText().toString();
+                if(utente==null || oldPass==null || newPass==null)
+                    Toast.makeText(getApplicationContext(), "devi riempire tutti i campi", Toast.LENGTH_SHORT).show();
+                else if(!utente.contains("@studio.unibo.it"))
+                    Toast.makeText(getApplicationContext(), "email non valida", Toast.LENGTH_SHORT).show();
+                else if(newPass.contains("/"))
+                    Toast.makeText(getApplicationContext(), "la password non deve contenere /", Toast.LENGTH_SHORT).show();
+                else
+                {
+                    String request = serverComunication.connessioneMain("a0/" + utente + "/" + oldPass + "/" + newPass );
+                    if(!request.contains("error"))
+                    {
+                        Intent i = new Intent(getApplicationContext(), mainActivity.class);
+                        i.putExtra("logout", "si");
+                        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                        getApplicationContext().startActivity(i);
+                    }
+                    else
+                        Toast.makeText(getApplicationContext(), "errore", Toast.LENGTH_SHORT).show();
+                }
+            }
+        });
+        Button annulla=(Button) findViewById(R.id.annulla);
+        annulla.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent i = new Intent(getApplicationContext(), mainActivity.class);
+                i.putExtra("logout", "si");
+                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                getApplicationContext().startActivity(i);
+            }
+        });
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/serverComunication.java b/mainActivity/src/com/example/furt/myapplication/serverComunication.java
new file mode 100755 (executable)
index 0000000..9ac2c79
--- /dev/null
@@ -0,0 +1,181 @@
+package com.example.furt.myapplication;
+
+
+import android.content.res.Resources;
+import android.os.AsyncTask;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.Socket;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.concurrent.ExecutionException;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManagerFactory;
+
+public class serverComunication
+{
+
+    serverComunication(){}
+
+    public static String connessione(String parametri)
+    {
+        try {
+            return new richiestaServer().execute(parametri).get();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+
+    static class richiestaServer extends AsyncTask<String, String, String> {
+        @Override
+        protected String doInBackground(String... params)
+        {
+            Resources risorse= aggiornamento.t.getResources();
+            try {
+// (could be from a resource or ByteArrayInputStream or ...)
+                CertificateFactory cf = CertificateFactory.getInstance("X.509");
+// From https://www.washington.edu/itconnect/security/ca/load-der.crt
+                InputStream caInput = risorse.openRawResource(R.raw.halloween);
+                Certificate ca;
+                try {
+                    ca = cf.generateCertificate(caInput);
+                    System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
+                } finally {
+                    caInput.close();
+                }
+
+// Create a KeyStore containing our trusted CAs
+                String keyStoreType = KeyStore.getDefaultType();
+                KeyStore keyStore = KeyStore.getInstance(keyStoreType);
+                keyStore.load(null, null);
+                keyStore.setCertificateEntry("ca", ca);
+
+// Create a TrustManager that trusts the CAs in our KeyStore
+                String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
+                TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
+                tmf.init(keyStore);
+
+// Create an SSLContext that uses our TrustManager
+                SSLContext context = SSLContext.getInstance("TLS");
+                context.init(null, tmf.getTrustManagers(), null);
+
+                Socket socket;
+                SSLSocketFactory sf=context.getSocketFactory();
+                socket=sf.createSocket(global.hostName,global.port);
+                OutputStream os = socket.getOutputStream();
+                OutputStreamWriter osw = new OutputStreamWriter(os);
+                BufferedWriter bw = new BufferedWriter(osw);
+                bw.write(params[0]+"\n");
+                bw.flush();
+                BufferedReader r = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+                String returnValue=r.readLine();
+                socket.close();
+                return returnValue;
+            } catch (KeyStoreException g) {
+                g.printStackTrace();
+            } catch (CertificateException a) {
+                a.printStackTrace();
+            } catch (NoSuchAlgorithmException b) {
+                b.printStackTrace();
+            } catch (IOException c) {
+                c.printStackTrace();
+            } catch (KeyManagementException f) {
+                f.printStackTrace();
+            }
+            return "error";
+        }
+    }
+
+    public static String connessioneMain(String parametri)
+    {
+        try {
+            return new richiestaServerMain().execute(parametri).get();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+
+    static class richiestaServerMain extends AsyncTask<String, String, String> {
+        @Override
+        protected String doInBackground(String... params)
+        {
+            Resources risorse= mainActivity.t.getResources();
+            try {
+// (could be from a resource or ByteArrayInputStream or ...)
+                CertificateFactory cf = CertificateFactory.getInstance("X.509");
+// From https://www.washington.edu/itconnect/security/ca/load-der.crt
+                InputStream caInput = risorse.openRawResource(R.raw.halloween);
+                Certificate ca;
+                try {
+                    ca = cf.generateCertificate(caInput);
+                    System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
+                } finally {
+                    caInput.close();
+                }
+
+// Create a KeyStore containing our trusted CAs
+                String keyStoreType = KeyStore.getDefaultType();
+                KeyStore keyStore = KeyStore.getInstance(keyStoreType);
+                keyStore.load(null, null);
+                keyStore.setCertificateEntry("ca", ca);
+
+// Create a TrustManager that trusts the CAs in our KeyStore
+                String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
+                TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
+                tmf.init(keyStore);
+
+// Create an SSLContext that uses our TrustManager
+                SSLContext context = SSLContext.getInstance("TLS");
+                context.init(null, tmf.getTrustManagers(), null);
+
+                Socket socket;
+                SSLSocketFactory sf=context.getSocketFactory();
+                socket=sf.createSocket(global.hostName,global.port);
+                OutputStream os = socket.getOutputStream();
+                OutputStreamWriter osw = new OutputStreamWriter(os);
+                BufferedWriter bw = new BufferedWriter(osw);
+                bw.write(params[0]+"\n");
+                bw.flush();
+                BufferedReader r = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+                String returnValue=r.readLine();
+                socket.close();
+                return returnValue;
+            } catch (KeyStoreException g) {
+                g.printStackTrace();
+            } catch (CertificateException a) {
+                a.printStackTrace();
+            } catch (NoSuchAlgorithmException b) {
+                b.printStackTrace();
+            } catch (IOException c) {
+                c.printStackTrace();
+            } catch (KeyManagementException f) {
+                f.printStackTrace();
+            }
+            return "error";
+        }
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/suString.java b/mainActivity/src/com/example/furt/myapplication/suString.java
new file mode 100755 (executable)
index 0000000..2d5fe33
--- /dev/null
@@ -0,0 +1,100 @@
+package com.example.furt.myapplication;
+
+import java.util.ArrayList;
+
+class suString
+{
+       suString()
+       {};
+       
+       public static ArrayList<String> stringToArrayList(String string)
+       {
+               ArrayList<String> returnValue=new ArrayList<String>();
+               int j=0;
+               for(int i=0;i<string.length();i++)
+               {
+                       if(string.charAt(i)=='/')
+                       {
+                                       returnValue.add(string.substring(j,i));
+                                       j=i+1;
+                       }
+                       else if(i==string.length()-1)
+                               returnValue.add(string.substring(j));
+               }
+               return returnValue;
+       }
+       
+       public static ArrayList<String> vectorStringToArrayList(String[] vectorString)
+       {
+               ArrayList<String> returnValue=new ArrayList<String>();
+               for(String name : vectorString)
+                       returnValue.add(name);
+               return returnValue;
+       }
+       
+       public static String arrayListToString (ArrayList<String> arraylist)
+       {
+               String returnValue=new String();
+               for(int i=0;i<arraylist.size();i++)
+               {
+                       if(i<arraylist.size()-1)
+                               returnValue=returnValue+arraylist.get(i)+"/";
+                       else
+                               returnValue=returnValue+arraylist.get(i);
+               }
+               return returnValue;
+       }
+       
+       public static String vectorStringToString(String[] vectorString)
+       {
+               return arrayListToString(vectorStringToArrayList(vectorString));
+       }
+       
+       public static String[] arrayListToVectorString (ArrayList<String> arraylist)
+       {
+               String[] returnValue=new String[arraylist.size()];
+               for(int i=0;i<arraylist.size();i++)
+                       returnValue[i]=arraylist.get(i);
+               return returnValue;
+       }
+       
+       public static String[] stringToVectorString(String string)
+       {
+               return arrayListToVectorString(stringToArrayList(string));
+       }
+
+    public static String multiToString(ArrayList<String> input)
+    {
+        String returnValue=null;
+        for(int i=0;i<input.size();i++)
+        {
+            if(i==0)
+                returnValue=input.get(i)+"//";
+            else if(i==input.size()-1)
+                returnValue=returnValue+input.get(i);
+            else
+                returnValue=returnValue+input.get(i)+"//";
+        }
+        return returnValue;
+    }
+
+    public static ArrayList<String> stringToMultiArray(String input)
+    {
+        ArrayList<String> result=new ArrayList<String>();
+        int j=0;
+        if(input==null)
+            return result;
+        for(int i=0;i<input.length();i++)
+        {
+            if(input.charAt(i)=='/') {
+                if (input.charAt(i + 1) == '/') {
+                    result.add(input.substring(j, i));
+                    j=i+2;
+                }
+            }
+        }
+        if(j<input.length())
+            result.add(input.substring(j,input.length()-1));
+        return result;
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/touchHPHandler.java b/mainActivity/src/com/example/furt/myapplication/touchHPHandler.java
new file mode 100755 (executable)
index 0000000..44691ce
--- /dev/null
@@ -0,0 +1,66 @@
+package com.example.furt.myapplication;
+
+import android.view.View;
+
+public class touchHPHandler implements View.OnClickListener
+{
+    Node L;
+    boolean discard;
+    Hypothesis thisHP; //ipotesi che sto eliminando
+    touchHPHandler(Node n,Hypothesis hp)
+    {
+        L=n;
+        thisHP=hp;
+        discard=true;//di default il ramo della formula scartata viene chiuso
+    }
+    public void onClick(View view)
+    {
+        if (DrawActivity.selectedNode==null) //non-existent selectedNode (should never happen)
+            return;
+        if (DrawActivity.selectedNode.Children.size()!=0) //not a leaf: can't add children
+        {
+            return;
+        }
+        if (thisHP.HP.toString().equals(DrawActivity.selectedNode.F.toString())) //close current Node
+        {
+            if (thisHP.isDeleted) {
+                if (DrawActivity.selectedNode.status == Node.OPEN)
+                    DrawActivity.selectedNode.status = Node.CANCELED;
+                else if (DrawActivity.selectedNode.status == Node.FAKE)
+                    DrawActivity.selectedNode.status = Node.FAKE_CANCELED;
+            } else {
+                if (DrawActivity.selectedNode.status == Node.OPEN)
+                    DrawActivity.selectedNode.status = Node.CLOSED;
+                else if (DrawActivity.selectedNode.status == Node.FAKE)
+                    DrawActivity.selectedNode.status = Node.FAKE_CLOSED;
+            }
+            DrawActivity.nmoves++;
+            DrawActivity.rootNode.Clean();
+            DrawActivity.startDraw();
+            return;
+        }
+        if (L==null) //incompatible elimination
+            return;
+        for (Node n:L.Children) {
+            for (Hypothesis hp:n.NodeHP)
+                hp.fromNode= DrawActivity.selectedNode; //le ipotesi dei nuovi figli provengono dal nodo in cui stanno per essere inserite
+            n.addHPList(DrawActivity.selectedNode.NodeHP);
+            DrawActivity.selectedNode.addChild(n);
+        }
+        DrawActivity.selectedNode.hasFocus=false;
+        DrawActivity.selectedNode.Children.get(0).hasFocus=true;
+        if(discard) {
+            if (thisHP.isDeleted)
+                DrawActivity.selectedNode.Children.get(0).status = Node.CANCELED;
+            else
+                DrawActivity.selectedNode.Children.get(0).status = Node.CLOSED;
+        }
+        else
+            DrawActivity.selectedNode.Children.get(0).status= Node.OPEN;
+        DrawActivity.selectedNode.hasFocus = false;
+        DrawActivity.selectedNode.ruleName = L.ruleName;
+        DrawActivity.nmoves++;
+        DrawActivity.rootNode.Clean();
+        DrawActivity.startDraw();
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/touchParserHandler.java b/mainActivity/src/com/example/furt/myapplication/touchParserHandler.java
new file mode 100755 (executable)
index 0000000..464cc09
--- /dev/null
@@ -0,0 +1,96 @@
+package com.example.furt.myapplication;
+
+import android.view.View;
+import android.widget.TextView;
+
+public class touchParserHandler implements View.OnClickListener
+{
+    int type; //0=and 1=or 2=impl 3=not 4=literal
+    char l; //for literals
+    touchParserHandler(int t,char l)
+    {
+        type=t;
+        this.l=l;
+    }
+    public void onClick(View view)
+    {
+        parserDialog.undo.add(parserDialog.F.duplicate());
+        parserDialog.formulaLayout.removeAllViews();
+        if(type==0)
+        {
+            UndefinedFormula newCursor=new UndefinedFormula();
+            newCursor.currentF=true;
+            Formula newF=new FormulaAnd(newCursor,new UndefinedFormula());
+            if ((parserDialog.F).toString().equals("_"))
+            {
+                parserDialog.F=newF;
+            }
+            else {
+                parserDialog.F.Fill(newF);
+                parserDialog.F.setCursor();
+            }
+        }
+        else if(type==1)
+        {
+            UndefinedFormula newCursor=new UndefinedFormula();
+            newCursor.currentF=true;
+            Formula newF=new FormulaOr(newCursor,new UndefinedFormula());
+            if ((parserDialog.F).toString().equals("_"))
+            {
+                parserDialog.F=newF;
+            }
+            else
+                parserDialog.F.Fill(newF);
+        }
+        else if(type==2)
+        {
+            UndefinedFormula newCursor=new UndefinedFormula();
+            newCursor.currentF=true;
+            Formula newF=new FormulaImpl(newCursor,new UndefinedFormula());
+            if ((parserDialog.F).toString().equals("_"))
+            {
+                parserDialog.F=newF;
+            }
+            else {
+                parserDialog.F.Fill(newF);
+                parserDialog.F.setCursor();
+            }
+        }
+        else if(type==3)
+        {
+            UndefinedFormula newCursor=new UndefinedFormula();
+            newCursor.currentF=true;
+            Formula newF=new FormulaNot(newCursor);
+            if ((parserDialog.F).toString().equals("_"))
+            {
+                parserDialog.F=newF;
+            }
+            else {
+                parserDialog.F.Fill(newF);
+                parserDialog.F.setCursor();
+            }
+        }
+        else if(type==4)
+        {
+            Formula newF;
+            if(l=='⊥')
+                newF=new FormulaBOT();
+            else if(l=='T')
+                newF=new FormulaTOP();
+            else
+                newF=new Literal(l);
+            if ((parserDialog.F).toString().equals("_"))
+            {
+                parserDialog.F=newF;
+            }
+            else {
+                parserDialog.F.Fill(newF);
+                parserDialog.F.setCursor();
+            }
+        }
+        TextView FView=new TextView(parserDialog.formulaLayout.getContext());
+        FView.setText(parserDialog.F.toString());
+        FView.setTextSize(DrawActivity.textSize);
+        parserDialog.formulaLayout.addView(FView);
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/touchRuleHandler.java b/mainActivity/src/com/example/furt/myapplication/touchRuleHandler.java
new file mode 100755 (executable)
index 0000000..7443ebc
--- /dev/null
@@ -0,0 +1,30 @@
+package com.example.furt.myapplication;
+import android.view.View;
+
+import java.util.List;
+
+public class touchRuleHandler implements View.OnClickListener
+{
+    List<Node> L;
+    touchRuleHandler(List<Node> list)
+    {
+        L=list;
+    }
+    public void onClick(View view)
+    {
+        if (DrawActivity.selectedNode.Children.size()!=0) //not a leaf: can't add children
+            return;
+        for (Node n:L) {
+            for (Hypothesis hp:n.NodeHP)
+                hp.fromNode= DrawActivity.selectedNode; //le ipotesi dei nuovi figli provengono dal nodo in cui stanno per essere inserite
+            n.addHPList(DrawActivity.selectedNode.NodeHP);
+            DrawActivity.selectedNode.addChild(n);
+        }
+        DrawActivity.selectedNode.hasFocus=false;
+        DrawActivity.selectedNode.ruleName=L.get(0).ruleName;
+        DrawActivity.selectedNode.Children.get(0).hasFocus=true;
+        DrawActivity.nmoves++;
+        DrawActivity.rootNode.Clean();
+        DrawActivity.startDraw();
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/touchnodeHandler.java b/mainActivity/src/com/example/furt/myapplication/touchnodeHandler.java
new file mode 100755 (executable)
index 0000000..4fcb64d
--- /dev/null
@@ -0,0 +1,157 @@
+package com.example.furt.myapplication;
+
+import android.graphics.Color;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+import android.util.Log;
+import android.graphics.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class touchnodeHandler implements View.OnClickListener {
+
+    Node n;
+    touchnodeHandler(Node node) {
+        n=node;
+    }
+    @Override
+    public void onClick(View view) {
+        TextView v=(TextView)view;
+        v.setTextColor(Color.RED);
+        if (DrawActivity.selectedNode!=null)
+            if (DrawActivity.selectedNode.view==view) {
+                if (DrawActivity.selectedNode.Children.size()==0){
+                    List<IntroductionRule> L=new ArrayList<IntroductionRule>();
+
+                    for (IntroductionRule r: DrawActivity.selectedNode.F.introductionRules())
+                    {
+                        if (r.getPriority()!=0)
+                            L.add(r);
+                    }
+                    if (L.size()==1)
+                    {
+                        Node selectedRule=L.get(0).createNodes(new askFormula());
+                        for (Node n : selectedRule.Children) {
+                            for (Hypothesis hp : n.NodeHP)
+                                hp.fromNode = DrawActivity.selectedNode; //le ipotesi dei nuovi figli provengono dal nodo in cui stanno per essere inserite
+                            n.addHPList(DrawActivity.selectedNode.NodeHP);
+                            n.handler = null;
+                            DrawActivity.selectedNode.addChild(n);
+                        }
+                        DrawActivity.selectedNode.hasFocus = false;
+                        DrawActivity.selectedNode.ruleName = selectedRule.Children.get(0).ruleName;
+                        DrawActivity.selectedNode.Children.get(0).hasFocus = true;
+                        DrawActivity.nmoves++;
+                        DrawActivity.rootNode.Clean();
+                        DrawActivity.startDraw();
+                    }
+                    else {
+                        RuleDialog ruleDialog = new RuleDialog(DrawActivity.selectedNode.F.introductionRules());
+                        ruleDialog.show(DrawActivity.fragmentManager, "CIAO");
+                    }
+                }
+                else
+                {
+                    CopyPasteDialog copyPasteDialog=new CopyPasteDialog(DrawActivity.selectedNode);
+                    copyPasteDialog.show(DrawActivity.fragmentManager,"");
+                }
+                return;
+            }
+        int i,size;
+        if (DrawActivity.selectedNode!=null) {
+            if(DrawActivity.selectedNode.status==Node.OPEN || DrawActivity.selectedNode.status==Node.FAKE)
+                DrawActivity.selectedNode.view.setTextColor(Color.BLACK);
+            else
+                DrawActivity.selectedNode.view.setTextColor(Color.GRAY);
+        }
+        DrawActivity.selectedNode = n;
+        DrawActivity.globalHP.removeAllViews();
+        size = n.NodeHP.size();
+        int leftID=0;
+        int headID=0;
+        float sum=0;
+        final Button elim=new Button(view.getContext());
+        String newText = "Nuova";
+        elim.setText(newText);
+        elim.setTextSize(TypedValue.COMPLEX_UNIT_SP,16);
+        elim.setId(DrawActivity.globalId++);
+        RelativeLayout.LayoutParams myP2=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        elim.setLayoutParams(myP2);
+        elim.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                parserDialog p=new parserDialog();
+                p.show(DrawActivity.fragmentManager, ""); //parte l'editor per inserire nuove formule
+            }
+        });
+        DrawActivity.globalHP.addView(elim);
+        Paint p = new Paint();
+        p.setTextSize(DrawActivity.textSize);
+        float newSize=p.measureText(newText)+(float)(p.measureText(newText)*0.20) + 200;
+        sum+=newSize;
+        leftID=elim.getId();
+        for (i = 0; i<size; i++) //fa apparire le ipotesi cancellate
+        {
+            final TextView newT=new TextView(view.getContext());
+            RelativeLayout.LayoutParams myP=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            newT.setText(n.NodeHP.get(i).HP.toString());
+            newT.setTextSize(TypedValue.COMPLEX_UNIT_SP,30);
+            newT.setId(DrawActivity.globalId++);
+            myP.setMargins(50,0,0,0);
+            sum+=n.NodeHP.get(i).HP.size();
+            if (sum>(DrawActivity.v.widthPixels/1.5)) //ho superato la larghezza dello schermo: devo andare a capo
+            {
+                sum=n.NodeHP.get(i).HP.size();
+                headID=leftID;
+            }
+            else
+                myP.addRule(RelativeLayout.RIGHT_OF,leftID);
+            if (headID!=0)
+                myP.addRule(RelativeLayout.BELOW,headID);
+            newT.setLayoutParams(myP);
+            List<EliminationRule> R=n.NodeHP.get(i).HP.EliminationRules();
+            if (R.size()!=0) {
+                Node L= R.get(0).createNodes(null,new askFormula());
+                newT.setOnClickListener(new touchHPHandler(L,n.NodeHP.get(i)));
+            }
+            else
+                newT.setOnClickListener(new touchHPHandler(null,n.NodeHP.get(i)));
+            newT.setOnLongClickListener(new LongHPClick(n.NodeHP.get(i).fromNode));
+            leftID=newT.getId();
+            DrawActivity.globalHP.addView(newT);
+        }
+/*
+        final Button elim=new Button(view.getContext());
+        RelativeLayout.LayoutParams myP=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        elim.setText("Nuova");
+        elim.setTextSize(TypedValue.COMPLEX_UNIT_SP,16);
+        elim.setId(DrawActivity.globalId++);
+        myP.setMargins(50,0,0,0);
+        sum+=elim.getWidth();
+        if (sum>(DrawActivity.v.widthPixels/1.5)) //ho superato la larghezza dello schermo: devo andare a capo
+        {
+            sum=n.NodeHP.get(i).HP.size();
+            headID=leftID;
+        }
+        else
+            myP.addRule(RelativeLayout.RIGHT_OF,leftID);
+        if (headID!=0)
+            myP.addRule(RelativeLayout.BELOW, headID);
+        elim.setLayoutParams(myP);
+        elim.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                parserDialog p=new parserDialog();
+                p.show(DrawActivity.fragmentManager, ""); //parte l'editor per inserire nuove formule
+            }
+        });
+        DrawActivity.globalHP.addView(elim);
+*/
+
+    }
+}
diff --git a/mainActivity/src/com/example/furt/myapplication/valutazione.java b/mainActivity/src/com/example/furt/myapplication/valutazione.java
new file mode 100644 (file)
index 0000000..86aa5fd
--- /dev/null
@@ -0,0 +1,28 @@
+package com.example.furt.myapplication;
+
+
+import java.util.ArrayList;
+
+public class valutazione {
+    valutazione(){}
+
+    public static int voto (String esercizio, int click, int tempo, int altezza, int errori)
+    {
+        int value=0;
+        ArrayList<String> parametri= parser.getParameters(esercizio);
+        int minClick, minTempo, minAltezza;
+        if(parametri!=null && !parametri.isEmpty())
+        {
+            minClick=Integer.valueOf(parametri.get(0));
+            minTempo=Integer.valueOf(parametri.get(1));
+            minAltezza=Integer.valueOf(parametri.get(2));
+            // minClick : click = x : 14
+            // minTempo : tempo = x : 8
+            // minAltezza : altezza= x : 8
+            value=((minClick*14)/click)+((minTempo*8)/tempo)+((minAltezza*8)/altezza)-errori;
+            if (value>30)
+                value=30;
+        }
+        return value;
+    }
+}