diff --git a/.gitignore b/.gitignore
index e314eb32c6126ff42c4cef06c4c26ad7897f9bbe..3622cd245b4976d460e4dc18c60ea895dfba32ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -64,3 +64,6 @@ build/
 
 ## OS Specific
 .DS_Store
+
+## iOS
+ios/robovm.properties
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index 970f0aa35cbcab6fef4ca24ef8d8c4fef7bf32ba..e9dad69e1bf1691da140766918e6f45d47a1072a 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -16,7 +16,7 @@
         <activity
             android:name="cz.nic.tablexia.android.AndroidLauncher"
             android:label="@string/app_name" 
-            android:screenOrientation="landscape"
+            android:screenOrientation="sensorLandscape"
             android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/android/assets/gfx/screen_loader_bighand.png b/android/assets/gfx/screen_loader_bighand.png
new file mode 100644
index 0000000000000000000000000000000000000000..434875f3c490e13b87a8022adb506bd3dfd029ed
Binary files /dev/null and b/android/assets/gfx/screen_loader_bighand.png differ
diff --git a/android/assets/gfx/screen_loader_smallhand.png b/android/assets/gfx/screen_loader_smallhand.png
new file mode 100644
index 0000000000000000000000000000000000000000..70dc3586db2d259be4f316e992bbc69f8a6eac2c
Binary files /dev/null and b/android/assets/gfx/screen_loader_smallhand.png differ
diff --git a/android/assets/icon/desktop_icon_devel_128.png b/android/assets/icon/desktop_icon_devel_128.png
new file mode 100644
index 0000000000000000000000000000000000000000..d5e32dcc2247e2a13cf451e660639a1824e13ef0
Binary files /dev/null and b/android/assets/icon/desktop_icon_devel_128.png differ
diff --git a/android/assets/icon/desktop_icon_devel_16.png b/android/assets/icon/desktop_icon_devel_16.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8465a9be4a2b7b401c4f197bc34b659a71e2b54
Binary files /dev/null and b/android/assets/icon/desktop_icon_devel_16.png differ
diff --git a/android/assets/icon/desktop_icon_devel_32.png b/android/assets/icon/desktop_icon_devel_32.png
new file mode 100644
index 0000000000000000000000000000000000000000..73490e182d010e867bc57dd529c5328348d88782
Binary files /dev/null and b/android/assets/icon/desktop_icon_devel_32.png differ
diff --git a/android/assets/text/application/application_cs.properties b/android/assets/text/application/application_cs.properties
index d4386f691c1b3420e178cc58a7babf31663b089e..095741916d6899b545f9b09cd664d333bf3724e3 100644
--- a/android/assets/text/application/application_cs.properties
+++ b/android/assets/text/application/application_cs.properties
@@ -9,10 +9,18 @@ mainmenu_encyclopedia=Encyklopedie
 mainmenu_preferences=NastavenĂ­
 mainmenu_about=O aplikaci
 mainmenu_logout=Odhlásit
+mainmenu_screendebug=Debug Screen
+
+gamedifficulty_easy=Lehká
+gamedifficulty_medium=Střední
+gamedifficulty_hard=Těžká
+
+victoryscreen_button_replay=Hrát znovu
+victoryscreen_button_changegame=Jinou hru
 
 game_robbery_title=LupiÄŤi
 game_kidnapping_title=Ăšnos
 game_pursuit_title=Pronásledování
 game_night_watch_title=HlĂ­dka
 game_shooting_range_title=Střelnice
-game_in_the_darkness_title=PotmÄ›
\ No newline at end of file
+game_in_the_darkness_title=PotmÄ›
diff --git a/android/assets/text/application/application_sk.properties b/android/assets/text/application/application_sk.properties
index d4c46b7076da1910e37015b1a6140c01949d5b1c..ed092ed093b5b0a4f3ffe2c11c2ec8ea941ad0e4 100644
--- a/android/assets/text/application/application_sk.properties
+++ b/android/assets/text/application/application_sk.properties
@@ -9,6 +9,14 @@ mainmenu_encyclopedia=Encyklopédia
 mainmenu_preferences=Nastavenie
 mainmenu_about=O aplikácií
 mainmenu_logout=Odhlásiť
+mainmenu_screendebug=Debug Screen
+
+gamedifficulty_easy=Ľahká
+gamedifficulty_medium=Stredná
+gamedifficulty_hard=Ťažká
+
+victoryscreen_button_replay=Hráť znovu
+victoryscreen_button_changegame=InĂş hru
 
 game_robbery_title=LupiÄŤi
 game_kidnapping_title=Ăšnos
diff --git a/android/build.gradle b/android/build.gradle
index 96b30896c966a8b20717e358697b46e47fbfe7bf..07907990409c1c55626d478b407db27339158420 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -1,6 +1,20 @@
 android {
     buildToolsVersion "21.1.2"
     compileSdkVersion 21
+
+    buildTypes {
+        debug {
+            applicationIdSuffix rootProject.applicationIdDebugSuffix
+        }
+        release {
+            debuggable false
+        }
+        devel.initWith(buildTypes.debug)
+        devel {
+            applicationIdSuffix rootProject.applicationIdDevelSuffix
+        }
+    }
+
     sourceSets {
         main {
             manifest.srcFile 'AndroidManifest.xml'
@@ -16,29 +30,27 @@ android {
         debug {
             res.srcDirs = ['res/debug']
         }
+        devel {
+            res.srcDirs = ['res/devel']
+        }
 
         instrumentTest.setRoot('tests')
     }
 
     defaultConfig {
-        versionName version
-        versionCode getVersionCodeFromGit()
+        versionName tablexiaVersionName
+        versionCode tablexiaVersionCode
         applicationId rootProject.applicationIdRelease
     }
 
-    buildTypes {
-        debug {
-            applicationIdSuffix rootProject.applicationIdDebugSuffix
-        }
-        release {
-            debuggable false
-        }
-    }
+    assemble.dependsOn = ['assembleRelease', 'assembleDebug']
 
     applicationVariants.all { variant ->
-        variant.outputs.each { output ->
-            def file = output.outputFile
-            output.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk").replace("android", appName))
+        if (!variant.buildType.name.equals("devel")) {
+            variant.outputs.each { output ->
+                def file = output.outputFile
+                output.outputFile = new File(file.parent, file.name.replace(".apk", "-" + tablexiaVersionName + ".apk").replace("android", appName))
+            }
         }
     }
 
@@ -59,15 +71,10 @@ android {
             }
         }
     }
-}
-
-def getVersionCodeFromGit() {
-    def stdout = new ByteArrayOutputStream()
-    exec {
-        commandLine 'git', 'log', '-1', '--format=%at'
-        standardOutput = stdout
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_6
+        targetCompatibility JavaVersion.VERSION_1_6
     }
-    return stdout.toString().trim().toInteger()
 }
 
 // needed to add JNI shared libraries to APK when compiling on CLI
diff --git a/android/res/devel/drawable-hdpi/ic_launcher.png b/android/res/devel/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e6f34723225e9fe83d239f308914c98de7d0f62
Binary files /dev/null and b/android/res/devel/drawable-hdpi/ic_launcher.png differ
diff --git a/android/res/devel/drawable-mdpi/ic_launcher.png b/android/res/devel/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..2cf055d553b8fe5558bc6ed5adb84d60655c9605
Binary files /dev/null and b/android/res/devel/drawable-mdpi/ic_launcher.png differ
diff --git a/android/res/devel/drawable-xhdpi/ic_launcher.png b/android/res/devel/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..02c60069912e99900bf404623d4ea381a0e948f0
Binary files /dev/null and b/android/res/devel/drawable-xhdpi/ic_launcher.png differ
diff --git a/android/res/devel/drawable-xxhdpi/ic_launcher.png b/android/res/devel/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..8d56688f36ddcd50e4963ac01d9bd94e6a8b9a6f
Binary files /dev/null and b/android/res/devel/drawable-xxhdpi/ic_launcher.png differ
diff --git a/android/res/devel/drawable-xxxhdpi/ic_launcher.png b/android/res/devel/drawable-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..9eb69cd2395b1d75e846047a92463a08835f69c5
Binary files /dev/null and b/android/res/devel/drawable-xxxhdpi/ic_launcher.png differ
diff --git a/android/src/cz/nic/tablexia/android/AndroidLauncher.java b/android/src/cz/nic/tablexia/android/AndroidLauncher.java
index 5627f27c120a1031f4bd2ed25d0a3c88199ebe9e..0ba59c0a53be801cc811a18eb473dadcc6506a47 100644
--- a/android/src/cz/nic/tablexia/android/AndroidLauncher.java
+++ b/android/src/cz/nic/tablexia/android/AndroidLauncher.java
@@ -13,6 +13,6 @@ public class AndroidLauncher extends AndroidApplication {
 	protected void onCreate (Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
-		initialize(new Tablexia(BuildConfig.DEBUG, getResources().getConfiguration().locale, BuildConfig.VERSION_NAME, BuildConfig.APPLICATION_ID), config);
+        initialize(new Tablexia(BuildConfig.BUILD_TYPE, getResources().getConfiguration().locale, BuildConfig.VERSION_NAME, savedInstanceState == null), config);
 	}
 }
diff --git a/build.gradle b/build.gradle
index fd0bc582ea8e4507c0999435400eb8bada27e044..8267576591eee1813daaf78ad234c2898235ba9d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ buildscript {
     dependencies {
         classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
         classpath 'com.android.tools.build:gradle:1.0.0'
-        classpath 'org.robovm:robovm-gradle-plugin:1.0.0-beta-01'
+        classpath 'org.robovm:robovm-gradle-plugin:1.0.0'
     }
 }
 
@@ -15,16 +15,21 @@ allprojects {
     apply plugin: "idea"
 
     version = getVersionNameFromGit()
-    project.extensions.add("applicationIdRelease", "cz.nic.tablexia")
-    project.extensions.add("applicationIdDebugSuffix", ".debug")
-    project.extensions.add("applicationIdDebug", applicationIdRelease + applicationIdDebugSuffix)
 
     ext {
         appName = 'Tablexia'
-        gdxVersion = '1.5.2'
+        tablexiaVersionName = getVersionNameFromGit()
+        tablexiaVersionCode = getVersionCodeFromGit()
+        applicationIdRelease = 'cz.nic.tablexia'
+        applicationIdDebugSuffix = '.debug'
+        applicationIdDebug = applicationIdRelease + applicationIdDebugSuffix
+        applicationIdDevelSuffix = '.devel'
+        applicationIdDevel = applicationIdRelease + applicationIdDevelSuffix
+
+        gdxVersion = '1.5.5'
 		gdxUtilsVersion = '0.9.1'
 	    mbassadorVersion = '1.2.0'
-        roboVMVersion = '1.0.0-beta-01'
+        roboVMVersion = '1.0.0'
         box2DLightsVersion = '1.3'
         ashleyVersion = '1.3.1'
         aiVersion = '1.4.0'
@@ -46,6 +51,15 @@ def getVersionNameFromGit() {
     return stdout.toString().trim()
 }
 
+def getVersionCodeFromGit() {
+    def stdout = new ByteArrayOutputStream()
+    exec {
+        commandLine 'git', 'log', '-1', '--format=%at'
+        standardOutput = stdout
+    }
+    return stdout.toString().trim().toInteger()
+}
+
 task zipAssets(type:Zip) {
 
 	new File(project(":core").projectDir.absolutePath + "/assets").eachDir() { dir ->
diff --git a/core/assets/common/application/victoryscreen/ratingstar_disabled.png b/core/assets/common/application/victoryscreen/ratingstar_disabled.png
new file mode 100644
index 0000000000000000000000000000000000000000..86bb89f6bce744f735d635514b954b64477829c1
Binary files /dev/null and b/core/assets/common/application/victoryscreen/ratingstar_disabled.png differ
diff --git a/core/assets/common/application/victoryscreen/ratingstar_enabled.png b/core/assets/common/application/victoryscreen/ratingstar_enabled.png
new file mode 100644
index 0000000000000000000000000000000000000000..a922caadf9bcfaa081fe1cbc8accdae3224731a6
Binary files /dev/null and b/core/assets/common/application/victoryscreen/ratingstar_enabled.png differ
diff --git a/core/assets/common/application/victoryscreen/resultsbanner.png b/core/assets/common/application/victoryscreen/resultsbanner.png
new file mode 100644
index 0000000000000000000000000000000000000000..84d90067a6ff5a5ce89fe474f9e9366fd6ece596
Binary files /dev/null and b/core/assets/common/application/victoryscreen/resultsbanner.png differ
diff --git a/core/assets/common/screen/createuser/panorama/balcony.png b/core/assets/common/screen/createuser/panorama/balcony.png
new file mode 100644
index 0000000000000000000000000000000000000000..8bd4cc8b4608c091005fbfa2493166e139a3b1dd
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/balcony.png differ
diff --git a/core/assets/common/screen/createuser/panorama/balcony_blur.png b/core/assets/common/screen/createuser/panorama/balcony_blur.png
new file mode 100644
index 0000000000000000000000000000000000000000..c50d427fbacc059e88b88c7d78872ae24961961b
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/balcony_blur.png differ
diff --git a/core/assets/common/screen/createuser/panorama/balcony_blur_winter.png b/core/assets/common/screen/createuser/panorama/balcony_blur_winter.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f3aee846d931cbe5a34ba435fca28ef70305187
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/balcony_blur_winter.png differ
diff --git a/core/assets/common/screen/createuser/panorama/balcony_winter.png b/core/assets/common/screen/createuser/panorama/balcony_winter.png
new file mode 100644
index 0000000000000000000000000000000000000000..af56bbf7d8775deb50a35511b9d8d194e0a1daea
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/balcony_winter.png differ
diff --git a/core/assets/common/screen/createuser/panorama/detectiveoffice.png b/core/assets/common/screen/createuser/panorama/detectiveoffice.png
new file mode 100644
index 0000000000000000000000000000000000000000..537bdfddaa8494a456007c3f8212ae54c4864b2a
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/detectiveoffice.png differ
diff --git a/core/assets/common/screen/createuser/panorama/newspaper/newspaper.png b/core/assets/common/screen/createuser/panorama/newspaper/newspaper.png
new file mode 100644
index 0000000000000000000000000000000000000000..0db074adecdceeac93d247a905737d49e28d6153
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/newspaper/newspaper.png differ
diff --git a/core/assets/common/screen/createuser/panorama/newspaper/open1.png b/core/assets/common/screen/createuser/panorama/newspaper/open1.png
new file mode 100644
index 0000000000000000000000000000000000000000..84f5697d79fe0105d48527190f5b922b7aed5f30
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/newspaper/open1.png differ
diff --git a/core/assets/common/screen/createuser/panorama/newspaper/open2.png b/core/assets/common/screen/createuser/panorama/newspaper/open2.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb96d14a0a335b6eb0764f00fe53a591bb66b28f
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/newspaper/open2.png differ
diff --git a/core/assets/common/screen/createuser/panorama/newspaper/open3.png b/core/assets/common/screen/createuser/panorama/newspaper/open3.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b4b0a40527d37d241f7af6c82a76cfcf83a7baa
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/newspaper/open3.png differ
diff --git a/core/assets/common/screen/createuser/panorama/newspaper/open4.png b/core/assets/common/screen/createuser/panorama/newspaper/open4.png
new file mode 100644
index 0000000000000000000000000000000000000000..7dd51ca11fcb32ac1e74d76b7f0cacaf777755b6
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/newspaper/open4.png differ
diff --git a/core/assets/common/screen/createuser/panorama/newspaper/open5.png b/core/assets/common/screen/createuser/panorama/newspaper/open5.png
new file mode 100644
index 0000000000000000000000000000000000000000..26431c9245e959b18dd485dde6e9bafa3a5a051b
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/newspaper/open5.png differ
diff --git a/core/assets/common/screen/createuser/panorama/swipe/tile0.png b/core/assets/common/screen/createuser/panorama/swipe/tile0.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c59b7a077ba41dba7735998ac6843ef1fdd34e8
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/swipe/tile0.png differ
diff --git a/core/assets/common/screen/createuser/panorama/swipe/tile1.png b/core/assets/common/screen/createuser/panorama/swipe/tile1.png
new file mode 100644
index 0000000000000000000000000000000000000000..073b30a31c87b3355dc8177f6d0a8adb9bb2830c
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/swipe/tile1.png differ
diff --git a/core/assets/common/screen/createuser/panorama/swipe/tile2.png b/core/assets/common/screen/createuser/panorama/swipe/tile2.png
new file mode 100644
index 0000000000000000000000000000000000000000..e25b1d89c51f782e1e5095776c462a15ce22c9da
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/swipe/tile2.png differ
diff --git a/core/assets/common/screen/createuser/panorama/swipe/tile3.png b/core/assets/common/screen/createuser/panorama/swipe/tile3.png
new file mode 100644
index 0000000000000000000000000000000000000000..86b4f94d6799e10dd751622f80012edfc816231d
Binary files /dev/null and b/core/assets/common/screen/createuser/panorama/swipe/tile3.png differ
diff --git a/core/assets/common/screen/debug/black.png b/core/assets/common/screen/debug/black.png
new file mode 100644
index 0000000000000000000000000000000000000000..d8fc30a3129c1ed8bf6f5c1ffb25a031c3e894ea
Binary files /dev/null and b/core/assets/common/screen/debug/black.png differ
diff --git a/core/assets/common/screen/debug/blue.png b/core/assets/common/screen/debug/blue.png
new file mode 100644
index 0000000000000000000000000000000000000000..c3870f917f4968a8db714a3628a502e7fc310841
Binary files /dev/null and b/core/assets/common/screen/debug/blue.png differ
diff --git a/core/assets/common/screen/debug/checker.png b/core/assets/common/screen/debug/checker.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b6cf9854d9be63a361d443eb0bbca60813714b2
Binary files /dev/null and b/core/assets/common/screen/debug/checker.png differ
diff --git a/core/assets/common/screen/debug/pink.png b/core/assets/common/screen/debug/pink.png
new file mode 100644
index 0000000000000000000000000000000000000000..26eb49ed2d2bc4562b4b7bf96c20f6d45268bebe
Binary files /dev/null and b/core/assets/common/screen/debug/pink.png differ
diff --git a/core/assets/common/screen/debug/point.png b/core/assets/common/screen/debug/point.png
new file mode 100644
index 0000000000000000000000000000000000000000..e5328a7b3a237e8774cda4b5fd7132826a4c5a4f
Binary files /dev/null and b/core/assets/common/screen/debug/point.png differ
diff --git a/core/assets/common/screen/debug/red.png b/core/assets/common/screen/debug/red.png
new file mode 100644
index 0000000000000000000000000000000000000000..5bc4cc83c9b5d765531cf3061344e26ba428e430
Binary files /dev/null and b/core/assets/common/screen/debug/red.png differ
diff --git a/core/assets/common/screen/debug/yellow.png b/core/assets/common/screen/debug/yellow.png
new file mode 100644
index 0000000000000000000000000000000000000000..de8ab0bd398bc00d945e679e6a301d971caa7f2f
Binary files /dev/null and b/core/assets/common/screen/debug/yellow.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/bankovniloupez_back.png b/core/assets/common/screen/gamemenu/gfx/bankovniloupez_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9d3c637e1255f67af94b207b0d9fd6883fb4772
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/bankovniloupez_back.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/bankovniloupez_fore.png b/core/assets/common/screen/gamemenu/gfx/bankovniloupez_fore.png
new file mode 100644
index 0000000000000000000000000000000000000000..59057615e33af54d54e6b28fd18da85c705a9b00
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/bankovniloupez_fore.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/bankovniloupez_mid.png b/core/assets/common/screen/gamemenu/gfx/bankovniloupez_mid.png
new file mode 100644
index 0000000000000000000000000000000000000000..74775e68cb0df75051b39285e3c386e53348c2d9
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/bankovniloupez_mid.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/clickablemap.png b/core/assets/common/screen/gamemenu/gfx/clickablemap.png
new file mode 100644
index 0000000000000000000000000000000000000000..73f656ead93ad3c7254dc2c462595db870ec2547
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/clickablemap.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/desk.png b/core/assets/common/screen/gamemenu/gfx/desk.png
new file mode 100644
index 0000000000000000000000000000000000000000..38fc8f00f6ac77a0aa08429bc99265a755f6a251
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/desk.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_background.png b/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_background.png
new file mode 100644
index 0000000000000000000000000000000000000000..e1d041a849ed53819e103ebcbf1e5204a3e79249
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_background.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb.png b/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb.png
new file mode 100644
index 0000000000000000000000000000000000000000..84637dbdd975ba3dc1970372cb42a4cf778bb281
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb_easy.png b/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb_easy.png
new file mode 100644
index 0000000000000000000000000000000000000000..c28f25ec3b430b7adc0ce29eb6dba44fa790b2b5
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb_easy.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb_hard.png b/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb_hard.png
new file mode 100644
index 0000000000000000000000000000000000000000..d77974303da7325a8b60b7427e33dd5905b6295b
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb_hard.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb_medium.png b/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb_medium.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb167c4d9371c20def7c9ba895b50881e107df5b
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/difficultyseekbar_thumb_medium.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/encyclopedia_pressed.png b/core/assets/common/screen/gamemenu/gfx/encyclopedia_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..74db6065095ddb394f41fbea5dbd6776d5f9c2b4
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/encyclopedia_pressed.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/halloffame_pressed.png b/core/assets/common/screen/gamemenu/gfx/halloffame_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..2b3f290191f25e8c2b6d15267c1e3be3e70396b3
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/halloffame_pressed.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/helpbutton_pressed.png b/core/assets/common/screen/gamemenu/gfx/helpbutton_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d64dd431a759b34179623c5c3896fec12b2829a
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/helpbutton_pressed.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/helpbutton_unpressed.png b/core/assets/common/screen/gamemenu/gfx/helpbutton_unpressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..66c6fc7a9f0789f4c74311743a1f35580aadd60e
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/helpbutton_unpressed.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/helplayer_clickablemap.png b/core/assets/common/screen/gamemenu/gfx/helplayer_clickablemap.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f4734cfbc95dfaccac0341bcef4d8e70056a4aa
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/helplayer_clickablemap.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/nocnisledovani_back.png b/core/assets/common/screen/gamemenu/gfx/nocnisledovani_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..663b9c0d5236dfe49b6090a53b9a8ac8d4e27bed
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/nocnisledovani_back.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/nocnisledovani_fore.png b/core/assets/common/screen/gamemenu/gfx/nocnisledovani_fore.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f3727508f0cbef101f675d490ede92f8d4911c6
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/nocnisledovani_fore.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/nocnisledovani_mid.png b/core/assets/common/screen/gamemenu/gfx/nocnisledovani_mid.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2ec630adcf5a9dbf548fd17a0e3096b26ff1625
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/nocnisledovani_mid.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/overlay.png b/core/assets/common/screen/gamemenu/gfx/overlay.png
new file mode 100644
index 0000000000000000000000000000000000000000..d8fc30a3129c1ed8bf6f5c1ffb25a031c3e894ea
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/overlay.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/potme_back.png b/core/assets/common/screen/gamemenu/gfx/potme_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..6eabf1d99e7bed3f680584bb6fbfadae3a538e70
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/potme_back.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/potme_fore.png b/core/assets/common/screen/gamemenu/gfx/potme_fore.png
new file mode 100644
index 0000000000000000000000000000000000000000..723044ed2001fd145670b2b415cd5b414f4dfbf5
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/potme_fore.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/potme_mid.png b/core/assets/common/screen/gamemenu/gfx/potme_mid.png
new file mode 100644
index 0000000000000000000000000000000000000000..017bffca99d67c5d5f5c96948a1d3dbe1620d71b
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/potme_mid.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/profile_pressed.png b/core/assets/common/screen/gamemenu/gfx/profile_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..2c2e54e9b36f299988c011522fdb55e61e607e25
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/profile_pressed.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/pronasledovani_back.png b/core/assets/common/screen/gamemenu/gfx/pronasledovani_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..cf8a55f8c84d57c0120a450fbf5b4260b71c9299
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/pronasledovani_back.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/pronasledovani_fore.png b/core/assets/common/screen/gamemenu/gfx/pronasledovani_fore.png
new file mode 100644
index 0000000000000000000000000000000000000000..753143e8a2809687a62696bf9dc590262888da07
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/pronasledovani_fore.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/pronasledovani_mid.png b/core/assets/common/screen/gamemenu/gfx/pronasledovani_mid.png
new file mode 100644
index 0000000000000000000000000000000000000000..a97adfee1cc802af3795a8089e59ae6e0ed51aad
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/pronasledovani_mid.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/statistics_pressed.png b/core/assets/common/screen/gamemenu/gfx/statistics_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..bebbb128babf83e47ee69a41852d63938206236b
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/statistics_pressed.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/streetdoor_pressed.png b/core/assets/common/screen/gamemenu/gfx/streetdoor_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..af4b3a8e16edf7211a31ec22be11c1decbcc3ed6
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/streetdoor_pressed.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/strelnice_back.png b/core/assets/common/screen/gamemenu/gfx/strelnice_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..10333b95475123376c6067f3c1d34f025d57a04e
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/strelnice_back.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/strelnice_fore.png b/core/assets/common/screen/gamemenu/gfx/strelnice_fore.png
new file mode 100644
index 0000000000000000000000000000000000000000..c4a0a41e2e8e05225247bafb190d0ec910043e39
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/strelnice_fore.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/strelnice_mid.png b/core/assets/common/screen/gamemenu/gfx/strelnice_mid.png
new file mode 100644
index 0000000000000000000000000000000000000000..f543837c39eb520cd93aeb74baa5d991684191d0
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/strelnice_mid.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/unos_back.png b/core/assets/common/screen/gamemenu/gfx/unos_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d6448ea367f76be9c1b5f2bf172a45d2fa8e301
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/unos_back.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/unos_fore.png b/core/assets/common/screen/gamemenu/gfx/unos_fore.png
new file mode 100644
index 0000000000000000000000000000000000000000..a741561713869570be5e47648fc414190df73d1a
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/unos_fore.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/unos_mid.png b/core/assets/common/screen/gamemenu/gfx/unos_mid.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ba240c927532ba1052b7b832a984a2d5eaffac8
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/unos_mid.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/vignetting.png b/core/assets/common/screen/gamemenu/gfx/vignetting.png
new file mode 100644
index 0000000000000000000000000000000000000000..c9247ca51177da00cb240b86720de9699deb450e
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/vignetting.png differ
diff --git a/core/assets/common/screen/profile/background.png b/core/assets/common/screen/profile/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..739d3949bf7550fa62fad0619a5eec42dd55e930
Binary files /dev/null and b/core/assets/common/screen/profile/background.png differ
diff --git a/core/assets/common/screen/profile/ink.png b/core/assets/common/screen/profile/ink.png
new file mode 100644
index 0000000000000000000000000000000000000000..13ce5d7757043e0e53be948d94a2123ecccc1dec
Binary files /dev/null and b/core/assets/common/screen/profile/ink.png differ
diff --git a/core/assets/common/screen/profile/inkpad.png b/core/assets/common/screen/profile/inkpad.png
new file mode 100644
index 0000000000000000000000000000000000000000..eed2a9a6bcb632ada3c70a7a6cead0a4b0f33963
Binary files /dev/null and b/core/assets/common/screen/profile/inkpad.png differ
diff --git a/core/assets/common/screen/profile/mugshotframe.png b/core/assets/common/screen/profile/mugshotframe.png
new file mode 100644
index 0000000000000000000000000000000000000000..525b4cac6a429886d170ab197bdd2f18515f4c22
Binary files /dev/null and b/core/assets/common/screen/profile/mugshotframe.png differ
diff --git a/core/assets/common/screen/profile/pencil.png b/core/assets/common/screen/profile/pencil.png
new file mode 100644
index 0000000000000000000000000000000000000000..5460327ad85d9900e87cedb4e658964106d5e1ee
Binary files /dev/null and b/core/assets/common/screen/profile/pencil.png differ
diff --git a/core/assets/common/screen/profile/pencil_dropped.png b/core/assets/common/screen/profile/pencil_dropped.png
new file mode 100644
index 0000000000000000000000000000000000000000..cab6f998fe0687c7f04f48cf6a42a42356ac7eee
Binary files /dev/null and b/core/assets/common/screen/profile/pencil_dropped.png differ
diff --git a/core/assets/common/screen/profile/pencil_dropped_selected.png b/core/assets/common/screen/profile/pencil_dropped_selected.png
new file mode 100644
index 0000000000000000000000000000000000000000..88b505ad15afada3ad5f464bf1b2f993c952d25c
Binary files /dev/null and b/core/assets/common/screen/profile/pencil_dropped_selected.png differ
diff --git a/core/assets/common/screen/profile/pencil_grabbed.png b/core/assets/common/screen/profile/pencil_grabbed.png
new file mode 100644
index 0000000000000000000000000000000000000000..67167e89250334ac98f4fc4baa679a56ae84d220
Binary files /dev/null and b/core/assets/common/screen/profile/pencil_grabbed.png differ
diff --git a/core/assets/common/screen/profile/sex_female.png b/core/assets/common/screen/profile/sex_female.png
new file mode 100644
index 0000000000000000000000000000000000000000..40ed86d45c1ccdeb53068afffc147b10d4fefb14
Binary files /dev/null and b/core/assets/common/screen/profile/sex_female.png differ
diff --git a/core/assets/common/screen/profile/sex_male.png b/core/assets/common/screen/profile/sex_male.png
new file mode 100644
index 0000000000000000000000000000000000000000..2640eb2ac943b163fef8e8f70fe1a2f221d5f9a7
Binary files /dev/null and b/core/assets/common/screen/profile/sex_male.png differ
diff --git a/core/assets/common/screen/profile/signature_background.9.png b/core/assets/common/screen/profile/signature_background.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..34a8684782808b80af8fd556e3b6dd0b8eb73a19
Binary files /dev/null and b/core/assets/common/screen/profile/signature_background.9.png differ
diff --git a/core/assets/common/screen/profile/stamp.png b/core/assets/common/screen/profile/stamp.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e80db058bac023e45e67c2a7f06663bb1c0509c
Binary files /dev/null and b/core/assets/common/screen/profile/stamp.png differ
diff --git a/core/assets/common/screen/profile/stamp_left_dropped.png b/core/assets/common/screen/profile/stamp_left_dropped.png
new file mode 100644
index 0000000000000000000000000000000000000000..4a9f24702ed6332c89da92348496173dec561bc0
Binary files /dev/null and b/core/assets/common/screen/profile/stamp_left_dropped.png differ
diff --git a/core/assets/common/screen/profile/stamp_left_grabbed.png b/core/assets/common/screen/profile/stamp_left_grabbed.png
new file mode 100644
index 0000000000000000000000000000000000000000..6dc7f8c326d1341c5c9e811c3d1a68fa70616c95
Binary files /dev/null and b/core/assets/common/screen/profile/stamp_left_grabbed.png differ
diff --git a/core/assets/common/screen/profile/stamp_left_selected.png b/core/assets/common/screen/profile/stamp_left_selected.png
new file mode 100644
index 0000000000000000000000000000000000000000..7e285f93da545c703e1d12011c0970726d07af6a
Binary files /dev/null and b/core/assets/common/screen/profile/stamp_left_selected.png differ
diff --git a/core/assets/common/screen/profile/stamp_middle_dropped.png b/core/assets/common/screen/profile/stamp_middle_dropped.png
new file mode 100644
index 0000000000000000000000000000000000000000..39a6962e70210e5228dfe9d518467695af0f3a4c
Binary files /dev/null and b/core/assets/common/screen/profile/stamp_middle_dropped.png differ
diff --git a/core/assets/common/screen/profile/stamp_middle_grabbed.png b/core/assets/common/screen/profile/stamp_middle_grabbed.png
new file mode 100644
index 0000000000000000000000000000000000000000..765902e61bd12e4af761d0094ce80c49596f0533
Binary files /dev/null and b/core/assets/common/screen/profile/stamp_middle_grabbed.png differ
diff --git a/core/assets/common/screen/profile/stamp_right_dropped.png b/core/assets/common/screen/profile/stamp_right_dropped.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f28651c6f40775a56b7af8e7f5cd2aa8b883896
Binary files /dev/null and b/core/assets/common/screen/profile/stamp_right_dropped.png differ
diff --git a/core/assets/common/screen/profile/stamp_right_grabbed.png b/core/assets/common/screen/profile/stamp_right_grabbed.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c90a45d977d7e251bc528af91e635da0e180706
Binary files /dev/null and b/core/assets/common/screen/profile/stamp_right_grabbed.png differ
diff --git a/core/assets/common/screen/profile/stampplaceholder.png b/core/assets/common/screen/profile/stampplaceholder.png
new file mode 100644
index 0000000000000000000000000000000000000000..1412e8205cf2bb95a4d4d75a8045848a74f22925
Binary files /dev/null and b/core/assets/common/screen/profile/stampplaceholder.png differ
diff --git a/core/assets/common/screen/profile/table.png b/core/assets/common/screen/profile/table.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2b0e26c037723806231dc09d8b571f64648f0c9
Binary files /dev/null and b/core/assets/common/screen/profile/table.png differ
diff --git a/core/assets/cs/screen/createuser/panorama/newspaper/detail01.png b/core/assets/cs/screen/createuser/panorama/newspaper/detail01.png
new file mode 100644
index 0000000000000000000000000000000000000000..55d7c9e036690dc887f7725e1bec551d2f32d066
Binary files /dev/null and b/core/assets/cs/screen/createuser/panorama/newspaper/detail01.png differ
diff --git a/core/assets/cs/screen/createuser/panorama/newspaper/detail02.png b/core/assets/cs/screen/createuser/panorama/newspaper/detail02.png
new file mode 100644
index 0000000000000000000000000000000000000000..a957ccb0eaaf65a07de48d910d068a2d37541826
Binary files /dev/null and b/core/assets/cs/screen/createuser/panorama/newspaper/detail02.png differ
diff --git a/core/assets/cs/screen/createuser/panorama/newspaper/detail03.png b/core/assets/cs/screen/createuser/panorama/newspaper/detail03.png
new file mode 100644
index 0000000000000000000000000000000000000000..f991753da10e867e23da437f1e6b99b65d4eb2f0
Binary files /dev/null and b/core/assets/cs/screen/createuser/panorama/newspaper/detail03.png differ
diff --git a/core/assets/cs/screen/createuser/panorama/newspaper/detail04.png b/core/assets/cs/screen/createuser/panorama/newspaper/detail04.png
new file mode 100644
index 0000000000000000000000000000000000000000..887737f2dbe3bfd44f855e8066d90ff066bd74af
Binary files /dev/null and b/core/assets/cs/screen/createuser/panorama/newspaper/detail04.png differ
diff --git a/core/assets/cs/screen/createuser/panorama/newspaper/detail05.png b/core/assets/cs/screen/createuser/panorama/newspaper/detail05.png
new file mode 100644
index 0000000000000000000000000000000000000000..4d5480a69ce336ed74a02742c563140d75739020
Binary files /dev/null and b/core/assets/cs/screen/createuser/panorama/newspaper/detail05.png differ
diff --git a/core/assets/cs/screen/createuser/panorama/newspaper/opened.png b/core/assets/cs/screen/createuser/panorama/newspaper/opened.png
new file mode 100644
index 0000000000000000000000000000000000000000..10efe5d47481ea0d778f86a54609c1d09e11731d
Binary files /dev/null and b/core/assets/cs/screen/createuser/panorama/newspaper/opened.png differ
diff --git a/core/assets/cs/screen/createuser/panorama/swipe/door.png b/core/assets/cs/screen/createuser/panorama/swipe/door.png
new file mode 100644
index 0000000000000000000000000000000000000000..4bbd9e8c9b927f50803a7dded26e509f2afbe966
Binary files /dev/null and b/core/assets/cs/screen/createuser/panorama/swipe/door.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/bankovniloupez_startbutton.png b/core/assets/cs/screen/gamemenu/gfx/bankovniloupez_startbutton.png
new file mode 100644
index 0000000000000000000000000000000000000000..515e06848856a1584d07115a81ed9ec75af6ca00
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/bankovniloupez_startbutton.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/bankovniloupez_startbutton_pressed.png b/core/assets/cs/screen/gamemenu/gfx/bankovniloupez_startbutton_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..74b1cfa1cb68dd408289a42a74e47952f5526f70
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/bankovniloupez_startbutton_pressed.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/bankovniloupez_title.png b/core/assets/cs/screen/gamemenu/gfx/bankovniloupez_title.png
new file mode 100644
index 0000000000000000000000000000000000000000..b0d8c541a4f0b0d5eb1fcba1838aab40286c6476
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/bankovniloupez_title.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/helplayer.png b/core/assets/cs/screen/gamemenu/gfx/helplayer.png
new file mode 100644
index 0000000000000000000000000000000000000000..ef6ac7ca9283901add57541243ccbe741c211fc9
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/helplayer.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/nocnisledovani_startbutton.png b/core/assets/cs/screen/gamemenu/gfx/nocnisledovani_startbutton.png
new file mode 100644
index 0000000000000000000000000000000000000000..e6b737671776ba40e084f48909f308c7ea5f8563
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/nocnisledovani_startbutton.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/nocnisledovani_startbutton_pressed.png b/core/assets/cs/screen/gamemenu/gfx/nocnisledovani_startbutton_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..625fc79fe25b5676650928a0526ba858aceedba9
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/nocnisledovani_startbutton_pressed.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/nocnisledovani_title.png b/core/assets/cs/screen/gamemenu/gfx/nocnisledovani_title.png
new file mode 100644
index 0000000000000000000000000000000000000000..261d0dd0c15dc41a2a8c5efd6833d0e8499ea6b9
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/nocnisledovani_title.png differ
diff --git a/core/assets/cs/screen/gamemenu/screen_gamemenu_startmenu_background.jpg b/core/assets/cs/screen/gamemenu/gfx/office.jpg
similarity index 100%
rename from core/assets/cs/screen/gamemenu/screen_gamemenu_startmenu_background.jpg
rename to core/assets/cs/screen/gamemenu/gfx/office.jpg
diff --git a/core/assets/cs/screen/gamemenu/gfx/potme_startbutton.png b/core/assets/cs/screen/gamemenu/gfx/potme_startbutton.png
new file mode 100644
index 0000000000000000000000000000000000000000..f38ebf062a39a51a8bb5674d4d47ba78797c9779
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/potme_startbutton.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/potme_startbutton_pressed.png b/core/assets/cs/screen/gamemenu/gfx/potme_startbutton_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce252cdc69a0b48eec7744fc6d3a95ccad3e4ae8
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/potme_startbutton_pressed.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/potme_title.png b/core/assets/cs/screen/gamemenu/gfx/potme_title.png
new file mode 100644
index 0000000000000000000000000000000000000000..957815382d5d4b62f8282394c61741f5fa78b6b5
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/potme_title.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/pronasledovani_startbutton.png b/core/assets/cs/screen/gamemenu/gfx/pronasledovani_startbutton.png
new file mode 100644
index 0000000000000000000000000000000000000000..cffd017412f8f4513d71ad3791c26f38442433e0
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/pronasledovani_startbutton.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/pronasledovani_startbutton_pressed.png b/core/assets/cs/screen/gamemenu/gfx/pronasledovani_startbutton_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..99dac76a1e4fa62dbee56287304f9eed593e1f31
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/pronasledovani_startbutton_pressed.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/pronasledovani_title.png b/core/assets/cs/screen/gamemenu/gfx/pronasledovani_title.png
new file mode 100644
index 0000000000000000000000000000000000000000..d5b2ad79503ab1f921df78fdba5741cd051f0d69
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/pronasledovani_title.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/strelnice_startbutton.png b/core/assets/cs/screen/gamemenu/gfx/strelnice_startbutton.png
new file mode 100644
index 0000000000000000000000000000000000000000..e484ec595785f360b844146b8c3f20b0ff450d38
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/strelnice_startbutton.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/strelnice_startbutton_pressed.png b/core/assets/cs/screen/gamemenu/gfx/strelnice_startbutton_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..8c5143946d6aa7eee7f430ce2c29fe69cceaf65c
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/strelnice_startbutton_pressed.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/strelnice_title.png b/core/assets/cs/screen/gamemenu/gfx/strelnice_title.png
new file mode 100644
index 0000000000000000000000000000000000000000..897f09d5fd118c5502442192226b625ab4419482
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/strelnice_title.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/unos_startbutton.png b/core/assets/cs/screen/gamemenu/gfx/unos_startbutton.png
new file mode 100644
index 0000000000000000000000000000000000000000..a3c0e9180f504c65727ac65a72c12b29b61ebafc
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/unos_startbutton.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/unos_startbutton_pressed.png b/core/assets/cs/screen/gamemenu/gfx/unos_startbutton_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..4a114cd8dd894292d2178c3da35ebfd63c8ff42b
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/unos_startbutton_pressed.png differ
diff --git a/core/assets/cs/screen/gamemenu/gfx/unos_title.png b/core/assets/cs/screen/gamemenu/gfx/unos_title.png
new file mode 100644
index 0000000000000000000000000000000000000000..e80abea04b7022c0d4f20be8c5b8499a8dbd0eb0
Binary files /dev/null and b/core/assets/cs/screen/gamemenu/gfx/unos_title.png differ
diff --git a/core/assets/sk/screen/gamemenu/screen_gamemenu_startmenu_background.jpg b/core/assets/sk/screen/gamemenu/gfx/screen_gamemenu_startmenu_background.jpg
similarity index 100%
rename from core/assets/sk/screen/gamemenu/screen_gamemenu_startmenu_background.jpg
rename to core/assets/sk/screen/gamemenu/gfx/screen_gamemenu_startmenu_background.jpg
diff --git a/core/src/cz/nic/tablexia/Tablexia.java b/core/src/cz/nic/tablexia/Tablexia.java
index b61c0088d31abc8f96dee06d3cdcb6ccf65a200b..f7bde234949749b1aeb2ea1388aeea77329439c5 100644
--- a/core/src/cz/nic/tablexia/Tablexia.java
+++ b/core/src/cz/nic/tablexia/Tablexia.java
@@ -1,8 +1,7 @@
 package cz.nic.tablexia;
 
+import com.badlogic.gdx.Application;
 import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.utils.reflect.ClassReflection;
-import com.badlogic.gdx.utils.reflect.ReflectionException;
 
 import net.engio.mbassy.listener.Handler;
 
@@ -16,42 +15,50 @@ import cz.nic.tablexia.loader.application.ApplicationSoundManager;
 import cz.nic.tablexia.loader.application.ApplicationTextManager;
 import cz.nic.tablexia.loader.application.ApplicationTextureManager;
 import cz.nic.tablexia.loader.zip.ZipAssetLoader;
-import cz.nic.tablexia.menu.MainMenu;
+import cz.nic.tablexia.menu.MainMenuContainer;
 import cz.nic.tablexia.screen.AbstractTablexiaScreen;
-import cz.nic.tablexia.screen.ScreenDefinition;
-import cz.nic.tablexia.screen.gamemenu.GameMenuScreen;
 import cz.nic.tablexia.screen.loader.LoaderScreen;
 import cz.nic.tablexia.util.Log;
+import cz.nic.tablexia.util.Utility;
 
 public class Tablexia extends TablexiaApplication {
 
-	private static final float      MAIN_MENU_WIDTH_RATIO   = 2f/7;
-	
-	private boolean					loadingComplete         = false;
-    private MainMenu                mainMenu;
-    private ZipAssetLoader          zipAssetLoader;
+    private boolean             loadingComplete = false;
+    private MainMenuContainer   mainMenuContainer;
+    private ZipAssetLoader      zipAssetLoader;
+    private boolean             resetState;
 
-    public Tablexia(boolean debug, Locale systemLocale, String versionName, String applicationId) {
-        TablexiaSettings.init(debug, systemLocale, versionName, applicationId);
+    public Tablexia(boolean debug, Locale systemLocale, String versionName, boolean resetState) {
+        TablexiaSettings.init(debug, systemLocale, versionName);
+        this.resetState = resetState;
     }
 
-    public Tablexia(String buildTypeKey, Locale systemLocale, String versionName, String applicationId) {
-        TablexiaSettings.init(buildTypeKey, systemLocale, versionName, applicationId);
+    public Tablexia(String buildTypeKey, Locale systemLocale, String versionName, boolean resetState) {
+        TablexiaSettings.init(buildTypeKey, systemLocale, versionName);
+        this.resetState = resetState;
+    }
+
+    private void loadingComplete() {
+        if (!loadingComplete) {
+            loadingComplete = true;
+            showLastOrInitialScreen();
+            ApplicationBus.getInstance().publishAsync(new ApplicationLoadingCompleteEvent());
+        }
+    }
+
+    private void showLastOrInitialScreen() {
+        AbstractTablexiaScreen<?> lastScreen = TablexiaSettings.getInstance().getCurrentScreen();
+        if (lastScreen != null) {
+            setScreenIfIsDifferent(lastScreen, ScreenTransaction.FADE);
+        } else {
+            setScreenIfIsDifferent(Utility.getScreenForScreenClass(TablexiaSettings.INITIAL_SCREEN), ScreenTransaction.MOVE_LEFT);
+        }
+    }
+
+    private void prepareMainMenu() {
+        mainMenuContainer = new MainMenuContainer(getStage().getWidth(), getStage().getHeight());
+        getStage().addActor(mainMenuContainer);
     }
-	
-	private void loadingComplete() {
-		if (!loadingComplete) {
-			loadingComplete = true;
-			setScreenIfIsDifferent(new GameMenuScreen(), ScreenTransaction.MOVE_LEFT);
-			ApplicationBus.getInstance().publishAsync(new ApplicationLoadingCompleteEvent());
-		}
-	}
-	
-	private void prepareMainMenu() {
-        mainMenu = new MainMenu(getStage().getWidth() * MAIN_MENU_WIDTH_RATIO, getStage().getHeight());
-		mainMenu.initMenuItems();
-		getStage().addActor(mainMenu);
-	}
 
     private void startLoading(Locale locale) {
         // sync loaded screen with loader image
@@ -72,9 +79,9 @@ public class Tablexia extends TablexiaApplication {
 
     private void clearLoadedData() {
         // clear main menu
-        if (mainMenu != null) {
-            mainMenu.remove();
-            mainMenu = null;
+        if (mainMenuContainer != null) {
+            mainMenuContainer.remove();
+            mainMenuContainer = null;
         }
 
         // dispose all loaders
@@ -99,101 +106,105 @@ public class Tablexia extends TablexiaApplication {
             }
         });
     }
-	
-	
+
+
 //////////////////////////// LIBGDX LIFECYCLE
-	
-	@Override
-	public void create () {
-		super.create();
 
-        TablexiaSettings.getInstance().loadPreferences();
+    @Override
+    public void create() {
+        super.create();
+
+        TablexiaSettings.getInstance().loadPreferences(resetState);
         Log.setLoglevel(TablexiaSettings.getInstance().getLogLevel());
 		
 		// init event bus handlers
 		ApplicationBus.getInstance().subscribe(this);
-		ScreenDefinition.initBus();
 
         // start loading application scope data
         startLoading(TablexiaSettings.getInstance().getLocale());
-	}
+    }
 
-	@Override
-	public void render () {
-		// render other screens
-		super.render();
-		
-		// process loading
-		if (!loadingComplete) {
+    @Override
+    public void pause() {
+        if (mainMenuContainer != null && getScreen() != null && getScreen().canBePaused()) {
+            // don't use menu open animation for android and iOS pause event (animation is run after resume)
+            mainMenuContainer.openMainMenu(Gdx.app.getType().equals(Application.ApplicationType.Desktop));
+        }
+        super.pause();
+    }
+
+    @Override
+    public void render() {
+        // render other screens
+        super.render();
+
+        // process loading
+        if (!loadingComplete) {
             // load internal assets
             if (!ApplicationFontManager.getInstance().update()) return;
             if (!ApplicationTextManager.getInstance().update()) return;
             // load external assets
             if (!zipAssetLoader.update()) return;
-			if (!ApplicationTextureManager.getInstance().update()) return;
+            if (!ApplicationTextureManager.getInstance().update()) return;
             if (!ApplicationSoundManager.getInstance().update()) return;
-			
-			prepareMainMenu();
-			loadingComplete();
-		}
-	}
-	
-	@Override
-	public void dispose() {
+
+            prepareMainMenu();
+            loadingComplete();
+        }
+    }
+
+    @Override
+    public void dispose() {
         super.dispose();
-		clearLoadedData();
-	}
-	
-	
+        clearLoadedData();
+    }
+
+
 //////////////////////////// APPLICATION LOADING COMPLETE EVENT
-	
-	public static class ApplicationLoadingCompleteEvent implements ApplicationEvent {}
-	
-	
+
+    public static class ApplicationLoadingCompleteEvent implements ApplicationEvent {
+    }
+
+
 //////////////////////////// CHANGE SCREEN EVENT
-	
-	public static class ChangeScreenEvent implements ApplicationEvent {
-		
-		private Class<? extends AbstractTablexiaScreen<?>> 	screen;
-		private ScreenTransaction 							screenTransaction;
 
-		public ChangeScreenEvent(Class<? extends AbstractTablexiaScreen<?>> screen, ScreenTransaction screenTransaction) {
-			this.screen = screen;
-			this.screenTransaction = screenTransaction;
-		}
-		
-		public Class<? extends AbstractTablexiaScreen<?>> getScreen() {
-			return screen;
-		}
-		
-		public ScreenTransaction getScreenTransaction() {
-			return screenTransaction;
-		}
-	}
-	
-	@Handler
-	public void handleChangeScreenEvent(final ChangeScreenEvent changeScreenEvent) {
-		final Class<? extends AbstractTablexiaScreen<?>> screenClass = changeScreenEvent.getScreen();
-		if (!loadingComplete) {
-			Log.err(getClass(), "Cannot change screen -> Application loading not complete!");
-			return;
-		}
-		if (screenClass == null) {
-			Log.err(getClass(), "Cannot change screen -> Received empty screen class!");
-			return;
-		}
-		// create new screen on GL thread
-		Gdx.app.postRunnable(new Runnable() {
-			
-			@Override
-			public void run() {
-				try {
-					AbstractTablexiaScreen<?> screen = (AbstractTablexiaScreen<?>) ClassReflection.getConstructors(screenClass)[0].newInstance(new Object[]{});
-					setScreenIfIsDifferent(screen, changeScreenEvent.getScreenTransaction());
-				} catch (ReflectionException e) {
-					Log.err(getClass(), "Cannot change screen! (Do you have only one parameter less constructor in screen?)", e);
-				}
-			}
-		});
-	}
+    public static class ChangeScreenEvent implements ApplicationEvent {
+
+        private Class<? extends AbstractTablexiaScreen<?>> screen;
+        private ScreenTransaction                          screenTransaction;
+
+        public ChangeScreenEvent(Class<? extends AbstractTablexiaScreen<?>> screen, ScreenTransaction screenTransaction) {
+            this.screen = screen;
+            this.screenTransaction = screenTransaction;
+        }
+
+        public Class<? extends AbstractTablexiaScreen<?>> getScreen() {
+            return screen;
+        }
+
+        public ScreenTransaction getScreenTransaction() {
+            return screenTransaction;
+        }
+    }
+
+    @Handler
+    public void handleChangeScreenEvent(final ChangeScreenEvent changeScreenEvent) {
+        final Class<? extends AbstractTablexiaScreen<?>> screenClass = changeScreenEvent.getScreen();
+        if (!loadingComplete) {
+            Log.err(((Object)this).getClass(), "Cannot change screen -> Application loading not complete!");
+            return;
+        }
+        if (screenClass == null) {
+            Log.err(((Object)this).getClass(), "Cannot change screen -> Received empty screen class!");
+            return;
+        }
+        // create new screen on GL thread
+        Gdx.app.postRunnable(new Runnable() {
+
+            @Override
+            public void run() {
+                setScreenIfIsDifferent(Utility.getScreenForScreenClass(screenClass), changeScreenEvent.getScreenTransaction());
+            }
+        });
+    }
 }
diff --git a/core/src/cz/nic/tablexia/TablexiaApplication.java b/core/src/cz/nic/tablexia/TablexiaApplication.java
index 272246154eee54b49e1ab0ddc469057379858d8a..f03c247fc1c3bebe01759e5a93f7343ff7f536cc 100644
--- a/core/src/cz/nic/tablexia/TablexiaApplication.java
+++ b/core/src/cz/nic/tablexia/TablexiaApplication.java
@@ -37,9 +37,9 @@ public abstract class TablexiaApplication implements ApplicationListener {
 
     private AbstractTablexiaScreen<?> lastScreen;
     private AbstractTablexiaScreen<?> screen;
-    private InputMultiplexer          inputMultiplexer;
-    private DebugInfo                 debugInfo;
-    private Stage                     stage;
+    private InputMultiplexer inputMultiplexer;
+    private DebugInfo debugInfo;
+    private Stage stage;
 
 
     public Stage getStage() {
@@ -80,7 +80,7 @@ public abstract class TablexiaApplication implements ApplicationListener {
 
     @Override
     public void create() {
-        stage = new Stage(new XFillViewport());
+        stage = new Stage();
         inputMultiplexer = new InputMultiplexer(stage);
         Gdx.input.setInputProcessor(inputMultiplexer);
         prepareDebugInfo();
@@ -108,6 +108,10 @@ public abstract class TablexiaApplication implements ApplicationListener {
         if (lastScreen != null) lastScreen.resize(width, height);
         if (screen != null) screen.resize(width, height);
         stage.getViewport().update(width, height, true);
+        // keep debug info on edges of the screen
+        if (TablexiaSettings.getInstance().isDebug()) {
+            debugInfo.onResize();
+        }
     }
 
 
@@ -115,7 +119,7 @@ public abstract class TablexiaApplication implements ApplicationListener {
 
     private void prepareDebugInfo() {
         if (TablexiaSettings.getInstance().isDebug()) {
-            debugInfo = new DebugInfo(getStage().getWidth(), getStage().getHeight());
+            debugInfo = new DebugInfo(); // TODO probably deprecated creating specific size
             getStage().addActor(debugInfo);
         }
     }
@@ -153,9 +157,10 @@ public abstract class TablexiaApplication implements ApplicationListener {
      * @param screen new screen to change for
      */
     public void setScreen(AbstractTablexiaScreen<?> screen) {
-        processLastScreen(this.screen);
+        lastScreen = this.screen;
         this.screen = screen;
-        processNewScreen(this.screen);
+        processLastScreen();
+        processNewScreen(screen);
     }
 
     /**
@@ -167,8 +172,10 @@ public abstract class TablexiaApplication implements ApplicationListener {
      * @param screenTransaction screen transaction type
      */
     public void setScreenIfIsDifferent(AbstractTablexiaScreen<?> newScreen, ScreenTransaction screenTransaction) {
-        if (getScreen() == null || getScreen().getClass() != newScreen.getClass()) {
-            setScreen(newScreen, screenTransaction);
+        if (newScreen != null) {
+            if (getScreen() == null || getScreen().getClass() != newScreen.getClass()) {
+                setScreen(newScreen, screenTransaction);
+            }
         }
     }
 
@@ -187,27 +194,27 @@ public abstract class TablexiaApplication implements ApplicationListener {
             screen = newScreen;
             screenTransaction.processTransaction(stage, lastScreen, newScreen,
 
-                new Runnable() {
+                    new Runnable() {
 
-                    @Override
-                    public void run() {
-                        processNewScreen(screen);
-                    }
-                },
+                        @Override
+                        public void run() {
+                            processNewScreen(screen);
+                        }
+                    },
 
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        processLastScreen(lastScreen);
-                    }
-                },
+                    new Runnable() {
+                        @Override
+                        public void run() {
+                            processLastScreen();
+                        }
+                    },
 
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        newScreen.performScreenVisible();
-                    }
-                });
+                    new Runnable() {
+                        @Override
+                        public void run() {
+                            newScreen.performScreenVisible();
+                        }
+                    });
         }
     }
 
@@ -223,6 +230,7 @@ public abstract class TablexiaApplication implements ApplicationListener {
     @SuppressWarnings("unchecked")
     private void processNewScreen(AbstractTablexiaScreen<?> newScreen) {
         if (newScreen != null) {
+            TablexiaSettings.getInstance().setCurrentScreen(newScreen);
             inputMultiplexer.addProcessor(newScreen.getInputProcessor());
             newScreen.show();
             newScreen.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
@@ -230,7 +238,7 @@ public abstract class TablexiaApplication implements ApplicationListener {
         }
     }
 
-    private void processLastScreen(AbstractTablexiaScreen<?> lastScreen) {
+    private void processLastScreen() {
         if (lastScreen != null) {
             inputMultiplexer.removeProcessor(lastScreen.getInputProcessor());
             lastScreen.hide();
@@ -267,8 +275,8 @@ public abstract class TablexiaApplication implements ApplicationListener {
     private static class MoveRightAnimation implements cz.nic.tablexia.TablexiaApplication.ScreenTransaction.ScreenTransactionImplementation {
 
         protected float newScreenMoveFrom = -Gdx.graphics.getWidth();
-        protected float newScreenMoveTo   = 0;
-        protected float lastScreenMoveTo  = Gdx.graphics.getWidth();
+        protected float newScreenMoveTo = 0;
+        protected float lastScreenMoveTo = Gdx.graphics.getWidth();
 
         @Override
         public void processTransaction(Stage stage, final AbstractTablexiaScreen<?> lastScreen, final AbstractTablexiaScreen<?> newScreen, Runnable newScreenHandler, final Runnable lastScreenHandler, final Runnable finishHandler) {
diff --git a/core/src/cz/nic/tablexia/TablexiaSettings.java b/core/src/cz/nic/tablexia/TablexiaSettings.java
index d0c83227bbc3d17be73b7aed3ca9ce3400ffe732..ca685d3b416c06282b338632061641650561e4b3 100644
--- a/core/src/cz/nic/tablexia/TablexiaSettings.java
+++ b/core/src/cz/nic/tablexia/TablexiaSettings.java
@@ -2,44 +2,55 @@ package cz.nic.tablexia;
 
 import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.Preferences;
+import com.badlogic.gdx.utils.reflect.ClassReflection;
+import com.badlogic.gdx.utils.reflect.ReflectionException;
 
 import java.util.Locale;
 
 import cz.nic.tablexia.bus.ApplicationBus;
 import cz.nic.tablexia.bus.event.LocaleChangedEvent;
+import cz.nic.tablexia.game.GameDefinition;
+import cz.nic.tablexia.game.difficulty.GameDifficulty;
 import cz.nic.tablexia.loader.application.ApplicationTextManager;
+import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+import cz.nic.tablexia.screen.gamemenu.GameMenuScreen;
 import cz.nic.tablexia.util.Log;
+import cz.nic.tablexia.util.Utility;
 
 public class TablexiaSettings {
 
-    private static final    int         DEFAULT_SCREEN_WIDTH        = 1000;
-    private static final    double      MAXIMUM_RATIO               = 9.0 / 16.0;
-    private static final    int         MIN_SCREEN_HEIGHT           = (int) (DEFAULT_SCREEN_WIDTH * MAXIMUM_RATIO);
-    private static final    boolean 	DEBUG_SHOW_BOUNDING_BOXES   = true;
-    public static final     String      LOCALE_KEY                  = "locale";
+    private static final int     DEFAULT_SCREEN_WIDTH      = 1000;
+    private static final double  MAXIMUM_RATIO             = 9.0 / 16.0;
+    private static final int     MIN_SCREEN_HEIGHT         = (int) (DEFAULT_SCREEN_WIDTH * MAXIMUM_RATIO);
+    private static final boolean DEBUG_SHOW_BOUNDING_BOXES = true;
 
-    private static final    String      IDE_BUILD_APPLICATION_ID    = "cz.nic.tablexia.debug";
-    private static final    String      IDE_BUILD_VERSION_NAME      = "IDE-BUILD";
+    public  static final Class<? extends AbstractTablexiaScreen<?>> INITIAL_SCREEN = GameMenuScreen.class;
 
-    private final           BuildType   BUILD_TYPE;
-    private final           String      VERSION_NAME;
-    private final           String      APPLICATION_ID;
+    private static final String PREFERENCES_KEY             = "cz.nic.tablexia.";
+    public static final String  LOCALE_KEY                  = "locale";
+    public static final String  CURRENT_SCREEN_KEY          = "current_screen";
 
-    private                 Preferences         preferences;
-    private                 LocaleDefinition    systemLocale;
-    private                 LocaleDefinition    selectedLocale;
+    private static final String IDE_BUILD_VERSION_NAME   = "DEVEL";
+
+    private final BuildType BUILD_TYPE;
+    private final String    VERSION_NAME;
+
+    private Preferences      preferences;
+    private LocaleDefinition systemLocale;
+    private LocaleDefinition selectedLocale;
 
 
     public static enum BuildType {
 
         RELEASE ("release", false,  Log.TablexiaLogLevel.ERROR),
-        DEBUG   ("debug",   true,   Log.TablexiaLogLevel.DEBUG);
+        DEBUG   ("debug",   true,   Log.TablexiaLogLevel.DEBUG),
+        DEVEL   ("devel",   true,   Log.TablexiaLogLevel.DEBUG);
 
-        private final static BuildType FALLBACK_VARIANT = BuildType.DEBUG;
+        private final static BuildType FALLBACK_VARIANT = BuildType.DEVEL;
 
         private final String                key;
         private final boolean               isDebug;
-        private Log.TablexiaLogLevel        logLevel;
+        private final Log.TablexiaLogLevel  logLevel;
 
         private BuildType(String key, boolean isDebug, Log.TablexiaLogLevel logLevel) {
             this.key = key;
@@ -47,6 +58,10 @@ public class TablexiaSettings {
             this.logLevel = logLevel;
         }
 
+        public String getKey() {
+            return key;
+        }
+
         public boolean isDebug() {
             return isDebug;
         }
@@ -56,7 +71,7 @@ public class TablexiaSettings {
         }
 
         public static BuildType getBuildTypeForKey(String key) {
-            for(BuildType buildType : BuildType.values()) {
+            for (BuildType buildType : BuildType.values()) {
                 if (buildType.key.equals(key)) {
                     return buildType;
                 }
@@ -67,12 +82,12 @@ public class TablexiaSettings {
 
     public enum LocaleDefinition {
 
-        SYSTEM  (null,                      "system",   ApplicationTextManager.LANGUAGE_SYSTEM),
-        cs_CZ   (new Locale("cs", "CZ"),    "cs_CZ",    ApplicationTextManager.LANGUAGE_CZECH),
-        sk_SK   (new Locale("sk", "SK"),    "sk_SK",    ApplicationTextManager.LANGUAGE_SLOVAK);
+        SYSTEM(null, "system", ApplicationTextManager.LANGUAGE_SYSTEM),
+        cs_CZ(new Locale("cs", "CZ"), "cs_CZ", ApplicationTextManager.LANGUAGE_CZECH),
+        sk_SK(new Locale("sk", "SK"), "sk_SK", ApplicationTextManager.LANGUAGE_SLOVAK);
 
-        public  final static LocaleDefinition   DEFAULT_LOCALE      = LocaleDefinition.cs_CZ;
-        private final static LocaleDefinition   FALLBACK_VARIANT    = LocaleDefinition.SYSTEM;
+        public final static  LocaleDefinition DEFAULT_LOCALE   = LocaleDefinition.cs_CZ;
+        private final static LocaleDefinition FALLBACK_VARIANT = LocaleDefinition.SYSTEM;
 
         private final Locale locale;
         private final String localeKey;
@@ -102,7 +117,7 @@ public class TablexiaSettings {
         }
 
         public static LocaleDefinition getLocaleDefinitionForKey(String key) {
-            for(LocaleDefinition localeDefinition: LocaleDefinition.values()) {
+            for (LocaleDefinition localeDefinition : LocaleDefinition.values()) {
                 if (localeDefinition.localeKey.equals(key)) {
                     return localeDefinition;
                 }
@@ -111,7 +126,7 @@ public class TablexiaSettings {
         }
 
         public static LocaleDefinition getLocaleDefinitionForLocale(Locale locale) {
-            for(LocaleDefinition localeDefinition: LocaleDefinition.values()) {
+            for (LocaleDefinition localeDefinition : LocaleDefinition.values()) {
                 if (localeDefinition.locale != null && localeDefinition.locale.equals(locale)) {
                     return localeDefinition;
                 }
@@ -125,11 +140,10 @@ public class TablexiaSettings {
 
     private static TablexiaSettings instance;
 
-    private TablexiaSettings(BuildType buildType, Locale systemLocale, String versionName, String applicationId) {
-        BUILD_TYPE          = buildType;
-        VERSION_NAME        = versionName == null ? IDE_BUILD_VERSION_NAME : versionName;
-        APPLICATION_ID      = applicationId == null ? IDE_BUILD_APPLICATION_ID : applicationId;
-        this.systemLocale   = LocaleDefinition.getLocaleDefinitionForLocale(systemLocale);
+    private TablexiaSettings(BuildType buildType, Locale systemLocale, String versionName) {
+        BUILD_TYPE = buildType;
+        VERSION_NAME = versionName == null ? IDE_BUILD_VERSION_NAME : versionName;
+        this.systemLocale = LocaleDefinition.getLocaleDefinitionForLocale(systemLocale);
     }
 
     public static TablexiaSettings getInstance() {
@@ -141,35 +155,39 @@ public class TablexiaSettings {
         return instance;
     }
 
-    public static void init(boolean debug, Locale systemLocale, String versionName, String applicationId) {
-        TablexiaSettings.init(debug ? BuildType.DEBUG : BuildType.RELEASE, systemLocale, versionName, applicationId);
+    public static void init(boolean debug, Locale systemLocale, String versionName) {
+        TablexiaSettings.init(debug ? BuildType.DEBUG : BuildType.RELEASE, systemLocale, versionName);
     }
 
-    public static void init(String buildTypeKey, Locale systemLocale, String versionName, String applicationId) {
-        TablexiaSettings.init(BuildType.getBuildTypeForKey(buildTypeKey), systemLocale, versionName, applicationId);
+    public static void init(String buildTypeKey, Locale systemLocale, String versionName) {
+        TablexiaSettings.init(BuildType.getBuildTypeForKey(buildTypeKey), systemLocale, versionName);
     }
 
-    public static void init(BuildType buildType, Locale systemLocale, String versionName, String applicationId) {
+    public static void init(BuildType buildType, Locale systemLocale, String versionName) {
         if (instance != null) {
             String exceptionMessage = "Tablexia settings already initialized!";
             Log.err(TablexiaSettings.class, exceptionMessage);
             throw new IllegalStateException(exceptionMessage);
         }
 
-        instance = new TablexiaSettings(buildType, systemLocale, versionName, applicationId);
+        instance = new TablexiaSettings(buildType, systemLocale, versionName);
     }
 
 
 //////////////////////////// LIBGDX PREFERENCES
 
-    public void loadPreferences() {
-        preferences     = Gdx.app.getPreferences(getApplicationId());
-        selectedLocale  = LocaleDefinition.getLocaleDefinitionForKey(preferences.getString(LOCALE_KEY));
+    public void loadPreferences(boolean resetState) {
+        preferences = Gdx.app.getPreferences(PREFERENCES_KEY + BUILD_TYPE.getKey());
+        selectedLocale = LocaleDefinition.getLocaleDefinitionForKey(preferences.getString(LOCALE_KEY));
+        if (resetState) {
+            preferences.remove(CURRENT_SCREEN_KEY);
+            preferences.flush();
+        }
     }
 
 
 //////////////////////////// SETTINGS ACCESS
-	
+
 	public boolean isDebug() {
 		return BUILD_TYPE.isDebug();
 	}
@@ -178,10 +196,6 @@ public class TablexiaSettings {
         return VERSION_NAME;
     }
 
-    public String getApplicationId() {
-        return APPLICATION_ID;
-    }
-
     public boolean isShowBoundingBoxes() {
         return isDebug() && DEBUG_SHOW_BOUNDING_BOXES;
     }
@@ -208,6 +222,38 @@ public class TablexiaSettings {
         return selectedLocale.getLocale();
     }
 
+    public void setCurrentScreen(AbstractTablexiaScreen screen) {
+        if (screen.hasState()) {
+            preferences.putString(CURRENT_SCREEN_KEY, screen.getClass().getName());
+            preferences.flush();
+        }
+    }
+
+    public AbstractTablexiaScreen<?> getCurrentScreen() {
+        String screenClassName = preferences.getString(CURRENT_SCREEN_KEY, null);
+        if (screenClassName != null) {
+            try {
+                return Utility.getScreenForScreenClass(ClassReflection.forName(screenClassName));
+            } catch (ReflectionException e) {
+                Log.err(getClass(), "Cannot load screen class: " + screenClassName, e);
+            }
+        }
+        return null;
+    }
+
+    public void setGameDifficulty(GameDefinition gameDefinition, GameDifficulty gameDifficulty) {
+        preferences.putString(getGameDifficultyPreferncesKey(gameDefinition), gameDifficulty.name());
+        preferences.flush();
+    }
+
+    public GameDifficulty getGameDifficulty(GameDefinition gameDefinition) {
+        return GameDifficulty.valueOf(GameDifficulty.class, preferences.getString(getGameDifficultyPreferncesKey(gameDefinition), GameDifficulty.DEFAULT_DIFFICULTY.name()));
+    }
+
+    private String getGameDifficultyPreferncesKey(GameDefinition gameDefinition) {
+        return "GAME_DIFFICULTY_" + gameDefinition.name();
+    }
+
 
 //////////////////////////// SCREEN SIZE
 
@@ -222,4 +268,4 @@ public class TablexiaSettings {
     public static int getMinScreenHeight() {
         return MIN_SCREEN_HEIGHT;
     }
-}
+}
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/bus/event/MainMenuPositionChangedEvent.java b/core/src/cz/nic/tablexia/bus/event/MainMenuPositionChangedEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2024d0713147f8ef770cf7c6d79095dbece5f94
--- /dev/null
+++ b/core/src/cz/nic/tablexia/bus/event/MainMenuPositionChangedEvent.java
@@ -0,0 +1,16 @@
+package cz.nic.tablexia.bus.event;
+
+import cz.nic.tablexia.bus.ApplicationBus;
+
+public class MainMenuPositionChangedEvent implements ApplicationBus.ApplicationEvent {
+
+    private boolean isMenuOpen;
+
+    public MainMenuPositionChangedEvent(boolean isMenuOpen) {
+        this.isMenuOpen = isMenuOpen;
+    }
+
+    public boolean isMenuOpen() {
+        return isMenuOpen;
+    }
+}
diff --git a/core/src/cz/nic/tablexia/debug/DebugInfo.java b/core/src/cz/nic/tablexia/debug/DebugInfo.java
index 7b3234ba0a8e185d9b1a9d1644e72ded7882dacd..462f5c979dd03434f396ff6deda876e7d45bf5e0 100644
--- a/core/src/cz/nic/tablexia/debug/DebugInfo.java
+++ b/core/src/cz/nic/tablexia/debug/DebugInfo.java
@@ -29,128 +29,132 @@ import static com.badlogic.gdx.scenes.scene2d.actions.Actions.alpha;
 
 /**
  * Debug info container
- * 
- * @author Matyáš Latner
  *
+ * @author Matyáš Latner
  */
 public class DebugInfo extends Table implements Disposable {
 
-	private static class DebugInfoComponent extends Table {
-		
-		private Map<String, Cell<Label>>	infoCellMap;
-		private LabelStyle 					labelStyle;
-
-		public DebugInfoComponent(float width, float height) {
-			infoCellMap = new HashMap<String, Cell<Label>>();
-			setBounds(0, 0, width, height);
-			setBackground(new TextureRegionDrawable(new TextureRegion(new ColorTexture(1, 1, BACKGROUND_COLOR))));
-			addAction(alpha(BACKGROUND_ALPHA));
-			
-			labelStyle = new LabelStyle(new BitmapFont(), FONT_COLOR);
-		}
-		
-		public synchronized void setInfoValue(String infoKey, String infoValue) {
-			Cell<Label> cell = infoCellMap.get(infoKey);
-			if (cell == null) {
-				createInfoCell(infoKey, infoValue);
-			} else {
-				cell.getActor().setText(infoKey + KEY_COLON + infoValue);
-			}
-		}
-		
-		private void clean() {
-			clearChildren();
-			infoCellMap.clear();
-		}
-		
-		private void createInfoCell(String infoKey, String infoValue) {
-			Cell<Label> cell = add(new Label(infoKey + KEY_COLON + infoValue, labelStyle));
-			infoCellMap.put(infoKey, cell);
-			if (getCells().size > 1) {
-				cell.pad(0, INFO_PADDING, 0, 0);
-			}
-		}
-		
-		@Override
-		public void setSize(float width, float height) {
-			super.setSize(width, height);
-		}
-		
-	}
-	
-	
-	private static final String NATIVE_HEAP 	= "Native Heap";
-	private static final String JAVA_HEAP 		= "Java Heap";
-	private static final String FPS 			= "FPS";
-    private static final String LOCALE 			= "Locale";
-    private static final String VERSION			= "Version";
-	
-	private static final String SCREEN_NAME 	= "Screen Name";
-	
-	private static final int 	INFO_PADDING	= 20;
-	private static final int 	MB_SIZE 		= 1000000;
-	private static final String UNIT_MB 		= " MB";
-	private static final String KEY_COLON 		= ": ";
-	
-	private static final Color FONT_COLOR 		= Color.WHITE;
-	private static final Color BACKGROUND_COLOR	= Color.BLACK;
-	private static final float BACKGROUND_ALPHA = 0.5f;
-	
-	private DebugInfoComponent applicationDebugInfo;
-	private DebugInfoComponent screenNameInfo;
-	private DebugInfoComponent screenDebugInfo;
-	
-	private ConcurrentLinkedQueue<ScreenInfoEvent> screenDebugInfoQueue = new ConcurrentLinkedQueue<ScreenInfoEvent>();
-	private ConcurrentLinkedQueue<ScreenChangedEvent> screenNameInfoQueue = new ConcurrentLinkedQueue<ScreenChangedEvent>();
-
-	public DebugInfo(float width, float height) {
-		setBounds(0, 0, width, height);
-		ApplicationBus.getInstance().subscribe(this);
-		
-		applicationDebugInfo = new DebugInfoComponent(width, height);
-		screenNameInfo = new DebugInfoComponent(width, height);
-		screenDebugInfo = new DebugInfoComponent(width, height);
-		
-		Table topTable = new Table();
-		topTable.add(screenNameInfo).expandX();
-		topTable.add(screenDebugInfo).pad(0, INFO_PADDING, 0, 0).expandX();
-		add(topTable);
-		row();
-		add(new Container<Actor>()).expand();
-		row();
-		add(applicationDebugInfo).expandX();
-	}
-	
-	public void update() {
+    private static class DebugInfoComponent extends Table {
+
+        private Map<String, Label> infoLabelMap;
+        private LabelStyle labelStyle;
+
+        public DebugInfoComponent() {
+            infoLabelMap = new HashMap<String, Label>();
+            setBackground(new TextureRegionDrawable(new TextureRegion(new ColorTexture(1, 1, BACKGROUND_COLOR))));
+            addAction(alpha(BACKGROUND_ALPHA));
+            labelStyle = new LabelStyle(new BitmapFont(), FONT_COLOR);
+        }
+
+        public synchronized void setInfoValue(String infoKey, String infoValue) {
+            Label label = infoLabelMap.get(infoKey);
+            if (label == null) {
+                createInfoLabel(infoKey, infoValue);
+            } else {
+                label.setText(infoKey + KEY_COLON + infoValue);
+            }
+        }
+
+        private void clean() {
+            clearChildren();
+            infoLabelMap.clear();
+        }
+
+        private void createInfoLabel(String infoKey, String infoValue) {
+            Label infoLabel = new Label(infoKey + KEY_COLON + infoValue, labelStyle);
+            infoLabelMap.put(infoKey, infoLabel);
+            clearChildren();
+
+            for (Label label : infoLabelMap.values()) {
+                Cell<Label> cell = add(label);
+                if (getCells().size > 1) {
+                    cell.pad(0, INFO_PADDING, 0, 0);
+                }
+            }
+        }
+
+        @Override
+        public void setSize(float width, float height) {
+            super.setSize(width, height);
+        }
+    }
+
+
+    private static final String NATIVE_HEAP = "Native Heap";
+    private static final String JAVA_HEAP = "Java Heap";
+    private static final String FPS = "FPS";
+    private static final String LOCALE = "Locale";
+    private static final String VERSION = "Version";
+
+    private static final String SCREEN_NAME = "Screen Name";
+
+    private static final int INFO_PADDING = 20;
+    private static final int MB_SIZE = 1000000;
+    private static final String UNIT_MB = " MB";
+    private static final String KEY_COLON = ": ";
+
+    private static final Color FONT_COLOR = Color.WHITE;
+    private static final Color BACKGROUND_COLOR = Color.BLACK;
+    private static final float BACKGROUND_ALPHA = 0.5f;
+
+    private DebugInfoComponent applicationDebugInfo;
+    private DebugInfoComponent screenNameInfo;
+    private DebugInfoComponent screenDebugInfo;
+
+    private ConcurrentLinkedQueue<ScreenInfoEvent> screenDebugInfoQueue = new ConcurrentLinkedQueue<ScreenInfoEvent>();
+    private ConcurrentLinkedQueue<ScreenChangedEvent> screenNameInfoQueue = new ConcurrentLinkedQueue<ScreenChangedEvent>();
+
+    public DebugInfo() {
+        ApplicationBus.getInstance().subscribe(this);
+
+        applicationDebugInfo = new DebugInfoComponent();
+        screenNameInfo = new DebugInfoComponent();
+        screenDebugInfo = new DebugInfoComponent();
+
+        Table topTable = new Table();
+        topTable.add(screenNameInfo).expandX();
+        topTable.add(screenDebugInfo).pad(0, INFO_PADDING, 0, 0).expandX();
+        add(topTable);
+        row();
+        add(new Container<Actor>()).expand();
+        row();
+        add(applicationDebugInfo).expandX();
+    }
+
+    public void update() {
         applicationDebugInfo.setInfoValue(FPS, "" + Gdx.graphics.getFramesPerSecond());
         applicationDebugInfo.setInfoValue(JAVA_HEAP, ("" + Gdx.app.getJavaHeap() / MB_SIZE) + UNIT_MB);
         applicationDebugInfo.setInfoValue(NATIVE_HEAP, ("" + Gdx.app.getNativeHeap() / MB_SIZE) + UNIT_MB);
         applicationDebugInfo.setInfoValue(LOCALE, "" + TablexiaSettings.getInstance().getLocale());
         applicationDebugInfo.setInfoValue(VERSION, "" + TablexiaSettings.getInstance().getVersionName());
 
-		while (!screenDebugInfoQueue.isEmpty()) {
-			ScreenInfoEvent screenInfoEvent = screenDebugInfoQueue.poll();
-			screenDebugInfo.setInfoValue(screenInfoEvent.getInfoKey(), screenInfoEvent.getInfoValue());
-		}
-		
-		while (!screenNameInfoQueue.isEmpty()) {
-			screenNameInfo.setInfoValue(SCREEN_NAME, "" + screenNameInfoQueue.poll().getScreenClass().getSimpleName());
-		}
-	}
-	
-	@Handler
-	public void handleScreenChangedEvent(ScreenChangedEvent screenChangedEvent) {
-		screenDebugInfo.clean();
-		screenNameInfoQueue.add(screenChangedEvent);
-	}
-	
-	@Handler
-	public void handleScreenInfoEvent(ScreenInfoEvent screenInfoEvent) {
-		screenDebugInfoQueue.add(screenInfoEvent);
-	}
-
-	@Override
-	public void dispose() {
-		ApplicationBus.getInstance().unsubscribe(this);
-	}
+        while (!screenDebugInfoQueue.isEmpty()) {
+            ScreenInfoEvent screenInfoEvent = screenDebugInfoQueue.poll();
+            screenDebugInfo.setInfoValue(screenInfoEvent.getInfoKey(), screenInfoEvent.getInfoValue());
+        }
+
+        while (!screenNameInfoQueue.isEmpty()) {
+            screenNameInfo.setInfoValue(SCREEN_NAME, "" + screenNameInfoQueue.poll().getScreenClass().getSimpleName());
+        }
+    }
+
+    public void onResize() {
+        setBounds(0,getStage().getCamera().position.y - getStage().getHeight() / 2,getStage().getWidth(), getStage().getHeight());
+    }
+
+    @Handler
+    public void handleScreenChangedEvent(ScreenChangedEvent screenChangedEvent) {
+        screenDebugInfo.clean();
+        screenNameInfoQueue.add(screenChangedEvent);
+    }
+
+    @Handler
+    public void handleScreenInfoEvent(ScreenInfoEvent screenInfoEvent) {
+        screenDebugInfoQueue.add(screenInfoEvent);
+    }
+
+    @Override
+    public void dispose() {
+        ApplicationBus.getInstance().unsubscribe(this);
+    }
 }
diff --git a/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java b/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java
new file mode 100644
index 0000000000000000000000000000000000000000..430e660102703449ec79cf2c0234ccb203db8a4c
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java
@@ -0,0 +1,264 @@
+package cz.nic.tablexia.game;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.math.Interpolation;
+import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.scenes.scene2d.Stage;
+import com.badlogic.gdx.scenes.scene2d.ui.Cell;
+import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+import com.badlogic.gdx.scenes.scene2d.ui.Stack;
+import com.badlogic.gdx.scenes.scene2d.ui.Table;
+
+import java.util.List;
+
+import cz.nic.tablexia.TablexiaSettings;
+import cz.nic.tablexia.game.common.RandomAccess;
+import cz.nic.tablexia.game.difficulty.GameDifficulty;
+import cz.nic.tablexia.graphics.ColorTexture;
+import cz.nic.tablexia.loader.application.ApplicationTextManager;
+import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+import cz.nic.tablexia.util.Log;
+import cz.nic.tablexia.util.ui.dialog.TwoButtonDialog;
+import cz.nic.tablexia.util.ui.dialog.text.DialogTextContent;
+
+import static com.badlogic.gdx.scenes.scene2d.actions.Actions.alpha;
+import static com.badlogic.gdx.scenes.scene2d.actions.Actions.delay;
+import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeIn;
+import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeOut;
+import static com.badlogic.gdx.scenes.scene2d.actions.Actions.run;
+import static com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence;
+
+public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T> {
+
+    public static final String RANDOM_SEED_SCREEN_INFO_LABEL        = "Random Seed";
+    public static final String GAME_DIFFICULTY_SCREEN_INFO_LABEL    = "Game Difficulty";
+    private static final int   SCREEN_TRANSACTION_FADE_DELAY	    = 1;
+
+    public static final String VICTORYSCREEN_RESULTSBANNER          = "application/victoryscreen/resultsbanner.png";
+    public static final String VICTORYSCREEN_RATINGSTAR_DISABLED    = "application/victoryscreen/ratingstar_disabled.png";
+    public static final String VICTORYSCREEN_RATINGSTAR_ENABLED     = "application/victoryscreen/ratingstar_enabled.png";
+
+    private RandomAccess    randomAccess;
+    private GameDifficulty  gameDifficulty;
+    private Actor           screenDimmer;
+
+    public AbstractTablexiaGame() {
+        final Texture texture = new ColorTexture(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), Color.BLACK);
+        screenDimmer = new Actor(){
+
+            public void draw(Batch batch, float parentAlpha) {
+                batch.setColor(getColor());
+                batch.draw(texture, 0, 0);
+                batch.setColor(Color.WHITE);
+            };
+        };
+        screenDimmer.addAction(alpha(0));
+        getStage().addActor(screenDimmer);
+    }
+
+
+//////////////////////////// SCREEN PAUSE
+
+    public boolean canBePaused() {
+        return true;
+    }
+
+
+//////////////////////////// ABSTRACT TABLEXIA SCREEN LIFECYCLE
+
+
+    @Override
+    protected final void prepareScreenTextureAssetNames(List<String> textureFileNames) {
+        textureFileNames.add(VICTORYSCREEN_RESULTSBANNER);
+        textureFileNames.add(VICTORYSCREEN_RATINGSTAR_DISABLED);
+        textureFileNames.add(VICTORYSCREEN_RATINGSTAR_ENABLED);
+        prepareGameTextureAssetNames(textureFileNames);
+    }
+
+    @Override
+    protected final T prepareScreenData() {
+        randomAccess = new RandomAccess();
+        printScreenInfo(RANDOM_SEED_SCREEN_INFO_LABEL, "" + getRandomAccess().getRandomSeed());
+
+        gameDifficulty = TablexiaSettings.getInstance().getGameDifficulty(GameDefinition.getGameDefinitionForClass((Class<? extends AbstractTablexiaGame<?>>)getClass()));
+        printScreenInfo(GAME_DIFFICULTY_SCREEN_INFO_LABEL, "" + gameDifficulty.name());
+
+        Log.info(getClass(), "Start game data loading with random seed: " + getRandomAccess().getRandomSeed() + " and difficulty: " + getGameDifficulty());
+
+        return prepareGameData();
+    }
+
+    @Override
+    protected final void screenLoaded() {
+        performShowTransaction(new Runnable() {
+            @Override
+            public void run() {
+                screenVisible();
+            }
+        });
+        gameLoaded();
+    }
+
+
+//////////////////////////// ABSTRACT TABLEXIA GAME LIFECYCLE
+
+    protected T prepareGameData() {
+        return null;
+    }
+
+    protected void prepareGameTextureAssetNames(List<String> textureFileNames) {}
+
+    protected void gameLoaded() {};
+
+
+//////////////////////////// ABSTRACT TABLEXIA GAME
+
+    private final float DIALOG_HEIGHT     = AbstractTablexiaGame.this.getStage().getHeight() * (3f/4);
+    private final float DIALOG_WIDTH      = DIALOG_HEIGHT * 1.2f;
+    private final float DIALOG_POSITION_X = (AbstractTablexiaGame.this.getStage().getWidth() / 2) - (DIALOG_WIDTH / 2);
+    private final float DIALOG_POSITION_Y = (AbstractTablexiaGame.this.getStage().getHeight() / 2) - (DIALOG_HEIGHT / 2);
+
+    private class VictoryDialog extends TwoButtonDialog {
+
+        public static final int   RATINGSTARS_COUNT = 3;
+        public static final float RATINGSTAR_DELAY  = 0.75f;
+
+        public static final float RESULTSBANNER_WIDTH_RATIO = 2f / 3;
+        public static final float RESULTSBANNER_TOPPADDING_RATIO = 1f / 30;
+        public static final float RATINGSTAR_HEIGHT_RATIO = 1f / 8;
+
+        Image[] ratingStarsEnabled;
+
+        public VictoryDialog() {
+            super(DIALOG_POSITION_X,
+                  DIALOG_POSITION_Y,
+                  DIALOG_WIDTH,
+                  DIALOG_HEIGHT,
+                  BackGroundType.DIALOG_SQUARE_BORDERLINES,
+                  new DialogTextContent("TEXT"),
+                  ButtonType.BLUE,
+                  ButtonType.GREEN,
+                  ApplicationTextManager.getInstance().getText(ApplicationTextManager.ApplicationTextsAssets.VICTORYSCREEN_BUTTON_CHANGEGAME),
+                  ApplicationTextManager.getInstance().getText(ApplicationTextManager.ApplicationTextsAssets.VICTORYSCREEN_BUTTON_REPLAY));
+        }
+
+        @Override
+        protected void prepareContent() {
+            // RESULTS BANNER
+            Image resultsBanner = new Image(getTexture(VICTORYSCREEN_RESULTSBANNER));
+            float resultBannerWidth = getWidth() * RESULTSBANNER_WIDTH_RATIO;
+            float resultsBannerSizeRatio = resultBannerWidth / resultsBanner.getWidth();
+            getContentTable().add(resultsBanner).width(resultBannerWidth).height(resultsBanner.getHeight() * resultsBannerSizeRatio).padTop(getHeight() * RESULTSBANNER_TOPPADDING_RATIO).center().colspan(3);
+
+            // RATING STARS
+            getContentTable().row();
+            Table ratingStarTable = new Table();
+            ratingStarsEnabled = new Image[RATINGSTARS_COUNT];
+            for (int i = 0; i < RATINGSTARS_COUNT; i++) {
+                createRatingStar(i, ratingStarTable);
+            }
+            getContentTable().add(ratingStarTable).center();
+
+            getContentTable().row();
+            getContentTable().add(new Actor()).expand();
+        }
+
+        private void createRatingStar(int starNumber, Table ratingStartTable) {
+            Stack ratingStack = new Stack();
+            Image ratingStarDisabled = new Image(getTexture(VICTORYSCREEN_RATINGSTAR_DISABLED));
+            Image ratingStarEnabled = new Image(getTexture(VICTORYSCREEN_RATINGSTAR_ENABLED));
+
+            ratingStarEnabled.setVisible(false);
+            ratingStarsEnabled[starNumber] = ratingStarEnabled;
+
+            ratingStack.add(ratingStarDisabled);
+            ratingStack.add(ratingStarEnabled);
+
+            float ratingStarHeight = getWidth() * RATINGSTAR_HEIGHT_RATIO;
+            float ratingStarSizeRatio = ratingStarHeight / ratingStarDisabled.getHeight();
+            Cell<Stack> cell = ratingStartTable.add(ratingStack);
+            cell.height(ratingStarHeight).width(ratingStarDisabled.getWidth() * ratingStarSizeRatio);
+        }
+
+        public Dialog show(int score, Stage stage) {
+            if (score < 0 || score > RATINGSTARS_COUNT) {
+                throw new IllegalArgumentException("Invalid score value: " + score);
+            }
+
+            super.show(stage);
+
+            for (int i = 0; i < score; i++) {
+                final Image ratingStarEnabled = ratingStarsEnabled[i];
+
+                addAction(sequence(delay((i + 1) * RATINGSTAR_DELAY), run(new Runnable() {
+                    @Override
+                    public void run() {
+                        ratingStarEnabled.setVisible(true);
+                    }
+                })));
+            }
+            return this;
+        }
+
+        @Override
+        protected void leftButtonAction() {
+        }
+
+        @Override
+        protected void rightButtonAction() {
+            startNewGame();
+        }
+    }
+
+    protected RandomAccess getRandomAccess() {
+        return randomAccess;
+    }
+
+    protected GameDifficulty getGameDifficulty() {
+        return gameDifficulty;
+    }
+
+    public void gameComplete(int score) {
+        (new VictoryDialog()).show(score, getStage());
+    }
+
+    private void startNewGame() {
+        performHideTransaction(new Runnable() {
+            @Override
+            public void run() {
+                startLoading();
+            }
+        });
+    }
+
+
+//////////////////////////// HIDE/SHOW TRANSACTIONS
+
+    protected void performHideTransaction(Runnable onHide) {
+        if (!screenDimmer.isVisible()) {
+            screenDimmer.addAction(alpha(0));
+            screenDimmer.setVisible(true);
+            screenDimmer.addAction(sequence(fadeIn(SCREEN_TRANSACTION_FADE_DELAY, Interpolation.pow4Out),
+                                            run(onHide)));
+        }
+    }
+
+    protected void performShowTransaction(Runnable onShow) {
+        if (screenDimmer.isVisible()) {
+            screenDimmer.addAction(sequence(
+                    fadeOut(SCREEN_TRANSACTION_FADE_DELAY, Interpolation.pow4In),
+                    run(new Runnable() {
+
+                        @Override
+                        public void run() {
+                            screenDimmer.setVisible(false);
+                        }
+                    }),
+                    run(onShow)));
+        }
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/GameDefinition.java b/core/src/cz/nic/tablexia/game/GameDefinition.java
index 1b28e2f8009f4bab570f7bc16f773203a2e06a47..e0252f01691abd3b292161e0639dd721830762c4 100644
--- a/core/src/cz/nic/tablexia/game/GameDefinition.java
+++ b/core/src/cz/nic/tablexia/game/GameDefinition.java
@@ -12,11 +12,10 @@ import cz.nic.tablexia.game.games.robbery.RobberyScreen;
 import cz.nic.tablexia.game.games.shooting_range.ShootingRangeScreen;
 import cz.nic.tablexia.loader.application.ApplicationTextManager;
 import cz.nic.tablexia.menu.IMenuItem;
-import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 
 
 public enum GameDefinition implements ApplicationEvent, IMenuItem {
-	
+
 	ROBBERY				("game_robbery_title",          RobberyScreen.class,        true),
     PURSUIT             ("game_pursuit_title",          PursuitScreen.class,        true),
     KIDNAPPING          ("game_kidnapping_title",       KidnappingScreen.class,     true),
@@ -26,29 +25,42 @@ public enum GameDefinition implements ApplicationEvent, IMenuItem {
 
 
 	private String 										menuTextKey;
-	private Class<? extends AbstractTablexiaScreen<?>> 	screenClass;
+	private Class<? extends AbstractTablexiaGame<?>> 	screenClass;
 	private boolean 									isCloseMenu;
 
-	private GameDefinition(String nameResource, Class<? extends AbstractTablexiaScreen<?>> screenClass, boolean isCloseMenu) {
+    public static GameDefinition[] getActiveGames(){
+        return new GameDefinition[]{ROBBERY, PURSUIT, KIDNAPPING, NIGHT_WATCH, SHOOTING_RANGE, IN_THE_DARKNESS};
+    }
+
+	private GameDefinition(String nameResource, Class<? extends AbstractTablexiaGame<?>> screenClass, boolean isCloseMenu) {
 		this.menuTextKey = nameResource;
 		this.screenClass = screenClass;
 		this.isCloseMenu = isCloseMenu;
 	}
-	
+
 	@Override
 	public String getTitle() {
 		return ApplicationTextManager.getInstance().getResult().get(menuTextKey);
 	}
-	
+
 	@Override
 	public void performAction() {
 		ApplicationBus.getInstance().publishAsync(this);
 		ApplicationBus.getInstance().publishAsync(new ChangeScreenEvent(screenClass, ScreenTransaction.FADE));
 	}
-	
+
 	@Override
 	public boolean isCloseMenu() {
 		return isCloseMenu;
 	}
 
+    public static GameDefinition getGameDefinitionForClass(Class<? extends AbstractTablexiaGame<?>> screenClass) {
+        for (GameDefinition gameDefinition : GameDefinition.values()) {
+            if (gameDefinition.screenClass.equals(screenClass)) {
+                return gameDefinition;
+            }
+        }
+        return null;
+    }
+
 }
diff --git a/core/src/cz/nic/tablexia/game/difficulty/GameDifficulty.java b/core/src/cz/nic/tablexia/game/difficulty/GameDifficulty.java
index 519a293597b4dba2a10470452701918cf32b9d5f..01df2f6e9e5eadb6cda421220610eff944e22230 100644
--- a/core/src/cz/nic/tablexia/game/difficulty/GameDifficulty.java
+++ b/core/src/cz/nic/tablexia/game/difficulty/GameDifficulty.java
@@ -19,6 +19,8 @@
 package cz.nic.tablexia.game.difficulty;
 
 
+import cz.nic.tablexia.loader.application.ApplicationTextManager;
+
 /**
  * Game difficulty types
  * 
@@ -26,33 +28,29 @@ package cz.nic.tablexia.game.difficulty;
  */
 public enum GameDifficulty {
 
-	// TODO use string resources
-    EASY(1),
-    MEDIUM(2),
-    HARD(3);
+    EASY    ("gamedifficulty_easy"),
+    MEDIUM  ("gamedifficulty_medium"),
+    HARD    ("gamedifficulty_hard");
+
+    public static final GameDifficulty DEFAULT_DIFFICULTY = EASY;
 
-    private int descriptionResourceId;
+    private String descriptionResourceKey;
 
-    private GameDifficulty(int descriptionResourceId) {
-        this.descriptionResourceId = descriptionResourceId;
+    private GameDifficulty(String descriptionResourceKey) {
+        this.descriptionResourceKey = descriptionResourceKey;
     }
 
-    /**
-     * Returns id of description for current difficulty
-     * 
-     * @return id of description string resource
-     */
-    public int getDescriptionResourceId() {
-        return descriptionResourceId;
+    public String getTextDescription() {
+        return ApplicationTextManager.getInstance().getText(getDescriptionResourceKey());
     }
 
     /**
-     * Returns string key for intent extra
+     * Returns key of description for current difficulty
      * 
-     * @return string key for intent extra
+     * @return key of description string resource
      */
-    public static String getIntentKey() {
-        return GameDifficulty.class.getName();
+    public String getDescriptionResourceKey() {
+        return descriptionResourceKey;
     }
 
     /**
diff --git a/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessScreen.java b/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessScreen.java
index 8d4697b26b49aee78368072aa71af96008695d39..52d9d630cce639a1ac48507f4f7bece73575846c 100644
--- a/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessScreen.java
+++ b/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessScreen.java
@@ -1,10 +1,10 @@
 package cz.nic.tablexia.game.games.in_the_darkness;
 
+import cz.nic.tablexia.game.AbstractTablexiaGame;
 import cz.nic.tablexia.game.games.robbery.rules.GameRule;
-import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 
 /**
  * Created by Václav Tarantík on 6.3.15.
  */
-public class InTheDarknessScreen extends AbstractTablexiaScreen<GameRule> {
+public class InTheDarknessScreen extends AbstractTablexiaGame<GameRule> {
 }
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingScreen.java b/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingScreen.java
index 6e54006a39c6f046fe23c17f8f75a804adba2603..b20d6f01b27f7d46171e7ac2f8194007d82924df 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingScreen.java
+++ b/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingScreen.java
@@ -1,10 +1,10 @@
 package cz.nic.tablexia.game.games.kidnapping;
 
+import cz.nic.tablexia.game.AbstractTablexiaGame;
 import cz.nic.tablexia.game.games.robbery.rules.GameRule;
-import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 
 /**
  * Created by Václav Tarantík on 6.3.15.
  */
-public class KidnappingScreen extends AbstractTablexiaScreen<GameRule> {
+public class KidnappingScreen extends AbstractTablexiaGame<GameRule> {
 }
diff --git a/core/src/cz/nic/tablexia/game/games/night_watch/NightWatchScreen.java b/core/src/cz/nic/tablexia/game/games/night_watch/NightWatchScreen.java
index 773fe5f650592cd958a17bd3f180838009ebebfb..bffc0392edb6816adfe36ea4cde0cc5d7951522e 100644
--- a/core/src/cz/nic/tablexia/game/games/night_watch/NightWatchScreen.java
+++ b/core/src/cz/nic/tablexia/game/games/night_watch/NightWatchScreen.java
@@ -1,10 +1,10 @@
 package cz.nic.tablexia.game.games.night_watch;
 
+import cz.nic.tablexia.game.AbstractTablexiaGame;
 import cz.nic.tablexia.game.games.robbery.rules.GameRule;
-import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 
 /**
  * Created by Václav Tarantík on 6.3.15.
  */
-public class NightWatchScreen extends AbstractTablexiaScreen<GameRule> {
+public class NightWatchScreen extends AbstractTablexiaGame<GameRule> {
 }
diff --git a/core/src/cz/nic/tablexia/game/games/pursuit/PursuitScreen.java b/core/src/cz/nic/tablexia/game/games/pursuit/PursuitScreen.java
index 6919c7ba57ce8c528bb0eab5ea0aef99f7b05436..43ccbf1e94d607de3210918f933f05f2c1b142b9 100644
--- a/core/src/cz/nic/tablexia/game/games/pursuit/PursuitScreen.java
+++ b/core/src/cz/nic/tablexia/game/games/pursuit/PursuitScreen.java
@@ -1,10 +1,10 @@
 package cz.nic.tablexia.game.games.pursuit;
 
+import cz.nic.tablexia.game.AbstractTablexiaGame;
 import cz.nic.tablexia.game.games.robbery.rules.GameRule;
-import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 
 /**
  * Created by Václav Tarantík on 6.3.15.
  */
-public class PursuitScreen extends AbstractTablexiaScreen<GameRule> {
+public class PursuitScreen extends AbstractTablexiaGame<GameRule> {
 }
diff --git a/core/src/cz/nic/tablexia/game/games/robbery/GameScreen.java b/core/src/cz/nic/tablexia/game/games/robbery/GameScreen.java
index 00ea3f8774baf169f0840461d378c4cbddc22830..19cab3e6fe52aa738d0f4a1911ae03a5ddb5689e 100644
--- a/core/src/cz/nic/tablexia/game/games/robbery/GameScreen.java
+++ b/core/src/cz/nic/tablexia/game/games/robbery/GameScreen.java
@@ -428,6 +428,8 @@ public class GameScreen extends AbstractTablexiaScreen<Void> {
 //                }
 //
 //            });
+        } else {
+            RobberyScreen.gameRobberyComplete();
         }
     }
 }
diff --git a/core/src/cz/nic/tablexia/game/games/robbery/RobberyScreen.java b/core/src/cz/nic/tablexia/game/games/robbery/RobberyScreen.java
index 68888e9e02fad46dd152b023040ddd1ca2c8f93e..590cc2ed7e5d72cbf2e593eeb96bae1fe0cc8aac 100644
--- a/core/src/cz/nic/tablexia/game/games/robbery/RobberyScreen.java
+++ b/core/src/cz/nic/tablexia/game/games/robbery/RobberyScreen.java
@@ -4,46 +4,28 @@ import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.InputMultiplexer;
 import com.badlogic.gdx.InputProcessor;
 import com.badlogic.gdx.audio.Sound;
-import com.badlogic.gdx.graphics.Color;
 import com.badlogic.gdx.graphics.Texture;
-import com.badlogic.gdx.graphics.g2d.Batch;
 import com.badlogic.gdx.graphics.g2d.BitmapFont;
-import com.badlogic.gdx.math.Interpolation;
-import com.badlogic.gdx.scenes.scene2d.Actor;
 
 import java.util.List;
 
-import cz.nic.tablexia.game.common.RandomAccess;
-import cz.nic.tablexia.game.difficulty.GameDifficulty;
+import cz.nic.tablexia.game.AbstractTablexiaGame;
 import cz.nic.tablexia.game.games.robbery.assets.RobberyAssets;
 import cz.nic.tablexia.game.games.robbery.creature.CreatureFactory;
 import cz.nic.tablexia.game.games.robbery.rules.GameRule;
 import cz.nic.tablexia.game.games.robbery.rules.GameRulesDefinition;
-import cz.nic.tablexia.graphics.ColorTexture;
 import cz.nic.tablexia.loader.application.ApplicationTextureManager;
 import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 
-import static com.badlogic.gdx.scenes.scene2d.actions.Actions.alpha;
-import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeIn;
-import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeOut;
-import static com.badlogic.gdx.scenes.scene2d.actions.Actions.run;
-import static com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence;
-
-public class RobberyScreen extends AbstractTablexiaScreen<GameRule> {
+public class RobberyScreen extends AbstractTablexiaGame<GameRule> {
 	
 	private static int			CREATURES_COUNT 				= 50;
 	private static int 			THIEVES_COUNT					= 8;
 	
-	private static final int 	SCREEN_TRANSACTION_FADE_DELAY	= 1;
-	
 	private static RobberyScreen instance			= null;
 	
-	private RandomAccess 							randomAccess 		= new RandomAccess();
-	private GameDifficulty 							gameDifficulty 		= GameDifficulty.EASY;
-	
 	private InputMultiplexer						inputMultiplexer;
 	private AbstractTablexiaScreen<Void> 			actualScreen;
-	private Actor 									screenDimmer;
 	
 	private boolean isRootScreenVisible;
 	private boolean isComponentScreenVisible;
@@ -52,7 +34,7 @@ public class RobberyScreen extends AbstractTablexiaScreen<GameRule> {
 //////////////////////////// SCREEN LOADERS
 	
 	@Override
-	protected void prepareScreenTextureAssetNames(List<String> textureFileNames) {
+	protected void prepareGameTextureAssetNames(List<String> textureFileNames) {
 		textureFileNames.add(ApplicationTextureManager.UniversalAssets.BACKGROUND_WOODEN);
 		
 		textureFileNames.add(RobberyAssets.SCREEN_RULEMESSAGE_PAPER_S1);
@@ -210,15 +192,13 @@ public class RobberyScreen extends AbstractTablexiaScreen<GameRule> {
 	protected String prepareScreenTextResourcesAssetName() {
 		return RobberyAssets.TEXT_PATH;
 	}
-	
+
 	@Override
-	protected GameRule prepareScreenData() {
-		GameRulesDefinition rule = GameRulesDefinition.getRandomGameRuleForDifficulty(gameDifficulty, randomAccess.getRandom());
-        GameRule gameRule = rule.getGameRuleInstance(randomAccess, CREATURES_COUNT, THIEVES_COUNT);
+	protected GameRule prepareGameData() {
+		GameRulesDefinition rule = GameRulesDefinition.getRandomGameRuleForDifficulty(getGameDifficulty(), getRandomAccess().getRandom());
+        GameRule gameRule = rule.getGameRuleInstance(getRandomAccess(), CREATURES_COUNT, THIEVES_COUNT);
         gameRule.generateCreatures();
-        
-        //TODO move to abstract game 
-        printScreenInfo("Random Seed", "" + gameRule.getRandomAccess().getRandomSeed());
+
         printScreenInfo("Game Rule", gameRule.getGameRuleDefinition().name());
         
 		return gameRule;
@@ -241,21 +221,11 @@ public class RobberyScreen extends AbstractTablexiaScreen<GameRule> {
 		isRootScreenVisible = false;
 		isComponentScreenVisible = false;
 		inputMultiplexer = new InputMultiplexer();
+        inputMultiplexer.addProcessor(getStage());
 	}
-	
+
 	@Override
-	protected void screenLoaded() {
-		final Texture texture = new ColorTexture(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), Color.BLACK);
-		screenDimmer = new Actor(){
-			
-			public void draw(Batch batch, float parentAlpha) {
-				batch.setColor(getColor());
-				batch.draw(texture, 0, 0);
-				batch.setColor(Color.WHITE);
-			};
-		};
-		screenDimmer.addAction(alpha(0));
-		getStage().addActor(screenDimmer);
+	protected void gameLoaded() {
 		showRuleScreen(false);
 	}
 	
@@ -291,24 +261,21 @@ public class RobberyScreen extends AbstractTablexiaScreen<GameRule> {
 	
 	private void showScreen(final AbstractTablexiaScreen<Void> newScreen, boolean transaction) {
 		isComponentScreenVisible = false;
-		if (transaction) {			
-			screenDimmer.addAction(sequence(fadeIn(SCREEN_TRANSACTION_FADE_DELAY, Interpolation.pow4Out),
-					run(new Runnable() {
-						
-						@Override
-						public void run() {
-							processNewScreen(newScreen);
-						}
-					}),
-					fadeOut(SCREEN_TRANSACTION_FADE_DELAY, Interpolation.pow4In),
-					run(new Runnable() {
-						
-						@Override
-						public void run() {
-							isComponentScreenVisible = true;
-							performComponentScreenVisible();
-						}
-					})));
+		if (transaction) {
+            performHideTransaction(new Runnable() {
+
+                @Override
+                public void run() {
+                    processNewScreen(newScreen);
+                    performShowTransaction(new Runnable() {
+                        @Override
+                        public void run() {
+                            isComponentScreenVisible = true;
+                            performComponentScreenVisible();
+                        }
+                    });
+                }
+            });
 		} else {
 			processNewScreen(newScreen);
 			isComponentScreenVisible = true;
@@ -413,4 +380,8 @@ public class RobberyScreen extends AbstractTablexiaScreen<GameRule> {
 	static void showRobberyGameScreen() {
 		instance.showGameScreen(true);
 	}
+
+    static void gameRobberyComplete() {
+        instance.gameComplete(2);
+    }
 }
diff --git a/core/src/cz/nic/tablexia/game/games/robbery/RuleScreen.java b/core/src/cz/nic/tablexia/game/games/robbery/RuleScreen.java
index ddc059408ef699d9a1ada07044a67773ec14d116..f549d476ce73e80d5a3e4adda59abbfde22287e7 100644
--- a/core/src/cz/nic/tablexia/game/games/robbery/RuleScreen.java
+++ b/core/src/cz/nic/tablexia/game/games/robbery/RuleScreen.java
@@ -100,6 +100,8 @@ public class RuleScreen extends AbstractTablexiaScreen<Void> {
 		getStage().addActor(label);
 		
 		loadingComplete = true;
+
+        screenResized((int)getStage().getWidth(), (int)getStage().getHeight());
 	}
 	
 	@Override
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeScreen.java b/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeScreen.java
index fbc4fad402c76057d616c502e424101f1186337e..21f844b62c13fd4d22aa628d7bd085496a03934b 100644
--- a/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeScreen.java
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeScreen.java
@@ -1,10 +1,10 @@
 package cz.nic.tablexia.game.games.shooting_range;
 
+import cz.nic.tablexia.game.AbstractTablexiaGame;
 import cz.nic.tablexia.game.games.robbery.rules.GameRule;
-import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 
 /**
  * Created by Václav Tarantík on 6.3.15.
  */
-public class ShootingRangeScreen extends AbstractTablexiaScreen<GameRule> {
+public class ShootingRangeScreen extends AbstractTablexiaGame<GameRule> {
 }
diff --git a/core/src/cz/nic/tablexia/loader/application/ApplicationFontManager.java b/core/src/cz/nic/tablexia/loader/application/ApplicationFontManager.java
index ed42a36021dca18e46811c4ffe6762185aa6ea47..3e072555f3302ade3b382bc351f1f09d2653c6af 100644
--- a/core/src/cz/nic/tablexia/loader/application/ApplicationFontManager.java
+++ b/core/src/cz/nic/tablexia/loader/application/ApplicationFontManager.java
@@ -68,4 +68,12 @@ public class ApplicationFontManager extends AssetManager implements IApplication
     public BitmapFont getFont(String fontName) {
         return get(fontName, BitmapFont.class);
     }
+
+    public BitmapFont getDefaultApplicationRegularFont() {
+        return getFont(APPLICATION_DEFAULT_FONT_REGULAR);
+    }
+
+    public BitmapFont getDefaultApplicationBoldFont() {
+        return getFont(APPLICATION_DEFAULT_FONT_BOLD);
+    }
 }
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/loader/application/ApplicationTextManager.java b/core/src/cz/nic/tablexia/loader/application/ApplicationTextManager.java
index 3f7cd2b2c8a087800c9f325ecc8a00e36b10c27a..493054d9c7216cb6ab4d804382ee145284fd089d 100644
--- a/core/src/cz/nic/tablexia/loader/application/ApplicationTextManager.java
+++ b/core/src/cz/nic/tablexia/loader/application/ApplicationTextManager.java
@@ -7,9 +7,8 @@ import com.badlogic.gdx.utils.async.AsyncTask;
 
 import java.util.Locale;
 
-import cz.nic.tablexia.TablexiaSettings;
-import cz.nic.tablexia.loader.TablexiaDataManager;
 import cz.nic.tablexia.loader.IApplicationLoader;
+import cz.nic.tablexia.loader.TablexiaDataManager;
 
 /**
  * Texture loader and manager for application context.
@@ -18,6 +17,11 @@ import cz.nic.tablexia.loader.IApplicationLoader;
  *
  */
 public class ApplicationTextManager extends TablexiaDataManager<I18NBundle> implements IApplicationLoader {
+
+    public static final class ApplicationTextsAssets {
+        public static final String VICTORYSCREEN_BUTTON_REPLAY      = "victoryscreen_button_replay";
+        public static final String VICTORYSCREEN_BUTTON_CHANGEGAME  = "victoryscreen_button_changegame";
+    }
 	
 	private static final String APPLICATION_TEXT_RESOURCE_FILE = "text/application/application";
 
diff --git a/core/src/cz/nic/tablexia/loader/application/ApplicationTextureManager.java b/core/src/cz/nic/tablexia/loader/application/ApplicationTextureManager.java
index c2e56a16ba8497d40e1906582de3c00e40cf27e1..4f30cf7e5ec65ae96af6395ed5f0b47d50958e0a 100644
--- a/core/src/cz/nic/tablexia/loader/application/ApplicationTextureManager.java
+++ b/core/src/cz/nic/tablexia/loader/application/ApplicationTextureManager.java
@@ -34,11 +34,7 @@ public class ApplicationTextureManager extends TablexiaTextureManager implements
 	private static final String MAINMENU_PATH 					= APPLICATION_PATH + "mainmenu/";
 	public 	static final String MAINMENU_BACKGROUND				= MAINMENU_PATH + "background.png";
 	
-	private static final String GAMEMENU_PATH 					= "screen/gamemenu/";
-	public 	static final String STARTMENU_BACKGROUND            = GAMEMENU_PATH + "screen_gamemenu_startmenu_background.jpg";
-
-    public void load() {
+	public void load() {
         loadTexture(MAINMENU_BACKGROUND);
-        loadTexture(STARTMENU_BACKGROUND);
     }
 }
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/menu/MainMenu.java b/core/src/cz/nic/tablexia/menu/MainMenu.java
index 72d7a11c529103626256bdbb3fab13f97cab6288..9bd2e24a680129d42d525feaa03763ec7536f9d9 100644
--- a/core/src/cz/nic/tablexia/menu/MainMenu.java
+++ b/core/src/cz/nic/tablexia/menu/MainMenu.java
@@ -3,10 +3,10 @@ package cz.nic.tablexia.menu;
 import com.badlogic.gdx.graphics.Color;
 import com.badlogic.gdx.graphics.Texture;
 import com.badlogic.gdx.graphics.Texture.TextureFilter;
-import com.badlogic.gdx.graphics.g2d.BitmapFont;
 import com.badlogic.gdx.graphics.g2d.TextureRegion;
 import com.badlogic.gdx.math.Interpolation;
 import com.badlogic.gdx.math.Interpolation.PowOut;
+import com.badlogic.gdx.scenes.scene2d.Action;
 import com.badlogic.gdx.scenes.scene2d.InputEvent;
 import com.badlogic.gdx.scenes.scene2d.actions.Actions;
 import com.badlogic.gdx.scenes.scene2d.ui.Button;
@@ -19,6 +19,8 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
 import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
 
 import cz.nic.tablexia.TablexiaSettings;
+import cz.nic.tablexia.bus.ApplicationBus;
+import cz.nic.tablexia.bus.event.MainMenuPositionChangedEvent;
 import cz.nic.tablexia.graphics.ColorTexture;
 import cz.nic.tablexia.loader.application.ApplicationFontManager;
 import cz.nic.tablexia.loader.application.ApplicationSoundManager;
@@ -26,138 +28,201 @@ import cz.nic.tablexia.loader.application.ApplicationTextureManager;
 
 /**
  * MainMenu container
- * 
- * @author Matyáš Latner
  *
+ * @author Matyáš Latner
  */
 public class MainMenu extends Stack {
-	
-	private static final float 	MENU_MOVE_DURATION 			= 1f;
-	private static final PowOut MENU_MOVE_INTERPOLATION 	= Interpolation.pow4Out;
-	private static final float 	MENU_CONTROLLER_SIZE_RATIO	= (1f/7);
-	private static final Color 	MENU_TEXT_COLOR 			= Color.BLACK;
-	private static final int 	OPEN_MENU_BUTTON_WIDTH 		= 55;
-	private static final int 	OPEN_MENU_BUTTON_HEIGHT 	= 75;
-	private static final int 	OPEN_MENU_BUTTON_TOP_OFFSET = 60;
-	
-	private Table 			menuTableLayout;
-	private TextButtonStyle menuButtonStyle;
-	private boolean 		isMenuOpen;
-	private Button 			openCloseButton;
-	private float 			menuClosePositionX;
-	private int             menuOpenPositionX;
-	private int             menuPositionY;
-
-	public MainMenu(float width, float height) {
-		setBounds(0, 0, width, height);
-		setDebug(TablexiaSettings.getInstance().isShowBoundingBoxes());
-		Texture background = ApplicationTextureManager.getInstance().getTexture(ApplicationTextureManager.MAINMENU_BACKGROUND);
-		background.setFilter(TextureFilter.Linear, TextureFilter.Linear);
-		
-		// menu layout
-		menuTableLayout = new Table();
-		menuTableLayout.setFillParent(true);
-		menuTableLayout.setBackground(new TextureRegionDrawable(new TextureRegion(background)));
-		addActor(menuTableLayout);
-		
-		// menu button style
-		menuButtonStyle = new TextButtonStyle();
-		menuButtonStyle.font = ApplicationFontManager.getInstance().getFont(ApplicationFontManager.FONT_ROBOTO_REGULAR);
-		menuButtonStyle.fontColor = MENU_TEXT_COLOR;
-		menuButtonStyle.up = new TextureRegionDrawable(new TextureRegion(new ColorTexture(50, 50, Color.BLUE)));
-		
-		// open close button
-		openCloseButton = new Button(new TextureRegionDrawable(new TextureRegion(new ColorTexture(OPEN_MENU_BUTTON_WIDTH, OPEN_MENU_BUTTON_HEIGHT, Color.RED))));
-		openCloseButton.addAction(Actions.alpha(0));
-		openCloseButton.align(Align.topRight);
-		openCloseButton.addListener(new ClickListener() {
-			
-			@Override
-			public void clicked(InputEvent event, float x, float y) {
-				toggleMenu();
-			}	
-		});
-		Table openCloseButtonContainer = new Table();
-		openCloseButtonContainer.add(openCloseButton).expandX().padTop(OPEN_MENU_BUTTON_TOP_OFFSET).right();
-		openCloseButtonContainer.row();
-		openCloseButtonContainer.add().expandY();
-		addActor(openCloseButtonContainer);
-		
-		prepareMenuPositions();
-		closeMenu(false);
-	}
-	
-	
+
+    private static final float      MENU_MOVE_DURATION = 1f;
+    private static final PowOut     MENU_MOVE_INTERPOLATION = Interpolation.pow4Out;
+    private static final float      MENU_CONTROLLER_SIZE_RATIO = (1f / 7);
+    private static final Color      MENU_TEXT_COLOR = Color.BLACK;
+    private static final int        OPEN_MENU_BUTTON_WIDTH = 55;
+    private static final int        OPEN_MENU_BUTTON_HEIGHT = 75;
+    private static final int        OPEN_MENU_BUTTON_TOP_OFFSET = 60;
+
+    private Table               menuTableLayout;
+    private TextButtonStyle     menuButtonStyle;
+    private Button              openCloseButton;
+    private float               menuClosePositionX;
+    private int                 menuOpenPositionX;
+    private int                 menuPositionY;
+    private Action              moveAction;
+    private boolean             isMenuClose;
+    private boolean             isMenuOpen;
+    private boolean             isClosing;
+    private boolean             isOpening;
+
+    public MainMenu(float width, float height) {
+        setBounds(0, 0, width, height);
+        setDebug(TablexiaSettings.getInstance().isShowBoundingBoxes());
+        Texture background = ApplicationTextureManager.getInstance().getTexture(ApplicationTextureManager.MAINMENU_BACKGROUND);
+        background.setFilter(TextureFilter.Linear, TextureFilter.Linear);
+
+        isClosing = false;
+        isOpening = false;
+
+        // menu layout
+        menuTableLayout = new Table();
+        menuTableLayout.setFillParent(true);
+        menuTableLayout.setBackground(new TextureRegionDrawable(new TextureRegion(background)));
+        addActor(menuTableLayout);
+
+        // menu button style
+        menuButtonStyle = new TextButtonStyle();
+        menuButtonStyle.font = ApplicationFontManager.getInstance().getFont(ApplicationFontManager.FONT_ROBOTO_REGULAR);
+        menuButtonStyle.fontColor = MENU_TEXT_COLOR;
+        menuButtonStyle.up = new TextureRegionDrawable(new TextureRegion(new ColorTexture(50, 50, Color.BLUE)));
+
+        // open close button
+        openCloseButton = new Button(new TextureRegionDrawable(new TextureRegion(new ColorTexture(OPEN_MENU_BUTTON_WIDTH, OPEN_MENU_BUTTON_HEIGHT, Color.RED))));
+        openCloseButton.addAction(Actions.alpha(0));
+        openCloseButton.align(Align.topRight);
+        openCloseButton.addListener(new ClickListener() {
+
+            @Override
+            public void clicked(InputEvent event, float x, float y) {
+                toggleMenu();
+            }
+        });
+        Table openCloseButtonContainer = new Table();
+        openCloseButtonContainer.add(openCloseButton).expandX().padTop(OPEN_MENU_BUTTON_TOP_OFFSET).right();
+        openCloseButtonContainer.row();
+        openCloseButtonContainer.add().expandY();
+        addActor(openCloseButtonContainer);
+
+        prepareMenuPositions();
+        closeMenu(false);
+    }
+
+
 //////////////////////////// MENU ITEMS
-	
-	public void initMenuItems() {
-		menuTableLayout.reset();
-		menuTableLayout.setDebug(TablexiaSettings.getInstance().isShowBoundingBoxes());
-		
-		for (final MainMenuDefinition menuItem : MainMenuDefinition.values()) {
-			addMenuItem(menuItem);
-			IMenuItem[] subMenu = menuItem.getSubmenu();
-			if (subMenu != null) {
-				for (IMenuItem submenuItem : subMenu) {
-					addMenuItem(submenuItem);
-				}
-			}
-		}
-	}
-	
-	private void addMenuItem(final IMenuItem menuItem) {
-		TextButton subMenuButton = new TextButton(menuItem.getTitle(), menuButtonStyle);
-		subMenuButton.addListener(new ClickListener() {
-			
-			@Override
-			public void clicked(InputEvent event, float x, float y) {
-				menuItem.performAction();
-				if (menuItem.isCloseMenu()) {					
-					closeMenu(true);
-				}
-			}
-			
-		});
-		menuTableLayout.add(subMenuButton).expandX();
-		menuTableLayout.row();
-	}
-	
-	
+
+    public void initMenuItems() {
+        menuTableLayout.reset();
+        menuTableLayout.setDebug(TablexiaSettings.getInstance().isShowBoundingBoxes());
+
+        for (final MainMenuDefinition menuItem : MainMenuDefinition.getItemsForMenu()) {
+            addMenuItem(menuItem);
+            IMenuItem[] subMenu = menuItem.getSubmenu();
+            if (subMenu != null) {
+                for (IMenuItem submenuItem : subMenu) {
+                    addMenuItem(submenuItem);
+                }
+            }
+        }
+    }
+
+    private void addMenuItem(final IMenuItem menuItem) {
+        TextButton subMenuButton = new TextButton(menuItem.getTitle(), menuButtonStyle);
+        subMenuButton.addListener(new ClickListener() {
+
+            @Override
+            public void clicked(InputEvent event, float x, float y) {
+                menuItem.performAction();
+                if (menuItem.isCloseMenu()) {
+                    closeMenu(true);
+                }
+            }
+
+        });
+        menuTableLayout.add(subMenuButton).expandX();
+        menuTableLayout.row();
+    }
+
+
 //////////////////////////// MENU MOVEMENT
-	
-	private void prepareMenuPositions() {
-		isMenuOpen = false;
-		menuClosePositionX = -(getWidth() - (getWidth() * MENU_CONTROLLER_SIZE_RATIO));
-		menuOpenPositionX = 0;
-		menuPositionY = 0;
-	}
-	
-	private void toggleMenu() {
-		if (isMenuOpen) {
-			closeMenu(true);
-		} else {
-			openMenu(true);
-		}
-	}
-	
-	private void closeMenu(boolean animated) {
-		isMenuOpen = false;
-		if (animated) {
-			addAction(Actions.moveTo(menuClosePositionX, menuPositionY, MENU_MOVE_DURATION, MENU_MOVE_INTERPOLATION));
-            ApplicationSoundManager.getInstance().getSound(ApplicationSoundManager.MAINMENU_CLOSE).play();
-		} else {
-			setPosition(menuClosePositionX, menuPositionY);
-		}
-	}
-	
-	private void openMenu(boolean animated) {
-		isMenuOpen = true;
-		if (animated) {
-			addAction(Actions.moveTo(menuOpenPositionX, menuPositionY, MENU_MOVE_DURATION, MENU_MOVE_INTERPOLATION));
-            ApplicationSoundManager.getInstance().getSound(ApplicationSoundManager.MAINMENU_OPEN).play();
-		} else {
-			setPosition(menuOpenPositionX, menuPositionY);
-		}
-	}
+
+    private void prepareMenuPositions() {
+        isMenuOpen = false;
+        isMenuClose = false;
+        isOpening = false;
+        isClosing = false;
+        menuClosePositionX = -(getWidth() - (getWidth() * MENU_CONTROLLER_SIZE_RATIO));
+        menuOpenPositionX = 0;
+        menuPositionY = 0;
+    }
+
+    private void toggleMenu() {
+        if (isOpening || isMenuOpen) {
+            closeMenu(true);
+        } else {
+            openMenu(true);
+        }
+    }
+
+    public void closeMenu(boolean animated) {
+        if (!isMenuClose && !isClosing) {
+            removeAction(moveAction);
+            isMenuOpen = false;
+            isOpening = false;
+            isClosing = true;
+            if (animated) {
+                moveAction = Actions.sequence(
+                        Actions.moveTo(menuClosePositionX, menuPositionY, MENU_MOVE_DURATION, MENU_MOVE_INTERPOLATION),
+                        Actions.run(new Runnable() {
+
+                            @Override
+                            public void run() {
+                                moveAction = null;
+                                isClosing = false;
+                                isMenuClose = true;
+                                sendMenuPositionChangedEvent();
+                            }
+                        }));
+                addAction(moveAction);
+                ApplicationSoundManager.getInstance().getSound(ApplicationSoundManager.MAINMENU_CLOSE).play();
+            } else {
+                moveAction = null;
+                isClosing = false;
+                isMenuClose = true;
+                setPosition(menuClosePositionX, menuPositionY);
+                sendMenuPositionChangedEvent();
+            }
+        }
+    }
+
+    public void openMenu(boolean animated) {
+        if (!isMenuOpen && !isOpening) {
+            removeAction(moveAction);
+            isMenuClose = false;
+            isClosing = false;
+            isOpening = true;
+            sendMenuPositionChangedEvent();
+            if (animated) {
+                moveAction = Actions.sequence(
+                        Actions.moveTo(menuOpenPositionX, menuPositionY, MENU_MOVE_DURATION, MENU_MOVE_INTERPOLATION),
+                        Actions.run(new Runnable() {
+
+                            @Override
+                            public void run() {
+                                moveAction = null;
+                                isMenuOpen = true;
+                                isOpening = false;
+                            }
+                        }));
+                addAction(moveAction);
+                ApplicationSoundManager.getInstance().getSound(ApplicationSoundManager.MAINMENU_OPEN).play();
+            } else {
+                moveAction = null;
+                isMenuOpen = true;
+                isOpening = false;
+                setPosition(menuOpenPositionX, menuPositionY);
+            }
+        }
+    }
+
+    //////////////////////////// POSITION CHANGED EVENT
+
+    private void sendMenuPositionChangedEvent() {
+        ApplicationBus.getInstance().post(new MainMenuPositionChangedEvent(!isMenuClose)).asynchronously();
+    }
+
+
+//////////////////////////// MENU MOVE PROGRESS
+
+    public float getMenuOpenPercentage() {
+        return 1 - Math.abs(getX() / menuClosePositionX);
+    }
 
 }
diff --git a/core/src/cz/nic/tablexia/menu/MainMenuContainer.java b/core/src/cz/nic/tablexia/menu/MainMenuContainer.java
new file mode 100644
index 0000000000000000000000000000000000000000..b2b6b0b3159f42ca09da57f6a95b70b0d8d452ba
--- /dev/null
+++ b/core/src/cz/nic/tablexia/menu/MainMenuContainer.java
@@ -0,0 +1,60 @@
+package cz.nic.tablexia.menu;
+
+import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.scenes.scene2d.Group;
+import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
+
+/**
+ * MainMenu container
+ *
+ * @author Matyáš Latner
+ */
+public class MainMenuContainer extends Group {
+
+    private static final float      MAIN_MENU_WIDTH_RATIO        = 2f/7;
+
+    private final MainMenu          mainMenu;
+    private final Group             screenDimmerLayer;
+    private final Actor             screenDimmer;
+
+    public MainMenuContainer(float width, float height) {
+        setBounds(0, 0, width, height);
+
+        screenDimmerLayer = new Group();
+        addActor(screenDimmerLayer);
+
+        mainMenu = new MainMenu(width * MAIN_MENU_WIDTH_RATIO, height);
+        mainMenu.initMenuItems();
+        addActor(mainMenu);
+
+        screenDimmer = new MainMenuDimmer(width, height);
+        screenDimmer.addListener(new ClickListener() {
+
+            @Override
+            public void clicked(InputEvent event, float x, float y) {
+                mainMenu.closeMenu(true);
+            }
+        });
+    }
+
+    @Override
+    public void draw(Batch batch, float parentAlpha) {
+        super.draw(batch, parentAlpha);
+        if (mainMenu.getMenuOpenPercentage() == 0) {
+            if (screenDimmer.getStage() != null) {
+                screenDimmer.remove();
+            }
+        } else {
+            if (screenDimmer.getStage() == null) {
+                screenDimmerLayer.addActor(screenDimmer);
+            }
+            screenDimmer.setColor(screenDimmer.getColor().r, screenDimmer.getColor().g, screenDimmer.getColor().b, mainMenu.getMenuOpenPercentage());
+        }
+    }
+
+    public void openMainMenu(boolean animated) {
+        mainMenu.openMenu(animated);
+    }
+}
diff --git a/core/src/cz/nic/tablexia/menu/MainMenuDefinition.java b/core/src/cz/nic/tablexia/menu/MainMenuDefinition.java
index 0f13e9123559e860005ab5aa38dec157fa44270d..c5dc2cd762935e724295b96b9590ced8dcfe65d4 100644
--- a/core/src/cz/nic/tablexia/menu/MainMenuDefinition.java
+++ b/core/src/cz/nic/tablexia/menu/MainMenuDefinition.java
@@ -1,47 +1,78 @@
 package cz.nic.tablexia.menu;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import cz.nic.tablexia.Tablexia;
+import cz.nic.tablexia.TablexiaApplication;
+import cz.nic.tablexia.TablexiaSettings;
 import cz.nic.tablexia.bus.ApplicationBus;
 import cz.nic.tablexia.bus.ApplicationBus.ApplicationEvent;
 import cz.nic.tablexia.game.GameDefinition;
 import cz.nic.tablexia.loader.application.ApplicationTextManager;
+import cz.nic.tablexia.screen.about.AboutScreen;
+import cz.nic.tablexia.screen.encyclopedia.EncyclopediaScreen;
+import cz.nic.tablexia.screen.halloffame.HallOfFameScreen;
+import cz.nic.tablexia.screen.preferences.PreferencesScreen;
+import cz.nic.tablexia.screen.statistics.StatisticsScreen;
+import cz.nic.tablexia.screen.viewport.ViewportDebugScreen;
+
 
+public enum MainMenuDefinition implements IMenuItem {
 
-public enum MainMenuDefinition implements ApplicationEvent, IMenuItem {
-	
-	GAMES				("mainmenu_games", 			GameDefinition.values(), false),
-	HALL_OF_FAME		("mainmenu_halloffame", 	null, true),
-	STATISTICS			("mainmenu_statistics", 	null, true),
-	ENCYCLOPEDIA		("mainmenu_encyclopedia", 	null, true),
-    PREFERENCES	        ("mainmenu_preferences",	null, true),
-	ABOUT_APPLICATION	("mainmenu_about", 			null, true),
-	LOGOUT				("mainmenu_logout", 		null, true);
+	GAMES				(false, "mainmenu_games", 			GameDefinition.values(), false, null), // TODO open menu event
+	HALL_OF_FAME		(false, "mainmenu_halloffame", 	    null, true, new Tablexia.ChangeScreenEvent(HallOfFameScreen.class, TablexiaApplication.ScreenTransaction.FADE)),
+	STATISTICS			(false, "mainmenu_statistics", 	    null, true, new Tablexia.ChangeScreenEvent(StatisticsScreen.class, TablexiaApplication.ScreenTransaction.FADE)),
+	ENCYCLOPEDIA		(false, "mainmenu_encyclopedia", 	null, true, new Tablexia.ChangeScreenEvent(EncyclopediaScreen.class, TablexiaApplication.ScreenTransaction.FADE)),
+    PREFERENCES	        (false, "mainmenu_preferences",	    null, true, new Tablexia.ChangeScreenEvent(PreferencesScreen.class, TablexiaApplication.ScreenTransaction.FADE)),
+	ABOUT_APPLICATION	(false, "mainmenu_about", 			null, true, new Tablexia.ChangeScreenEvent(AboutScreen.class, TablexiaApplication.ScreenTransaction.FADE)),
+	LOGOUT				(false, "mainmenu_logout", 		    null, true, null), // TODO specify event
+    SCREEN_DEBUG    	(true,  "mainmenu_screendebug",     null, true, new Tablexia.ChangeScreenEvent(ViewportDebugScreen.class, TablexiaApplication.ScreenTransaction.FADE));
 
-	private String menuTextKey;
+    private boolean debug;
+    private String menuTextKey;
 	private IMenuItem[] submenu;
 	private boolean isCloseMenu;
+	private ApplicationEvent action;
 
-	private MainMenuDefinition(String nameResource, IMenuItem[] submenu, boolean isCloseMenu) {
-		this.menuTextKey = nameResource;
+	private MainMenuDefinition(boolean debug, String nameResource, IMenuItem[] submenu, boolean isCloseMenu, ApplicationEvent action) {
+        this.debug = debug;
+        this.menuTextKey = nameResource;
 		this.submenu = submenu;
 		this.isCloseMenu = isCloseMenu;
+		this.action = action;
 	}
-	
+
+    public ApplicationEvent getAction() {
+		return action;
+	}
+
 	@Override
 	public String getTitle() {
 		return ApplicationTextManager.getInstance().getText(menuTextKey);
-	}	
-	
+	}
+
 	@Override
 	public void performAction() {
-		ApplicationBus.getInstance().publishAsync(this);
+		ApplicationBus.getInstance().publishAsync(this.getAction());
 	}
 
 	public IMenuItem[] getSubmenu() {
 		return submenu;
 	}
-	
+
 	@Override
 	public boolean isCloseMenu() {
 		return isCloseMenu;
 	}
+
+    public static List<MainMenuDefinition> getItemsForMenu() {
+        List<MainMenuDefinition> mainMenu = new ArrayList<MainMenuDefinition>();
+        for (MainMenuDefinition mainMenuDefinition : MainMenuDefinition.values()) {
+            if (TablexiaSettings.getInstance().isDebug() || !mainMenuDefinition.debug) {
+                mainMenu.add(mainMenuDefinition);
+            }
+        }
+        return mainMenu;
+    }
 }
diff --git a/core/src/cz/nic/tablexia/menu/MainMenuDimmer.java b/core/src/cz/nic/tablexia/menu/MainMenuDimmer.java
new file mode 100644
index 0000000000000000000000000000000000000000..4135e0a6b4deff42c656a83e6b632f479c85361e
--- /dev/null
+++ b/core/src/cz/nic/tablexia/menu/MainMenuDimmer.java
@@ -0,0 +1,36 @@
+package cz.nic.tablexia.menu;
+
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.scenes.scene2d.Actor;
+
+import cz.nic.tablexia.graphics.ColorTexture;
+
+/**
+ * MainMenu dimmer
+ *
+ * @author Matyáš Latner
+ */
+public class MainMenuDimmer extends Actor {
+
+    private static final float      MAIN_MENU_DIMMER_MAX_ALPHA   = 0.7f;
+    public static final Color       DIMMER_COLOR = Color.BLACK;
+
+    private final Texture           texture;
+
+    public MainMenuDimmer(float width, float height) {
+        setBounds(0, 0, width, height);
+        texture = new ColorTexture((int)width, (int)height, DIMMER_COLOR);
+    }
+
+    @Override
+    public void draw(Batch batch, float parentAlpha) {
+        Color color = getColor();
+        color.a = color.a * MAIN_MENU_DIMMER_MAX_ALPHA;
+
+        batch.setColor(getColor());
+        batch.draw(texture, 0, 0);
+        batch.setColor(Color.WHITE);
+    }
+}
diff --git a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
index 2d49389907b83bfcd2efce0f65a7d0feae9212b6..66131df18860ff40f227dd7ffceec1249a6d5168 100644
--- a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
+++ b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
@@ -12,6 +12,8 @@ import com.badlogic.gdx.scenes.scene2d.Stage;
 import com.badlogic.gdx.utils.I18NBundle;
 import com.badlogic.gdx.utils.async.AsyncTask;
 
+import net.engio.mbassy.listener.Handler;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -19,6 +21,7 @@ import java.util.Locale;
 import cz.nic.tablexia.TablexiaSettings;
 import cz.nic.tablexia.bus.ApplicationBus;
 import cz.nic.tablexia.bus.ApplicationBus.ApplicationEvent;
+import cz.nic.tablexia.bus.event.MainMenuPositionChangedEvent;
 import cz.nic.tablexia.loader.TablexiaAssetManager;
 import cz.nic.tablexia.loader.TablexiaDataManager;
 import cz.nic.tablexia.loader.TablexiaSoundManager;
@@ -37,9 +40,11 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
     private TextManager 			textManager;
     private DataManager 			dataManager;
     private ScreenLoadingListener 	screenLoadingListener;
-    private boolean					loadingComplete;
-    private boolean					loadingStarted;
+    private boolean                 loadingComplete;
+    private boolean                 loadingStarted;
     private boolean                 loadAsync;
+    private boolean                 paused;
+    private boolean                 hasState;
 
     private static class TextManager extends TablexiaDataManager<I18NBundle> {
 
@@ -107,21 +112,31 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
 
 
     public AbstractTablexiaScreen() {
-        this(true, TablexiaAssetManager.StorageType.EXTERNAL);
+        this(true, true, TablexiaAssetManager.StorageType.EXTERNAL);
     }
 	
-	public AbstractTablexiaScreen(boolean loadAsync, TablexiaAssetManager.StorageType storageType) {
-        stage = prepareStage();
-        this.loadAsync  = loadAsync;
-		textureManager 	= new TablexiaTextureManager(storageType);
-		soundManager 	= new TablexiaSoundManager(storageType);
-		textManager 	= new TextManager();
-		dataManager 	= new DataManager();
-		
+	public AbstractTablexiaScreen(boolean hasState, boolean loadAsync, TablexiaAssetManager.StorageType storageType) {
+        stage               = prepareStage();
+        this.hasState       = hasState;
+        this.loadAsync      = loadAsync;
+		textureManager 	    = new TablexiaTextureManager(storageType);
+		soundManager 	    = new TablexiaSoundManager(storageType);
+		textManager 	    = new TextManager();
+		dataManager 	    = new DataManager();
+
 		loadingComplete = false;
-		loadingStarted = false;
+        loadingStarted = false;
 	}
 
+    public boolean hasState() {
+        return hasState;
+    }
+
+//////////////////////////// SCREEN PAUSE
+
+    public boolean canBePaused() {
+        return false;
+    }
 
 //////////////////////////// LOADING LISTENER
 
@@ -143,7 +158,7 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
 //////////////////////////// STAGE
 
     private Stage prepareStage() {
-        return new Stage(new XFillViewport());
+		return new Stage(new XFillViewport());
     }
 
     public Stage getStage() {
@@ -166,20 +181,30 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
     }
 
 
+//////////////////////////// MAIN MENU POSITION CHANGE HANDLER
+
+    @Handler
+    public void handleMainMenuPositionChangedEvent(MainMenuPositionChangedEvent mainMenuPositionChangedEvent) {
+        paused = mainMenuPositionChangedEvent.isMenuOpen();
+    }
+
+
 //////////////////////////// LIBGDX LIFECYCLE
 	
 	@Override
 	public final void show() {
+        ApplicationBus.getInstance().subscribe(this);
 		if (!loadingComplete) {
-			startTextureLoader();
-			startSoundLoader();
-			startTextLoader();
-			startDataLoader();
-			loadingStarted = true;
+			startLoading();
 		}
 	}
-	
-	@Override
+
+    @Override
+    public final void hide() {
+        ApplicationBus.getInstance().unsubscribe(this);
+    }
+
+    @Override
 	public final void resize(int width, int height) {
 		stage.getViewport().update(width, height, true);
 		if (loadingComplete) {
@@ -189,8 +214,9 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
 
 	@Override
 	public final void render(float delta) {
-		if (!loadingComplete) {
-			if (loadingStarted) {
+        if (!loadingComplete) {
+            // SCREEN LOADING
+            if (loadingStarted) {
 
                 if (loadAsync) {
                     if (!textureManager.update()) return;
@@ -204,47 +230,50 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
                     dataManager.finishLoading();
                 }
 
-				loadingComplete = true;
-				performScreenLoaded();
-				performScreenResized((int)stage.getWidth(), (int)stage.getHeight());
-				notifyLoadingCompleteListeners();
-			}
+                loadingComplete = true;
+                loadingStarted = false;
+                performScreenLoaded();
+                notifyLoadingCompleteListeners();
+            }
 		} else {
-			screenRender(delta);
-			stage.act(delta);
+            // SCREEN RENDERING
+            screenRender(delta);
+            if (!paused) {
+                stage.act(delta);
+            }
 			stage.draw();
-		}
+        }
 	}
 	
 	@Override
 	public final void dispose() {
-		stage.dispose();
-		textureManager.dispose();
-		soundManager.dispose();
-		textManager.dispose();
-		dataManager.dispose();
-		performScreenDisposed();
-	}
+        stage.dispose();
+        textureManager.dispose();
+        soundManager.dispose();
+        textManager.dispose();
+        dataManager.dispose();
+        performScreenDisposed();
+    }
 	
 	
 //////////////////////////// TABLEXIA SCREEN LIFECYCLE
 	
-	private void performScreenLoaded() {
+	private final void performScreenLoaded() {
 		Log.info(getClass(), "[ ------- Screen Loaded ------- ]");
 		screenLoaded();
 	}
 	
-	public void performScreenVisible() {
+	public final void performScreenVisible() {
 		Log.info(getClass(), "[ ------- Screen Visible ------- ]");
 		screenVisible();
 	}
 	
-	private void performScreenResized(int width, int height) {
+	private final void performScreenResized(int width, int height) {
 		Log.info(getClass(), "[ ------- Screen Resized ------- ]");
 		screenResized(width, height);
 	}
 	
-	private void performScreenDisposed() {
+	private final void performScreenDisposed() {
 		Log.info(getClass(), "[ ------- Screen Disposed ------- ]");
 		screenDisposed();
 	}
@@ -270,6 +299,16 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
 
 
 //////////////////////////// LOADERS
+
+    protected void startLoading() {
+        loadingComplete = false;
+        loadingStarted  = true;
+
+        startTextureLoader();
+        startSoundLoader();
+        startTextLoader();
+        startDataLoader();
+    }
 	
 	private void startTextureLoader() {
         List<String> textureFileNames = new ArrayList<String>();
@@ -290,10 +329,11 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
 	private void startTextLoader() {
 		textManager.load(TablexiaSettings.getInstance().getLocale(), prepareScreenTextResourcesAssetName());
 	}
-	
-	private void startDataLoader() {
-		dataManager.load();
-	}
+
+    protected void startDataLoader() {
+        dataManager.load();
+    }
+
 	
 	public Texture getTexture(String textureName) {
 		return textureManager.getTexture(textureName);
@@ -308,11 +348,11 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
 	}
 
     public BitmapFont getDefaultRegularFont() {
-        return ApplicationFontManager.getInstance().getFont(ApplicationFontManager.APPLICATION_DEFAULT_FONT_REGULAR);
+        return ApplicationFontManager.getInstance().getDefaultApplicationRegularFont();
     }
 
     public BitmapFont getDefaultBoldFont() {
-        return ApplicationFontManager.getInstance().getFont(ApplicationFontManager.APPLICATION_DEFAULT_FONT_BOLD);
+        return ApplicationFontManager.getInstance().getDefaultApplicationBoldFont();
     }
 	
 	public String getFormattedText(String key, Object... args) {
diff --git a/core/src/cz/nic/tablexia/screen/ScreenDefinition.java b/core/src/cz/nic/tablexia/screen/ScreenDefinition.java
index aedb419736ec0613322a59910585e26e838adf20..ba280e041995f5fd3a6ce0c40f98f4ad8c53683c 100644
--- a/core/src/cz/nic/tablexia/screen/ScreenDefinition.java
+++ b/core/src/cz/nic/tablexia/screen/ScreenDefinition.java
@@ -1,6 +1,7 @@
 package cz.nic.tablexia.screen;
 
 import net.engio.mbassy.listener.Handler;
+
 import cz.nic.tablexia.Tablexia.ChangeScreenEvent;
 import cz.nic.tablexia.TablexiaApplication.ScreenTransaction;
 import cz.nic.tablexia.bus.ApplicationBus;
@@ -9,52 +10,57 @@ import cz.nic.tablexia.screen.about.AboutScreen;
 import cz.nic.tablexia.screen.encyclopedia.EncyclopediaScreen;
 import cz.nic.tablexia.screen.gamemenu.GameMenuScreen;
 import cz.nic.tablexia.screen.halloffame.HallOfFameScreen;
+import cz.nic.tablexia.screen.loader.LoaderScreen;
 import cz.nic.tablexia.screen.preferences.PreferencesScreen;
 import cz.nic.tablexia.screen.statistics.StatisticsScreen;
 
 public enum ScreenDefinition {
-	
-	GAME_MENU			(GameMenuScreen.class, 		null),
-	HALL_OF_FAME		(HallOfFameScreen.class,	MainMenuDefinition.HALL_OF_FAME),
-	STATISTICS			(StatisticsScreen.class,	MainMenuDefinition.STATISTICS),
-	ENCYCLOPEDIA		(EncyclopediaScreen.class, 	MainMenuDefinition.ENCYCLOPEDIA),
-    PREFERENCES	        (PreferencesScreen.class, 	MainMenuDefinition.PREFERENCES),
-	ABOUT_APPLICATION	(AboutScreen.class, 		MainMenuDefinition.ABOUT_APPLICATION);
-	
-	private Class<? extends AbstractTablexiaScreen<?>> 	screenClass;
-	private MainMenuDefinition 							mainMenuDefinition;
-	private static Object								messageHandler;
-
-	private ScreenDefinition(Class<? extends AbstractTablexiaScreen<?>> screenClass, MainMenuDefinition mainMenuDefinition) {
-		this.screenClass = screenClass;
-		this.mainMenuDefinition = mainMenuDefinition;
-	}
-	
-	public MainMenuDefinition getMainMenuDefinition() {
-		return mainMenuDefinition;
-	}
-
-	public void performMenuAction() {
-		ApplicationBus.getInstance().publishAsync(new ChangeScreenEvent(screenClass, ScreenTransaction.FADE));
-	}
-	
-	public static ScreenDefinition getScreenDefinitionForMainMenuDefinition(MainMenuDefinition mainMenuDefinition) {
-		for (ScreenDefinition screenDefinition : ScreenDefinition.values()) {					
-			if (screenDefinition.getMainMenuDefinition() == mainMenuDefinition) {
-				return screenDefinition;
-			}
-		}
-		return null;
-	}
-	
-	public static void initBus() {
-		messageHandler = new Object() {
-			 
-			@Handler
-			public void handleChangeScreenEvent(MainMenuDefinition mainMenuDefinition) {
-				ScreenDefinition.getScreenDefinitionForMainMenuDefinition(mainMenuDefinition).performMenuAction();
-			}
-		};
-		ApplicationBus.getInstance().subscribe(messageHandler);
-	}
+    LOADER(LoaderScreen.class, null),
+    GAME_MENU(GameMenuScreen.class, null),
+    HALL_OF_FAME(HallOfFameScreen.class, MainMenuDefinition.HALL_OF_FAME),
+    STATISTICS(StatisticsScreen.class, MainMenuDefinition.STATISTICS),
+    ENCYCLOPEDIA(EncyclopediaScreen.class, MainMenuDefinition.ENCYCLOPEDIA),
+    PREFERENCES(PreferencesScreen.class, MainMenuDefinition.PREFERENCES),
+    ABOUT_APPLICATION(AboutScreen.class, MainMenuDefinition.ABOUT_APPLICATION);
+
+    private        Class<? extends AbstractTablexiaScreen<?>> screenClass;
+    private        MainMenuDefinition                         mainMenuDefinition;
+    private static Object                                     messageHandler;
+
+    private ScreenDefinition(Class<? extends AbstractTablexiaScreen<?>> screenClass, MainMenuDefinition mainMenuDefinition) {
+        this.screenClass = screenClass;
+        this.mainMenuDefinition = mainMenuDefinition;
+    }
+
+    public MainMenuDefinition getMainMenuDefinition() {
+        return mainMenuDefinition;
+    }
+
+    public Class<? extends AbstractTablexiaScreen<?>> getScreenClass() {
+        return screenClass;
+    }
+
+    public void performMenuAction() {
+        ApplicationBus.getInstance().publishAsync(new ChangeScreenEvent(screenClass, ScreenTransaction.FADE));
+    }
+
+    public static ScreenDefinition getScreenDefinitionForMainMenuDefinition(MainMenuDefinition mainMenuDefinition) {
+        for (ScreenDefinition screenDefinition : ScreenDefinition.values()) {
+            if (screenDefinition.getMainMenuDefinition() == mainMenuDefinition) {
+                return screenDefinition;
+            }
+        }
+        return null;
+    }
+
+    public static void initBus() {
+        messageHandler = new Object() {
+
+            @Handler
+            public void handleChangeScreenEvent(MainMenuDefinition mainMenuDefinition) {
+                ScreenDefinition.getScreenDefinitionForMainMenuDefinition(mainMenuDefinition).performMenuAction();
+            }
+        };
+        ApplicationBus.getInstance().subscribe(messageHandler);
+    }
 }
diff --git a/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java b/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java
new file mode 100644
index 0000000000000000000000000000000000000000..3ee1a3225fa9c511176b74abe7007d474087bb86
--- /dev/null
+++ b/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java
@@ -0,0 +1,21 @@
+package cz.nic.tablexia.screen.createuser;
+
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.scenes.scene2d.ui.Label;
+import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
+import com.badlogic.gdx.scenes.scene2d.ui.Table;
+
+import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+
+public class FormScreen extends AbstractTablexiaScreen<Void> {
+
+    @Override
+    protected void screenLoaded() {
+        Label label = new Label(getClass().getSimpleName(), new LabelStyle(getDefaultRegularFont(), Color.WHITE));
+        Table table = new Table();
+        table.add(label);
+        label.setPosition(getStage().getWidth() / 2, getStage().getHeight() / 2);
+        getStage().addActor(label);
+    }
+
+}
diff --git a/core/src/cz/nic/tablexia/screen/createuser/PanoramaAssets.java b/core/src/cz/nic/tablexia/screen/createuser/PanoramaAssets.java
new file mode 100644
index 0000000000000000000000000000000000000000..f8bec1625adce2e0c7e8afd6c3a8bb90314ee579
--- /dev/null
+++ b/core/src/cz/nic/tablexia/screen/createuser/PanoramaAssets.java
@@ -0,0 +1,15 @@
+package cz.nic.tablexia.screen.createuser;
+
+import cz.nic.tablexia.util.assetmanager.DirectoryAsset;
+
+/**
+ * Created by lhoracek on 4/2/15.
+ */
+public class PanoramaAssets extends DirectoryAsset {
+    public static final String PATH = "screen/createuser/panorama";
+
+    @Override
+    public String getPath() {
+        return PATH;
+    }
+}
diff --git a/core/src/cz/nic/tablexia/screen/createuser/PanoramaScreen.java b/core/src/cz/nic/tablexia/screen/createuser/PanoramaScreen.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d6692c23866863841169a927a0fb50353a22ca3
--- /dev/null
+++ b/core/src/cz/nic/tablexia/screen/createuser/PanoramaScreen.java
@@ -0,0 +1,79 @@
+package cz.nic.tablexia.screen.createuser;
+
+import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.scenes.scene2d.Group;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+
+import java.util.List;
+
+import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+
+/**
+ * Screen showing street animation and office before user create form
+ */
+public class PanoramaScreen extends AbstractTablexiaScreen<Void> {
+    private PanoramaAssets assets = new PanoramaAssets();
+
+    private Actor balconyBlur, newspaper, newspaperOpen;
+
+    @Override
+    protected void prepareScreenTextureAssetNames(List<String> textureFileNames) {
+        super.prepareScreenTextureAssetNames(textureFileNames);
+        textureFileNames.addAll(assets.values());
+    }
+
+    @Override
+    protected void screenLoaded() {
+        switchScreen(prepareBalcony());
+    }
+
+    private void switchScreen(Actor actor) {
+        getStage().clear();
+        getStage().addActor(actor);
+    }
+
+    private Actor prepareBalcony() {
+        Group group = new Group();
+
+        boolean isWinter = true;
+
+        Image balcony = new Image(getTexture(assets.get("balcony" + (isWinter ? "_winter" : ""))));
+        setFullScreen(balcony);
+        group.addActor(balcony);
+
+        balconyBlur = new Image(getTexture(assets.get("balcony_blur" + (isWinter ? "_winter" : ""))));
+        setFullScreen(balconyBlur);
+        group.addActor(balconyBlur);
+
+        // TODO newspaper spin
+        // TODO newspaper detail
+
+        setFullScreen(group);
+        return group;
+    }
+
+    private Actor prepareSwipeStreet() {
+        Group group = new Group();
+        // TODO tiles in horizontal panel
+        // TODO active door
+
+        setFullScreen(group);
+        return group;
+    }
+
+    private Actor prepareOffice() {
+        Group group = new Group();
+
+        Image background = new Image(getTexture(assets.get("detectiveoffice")));
+        setFullScreen(background);
+        group.addActor(background);
+
+        setFullScreen(group);
+        return group;
+    }
+
+    private void setFullScreen(Actor actor) {
+        actor.setPosition(0, 0);
+        actor.setSize(getStage().getWidth(), getStage().getHeight());
+    }
+}
diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuAssets.java b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuAssets.java
new file mode 100644
index 0000000000000000000000000000000000000000..724ad0a8489dc7f1c80136e927eb04537932c8af
--- /dev/null
+++ b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuAssets.java
@@ -0,0 +1,87 @@
+package cz.nic.tablexia.screen.gamemenu;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import cz.nic.tablexia.game.GameDefinition;
+
+/**
+ * Created by lhoracek on 3/11/15.
+ */
+public final class GameMenuAssets {
+
+    private GameMenuAssets() {
+    }
+
+
+    public static enum GameMenuLayers {
+        FORE, MID, BACK, TITLE, STARTBUTTON, STARTBUTTON_PRESSED;
+    }
+
+    private static final String GAMEMENU_PATH = "screen/gamemenu/gfx/";
+
+    public static final String OFFICE               = GAMEMENU_PATH + "office.jpg";
+    public static final String OFFICE_CLICKMAP      = GAMEMENU_PATH + "clickablemap.png";
+    public static final String OFFICE_HELP          = GAMEMENU_PATH + "helplayer.png";
+    public static final String OVERLAY              = GAMEMENU_PATH + "overlay.png";
+    public static final String VIGNETTE             = GAMEMENU_PATH + "vignetting.png";
+    public static final String DESK                 = GAMEMENU_PATH + "desk.png";
+    public static final String ENCYCLOPEDIA_PRESSED = GAMEMENU_PATH + "encyclopedia_pressed.png";
+    public static final String HALLOFFAME_PRESSED   = GAMEMENU_PATH + "halloffame_pressed.png";
+    public static final String STATISTICS_PRESSED   = GAMEMENU_PATH + "statistics_pressed.png";
+    public static final String DOOR_PRESSED         = GAMEMENU_PATH + "streetdoor_pressed.png";
+    public static final String PROFILE_PRESSED      = GAMEMENU_PATH + "profile_pressed.png";
+
+    public static final String DIFF_BAR          = GAMEMENU_PATH + "difficultyseekbar_background.png";
+    public static final String DIFF_THUMB        = GAMEMENU_PATH + "difficultyseekbar_thumb.png";
+    public static final String DIFF_THUMB_EASY   = GAMEMENU_PATH + "difficultyseekbar_thumb_easy.png";
+    public static final String DIFF_THUMB_HARD   = GAMEMENU_PATH + "difficultyseekbar_thumb_hard.png";
+    public static final String DIFF_THUMB_MEDIUM = GAMEMENU_PATH + "difficultyseekbar_thumb_medium.png";
+
+    public static final String GAME_ROBBERY_BASE         = "bankovniloupez";
+    public static final String GAME_PURSUIT_BASE         = "pronasledovani";
+    public static final String GAME_KIDNAPPING_BASE      = "unos";
+    public static final String GAME_SHOOTING_RANGE_BASE  = "strelnice";
+    public static final String GAME_NIGHT_WATCH_BASE     = "nocnisledovani";
+    public static final String GAME_IN_THE_DARKNESS_BASE = "potme";
+
+    public static final String TEXT_PATH = "text/gamemenu";
+
+    public static List<String> textures = new ArrayList<String>();
+
+    static {
+        textures.add(OFFICE);
+        textures.add(OFFICE_CLICKMAP);
+        textures.add(DESK);
+        textures.add(OFFICE_HELP);
+        textures.add(VIGNETTE);
+        textures.add(OVERLAY);
+
+        textures.add(DIFF_BAR);
+        textures.add(DIFF_THUMB);
+        textures.add(DIFF_THUMB_EASY);
+        textures.add(DIFF_THUMB_HARD);
+        textures.add(DIFF_THUMB_MEDIUM);
+
+        textures.add(ENCYCLOPEDIA_PRESSED);
+        textures.add(HALLOFFAME_PRESSED);
+        textures.add(STATISTICS_PRESSED);
+        textures.add(DOOR_PRESSED);
+        textures.add(PROFILE_PRESSED);
+
+        String baseGameAsset = "MENU_GAME_";
+        for (GameDefinition gd : GameDefinition.getActiveGames()) {
+            for (GameMenuLayers gml : GameMenuLayers.values()) {
+                textures.add(getResourcePath(gd, gml));
+            }
+        }
+    }
+
+    public static String getResourcePath(GameDefinition game, GameMenuLayers layer) {
+        try {
+            return GAMEMENU_PATH + (GameMenuAssets.class.getField("GAME_" + game.name() + "_BASE").get(null)) + "_" + layer.name().toLowerCase() + ".png";
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Error generating path for " + game.name() + " " + layer.name());
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java
index 12f1f18c2b0e45d27e8c2d843925ff7fdeeea9ea..6edb7edaea7d2567b3d391e182b7728291c929ae 100644
--- a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java
+++ b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java
@@ -1,27 +1,61 @@
 package cz.nic.tablexia.screen.gamemenu;
 
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.scenes.scene2d.Touchable;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+
+import net.engio.mbassy.listener.Handler;
+
+import java.util.List;
+
+import cz.nic.tablexia.TablexiaSettings;
+import cz.nic.tablexia.bus.ApplicationBus;
+import cz.nic.tablexia.game.GameDefinition;
 import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+import cz.nic.tablexia.screen.gamemenu.pages.GameMenuPage;
 import cz.nic.tablexia.screen.gamemenu.pages.OfficeMenuPage;
-import cz.nic.tablexia.util.Log;
 import cz.nic.tablexia.util.ui.ViewPager;
 
 public class GameMenuScreen extends AbstractTablexiaScreen<Void> {
 
     private ViewPager vp;
 
+    @Override
+    protected void prepareScreenTextureAssetNames(List<String> textureFileNames) {
+        super.prepareScreenTextureAssetNames(textureFileNames);
+        textureFileNames.addAll(GameMenuAssets.textures);
+    }
+
     @Override
     protected void screenLoaded() {
+        getStage().setDebugAll(TablexiaSettings.getInstance().isShowBoundingBoxes());
         vp = new ViewPager();
+        vp.addPage(new OfficeMenuPage(this));
+
+        for (GameDefinition gd : GameDefinition.getActiveGames()) {
+            vp.addPage(new GameMenuPage(this, gd));
+        }
 
-        vp.addPage(new OfficeMenuPage());
-        vp.addPage(new OfficeMenuPage());
-        vp.addPage(new OfficeMenuPage());
-        vp.addPage(new OfficeMenuPage());
-        vp.addPage(new OfficeMenuPage());
         vp.setSize(getStage().getWidth(), getStage().getHeight());
+        getStage().addActor(vp);
 
-        Log.info(getClass().getName(), "ViewPager size: " + getStage().getWidth() + "x" + getStage().getHeight());
+        Image im = new Image(getTexture(GameMenuAssets.VIGNETTE));
+        im.setTouchable(Touchable.disabled);
+        im.setSize(getStage().getWidth(), getStage().getHeight());
+        getStage().addActor(im);
 
-        getStage().addActor(vp);
+        ApplicationBus.getInstance().subscribe(this);
+    }
+
+    @Handler
+    public void handleShowStreet(OfficeMenuPage.ShowStreetEvent message) {
+        vp.scrollToPage(1);
+    }
+
+    @Override
+    public Texture getTexture(String textureName) {
+        Texture texture = super.getTexture(textureName);
+        texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
+        return texture;
     }
 }
diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java b/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java
index 6230942ab146898cd580cf5709db0a08e396eee4..54666a561f8b45217070149d3eb2a0cd588efdd0 100644
--- a/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java
+++ b/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java
@@ -1,26 +1,308 @@
 package cz.nic.tablexia.screen.gamemenu.pages;
 
+import com.badlogic.gdx.graphics.Color;
 import com.badlogic.gdx.graphics.Texture;
 import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.graphics.g2d.BitmapFont;
+import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.InputListener;
+import com.badlogic.gdx.scenes.scene2d.actions.AlphaAction;
+import com.badlogic.gdx.scenes.scene2d.actions.MoveToAction;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+import com.badlogic.gdx.scenes.scene2d.ui.Label;
+import com.badlogic.gdx.scenes.scene2d.ui.Stack;
+import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
 
-import cz.nic.tablexia.loader.application.ApplicationTextureManager;
+import cz.nic.tablexia.TablexiaSettings;
+import cz.nic.tablexia.game.GameDefinition;
+import cz.nic.tablexia.game.difficulty.GameDifficulty;
+import cz.nic.tablexia.loader.application.ApplicationTextManager;
+import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+import cz.nic.tablexia.screen.gamemenu.GameMenuAssets;
+import cz.nic.tablexia.util.ui.ViewPager;
 
 /**
+ * Representing one page in ViewPager with specific game
  * Created by lhoracek on 3/4/15.
  */
-public class GameMenuPage extends MenuPage {
-    private Texture backgroundTexture;
+public class GameMenuPage extends MenuPage implements ViewPager.ScrollListener {
+    private GameDefinition game;
 
-    public GameMenuPage() {
-        //FIXME don't use ApplicationTextureManager
-        backgroundTexture = ApplicationTextureManager.getInstance().getTexture(ApplicationTextureManager.STARTMENU_BACKGROUND);
-        backgroundTexture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
+    private float diffEasyX, diffMediumX, diffHardX;
+    private Actor diffEasy, diffMedium, diffHard;
+    private Stack diffStack;
+    private GameDifficulty gameDifficulty = GameDifficulty.EASY;
+
+    private float scrollOffset = TablexiaSettings.getDefaultScreenWidth(); // hack to keep paralax layers out of picture before scrolled for first time
+
+    public GameMenuPage(AbstractTablexiaScreen screen, GameDefinition game) {
+        super(screen);
+        this.game = game;
+
+        // Title
+        Texture title = getScreen().getTexture(GameMenuAssets.getResourcePath(game, GameMenuAssets.GameMenuLayers.TITLE));
+        Image titleImage = new Image(title);
+        int titleX = (int) (screen.getStage().getWidth() * 0.2);
+        int titleWidth = (int) (screen.getStage().getWidth() * 0.6);
+        int titleHeight = (int) (titleWidth * ((float) title.getHeight() / (float) title.getWidth()));
+        int titleY = (int) (screen.getStage().getHeight() - (screen.getStage().getHeight() * 0.05) - titleHeight);
+        titleImage.setPosition(titleX, titleY);
+        titleImage.setSize(titleWidth, titleHeight);
+        addActor(titleImage);
+
+        // Start button
+        Texture start = getScreen().getTexture(GameMenuAssets.getResourcePath(game, GameMenuAssets.GameMenuLayers.STARTBUTTON));
+        final Image startButton = new Image(start);
+        int startY = (int) (screen.getStage().getWidth() * 0.1);
+        int startHeight = (int) (screen.getStage().getHeight() * 0.25);
+        int startWidth = (int) (startHeight * ((float) start.getWidth() / (float) start.getHeight()));
+        int startX = (int) screen.getStage().getWidth() / 2 - startWidth / 2;
+        startButton.setSize(startWidth, startHeight);
+        startButton.setPosition(startX, startY);
+
+        // Start button down
+        Texture startDown = getScreen().getTexture(GameMenuAssets.getResourcePath(game, GameMenuAssets.GameMenuLayers.STARTBUTTON_PRESSED));
+        final Image startDownButton = new Image(startDown);
+        int startDownY = (int) (screen.getStage().getWidth() * 0.1);
+        int startDownHeight = (int) (screen.getStage().getHeight() * 0.25);
+        int startDownWidth = (int) (startDownHeight * ((float) startDown.getWidth() / (float) startDown.getHeight()));
+        int startDownX = (int) screen.getStage().getWidth() / 2 - startDownWidth / 2;
+        startDownButton.setSize(startDownWidth, startDownHeight);
+        startDownButton.setPosition(startDownX, startDownY);
+        startDownButton.setVisible(false);
+
+        addActor(startDownButton);
+        addActor(startButton);
+        startButton.addListener(new ClickListener() {
+            @Override
+            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
+                startButton.addAction(new AlphaAction());
+                startDownButton.setVisible(true);
+                return super.touchDown(event, x, y, pointer, button);
+            }
+
+            @Override
+            public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
+                AlphaAction aa = new AlphaAction();
+                aa.setAlpha(1);
+                startButton.addAction(aa);
+                startDownButton.setVisible(false);
+                super.exit(event, x, y, pointer, toActor);
+            }
+
+            @Override
+            public void clicked(InputEvent event, float x, float y) {
+                super.clicked(event, x, y);
+                GameMenuPage.this.game.performAction(); // TODO launch game using events
+            }
+        });
+
+        final Texture diff = getScreen().getTexture(GameMenuAssets.DIFF_THUMB_EASY);
+        float diffY = screen.getStage().getHeight() * 0.06f;
+        float diffHeight = screen.getStage().getHeight() * 0.12f;
+        float diffWidth = diffHeight * ((float) diff.getWidth() / (float) diff.getHeight());
+
+        //TODO load initial difficulty from TablexiaSettings
+        // Difficulty bar
+        Texture diffBar = getScreen().getTexture(GameMenuAssets.DIFF_BAR);
+        Image diffBarImage = new Image(diffBar);
+
+        int diffBarHeight = (int) (screen.getStage().getHeight() * 0.04f);
+        int diffBarWidth = (int) (diffBarHeight * ((float) diffBar.getWidth() / (float) diffBar.getHeight()));
+        int diffBarX = (int) screen.getStage().getWidth() / 2 - diffBarWidth / 2;
+        int diffBarY = (int) (screen.getStage().getHeight() * 0.1);
+        diffBarImage.setPosition(diffBarX, diffBarY);
+        diffBarImage.setSize(diffBarWidth, diffBarHeight);
+        addActor(diffBarImage);
+
+        diffMediumX = (screen.getStage().getWidth() / 2) - (diffWidth / 2);
+        diffEasyX = diffMediumX - (diffBarWidth / 2) + (diffWidth * 0.1f);
+        diffHardX = diffMediumX + (diffBarWidth / 2) - (diffWidth * 0.1f);
+
+        // Labels for diffuculty slider
+        BitmapFont font = screen.getDefaultBoldFont();
+        font.setScale(0.5f);
+        Label.LabelStyle labelStyle = new Label.LabelStyle(font, Color.BLACK);
+
+        Label easy = new Label(GameDifficulty.EASY.getTextDescription(), labelStyle);
+        Label medium = new Label(GameDifficulty.MEDIUM.getTextDescription(), labelStyle);
+        Label hard = new Label(GameDifficulty.HARD.getTextDescription(), labelStyle);
+
+        float labelY = screen.getStage().getHeight() * 0.06f;
+        float labelAddX = diffWidth / 2;
+        easy.setPosition(diffEasyX + labelAddX - easy.getWidth() / 2, labelY);
+        medium.setPosition(diffMediumX + labelAddX - medium.getWidth() / 2, labelY);
+        hard.setPosition(diffHardX + labelAddX - hard.getWidth() / 2, labelY);
+
+        addActor(easy);
+        addActor(medium);
+        addActor(hard);
+
+        // Difficulty button
+        diffStack = new Stack();
+        diffStack.addActor(diffEasy = new Image(diff));
+        diffStack.addActor(diffMedium = new Image(getScreen().getTexture(GameMenuAssets.DIFF_THUMB_MEDIUM)));
+        diffStack.addActor(diffHard = new Image(getScreen().getTexture(GameMenuAssets.DIFF_THUMB_HARD)));
+
+        float diffX = diffEasyX;
+        diffStack.setSize(diffWidth, diffHeight);
+        diffStack.setPosition(diffX, diffY);
+        addActor(diffStack);
+        setDifficulty(gameDifficulty);
+
+        diffStack.addListener(new InputListener() {
+            float lastX;
+
+            @Override
+            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
+                super.touchDown(event, x, y, pointer, button);
+                lastX = x;
+                event.stop();
+                return true;
+            }
+
+            @Override
+            public void touchDragged(InputEvent event, float x, float y, int pointer) {
+                super.touchDragged(event, x, y, pointer);
+                float bx = diffStack.getX() + (x - lastX);
+                if (bx >= diffEasyX && bx <= diffHardX) {
+                    diffStack.setPosition(bx, diffStack.getY());
+                }
+                showDifficulty(getDifficulty());
+                event.stop();
+            }
+
+            @Override
+            public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
+                super.touchUp(event, x, y, pointer, button);
+                float bx = diffStack.getX() + (x - lastX);
+
+                GameDifficulty newDiff = getDifficulty();
+                setDifficulty(newDiff);
+                if (gameDifficulty != newDiff) {
+                    difficultyChanged(newDiff);
+                }
+                event.stop();
+            }
+        });
+    }
+
+    /**
+     * Change selector to custom difficulty
+     *
+     * @param difficulty
+     */
+    public void setDifficulty(GameDifficulty difficulty) {
+        showDifficulty(difficulty);
+        MoveToAction ma = new MoveToAction();
+        switch (difficulty) {
+            case EASY:
+                ma.setPosition(diffEasyX, diffStack.getY());
+                break;
+            case MEDIUM:
+                ma.setPosition(diffMediumX, diffStack.getY());
+                break;
+            case HARD:
+                ma.setPosition(diffHardX, diffStack.getY());
+                break;
+        }
+        diffStack.addAction(ma);
+        if (gameDifficulty != difficulty) {
+            difficultyChanged(difficulty);
+        }
+    }
+
+    /**
+     * Called when difficulty is changed
+     *
+     * @param difficulty
+     */
+    public void difficultyChanged(GameDifficulty difficulty) {
+        gameDifficulty = difficulty;
+        TablexiaSettings.getInstance().setGameDifficulty(game, difficulty);
+    }
+
+    /**
+     * Get nearest difficulty from current slider position
+     *
+     * @return
+     */
+    private GameDifficulty getDifficulty() {
+        float bx = diffStack.getX();
+        if (bx < diffMediumX) {
+            if ((diffEasyX + ((diffMediumX - diffEasyX) / 2)) > bx) {
+                return GameDifficulty.EASY;
+            } else {
+                return GameDifficulty.MEDIUM;
+            }
+        } else {
+            if ((diffMediumX + ((diffHardX - diffMediumX) / 2)) > bx) {
+                return GameDifficulty.MEDIUM;
+            } else {
+                return GameDifficulty.HARD;
+            }
+        }
+    }
+
+    /**
+     * Check difficulty image and display corresponding image
+     *
+     * @param diff
+     */
+    private void showDifficulty(GameDifficulty diff) {
+        diffEasy.setVisible(false);
+        diffMedium.setVisible(false);
+        diffHard.setVisible(false);
+
+        switch (diff) {
+            case EASY:
+                diffEasy.setVisible(true);
+                break;
+            case MEDIUM:
+                diffMedium.setVisible(true);
+                break;
+            case HARD:
+                diffHard.setVisible(true);
+                break;
+        }
     }
 
     @Override
     public void draw(Batch batch, float parentAlpha) {
-        batch.disableBlending();
-        batch.draw(backgroundTexture, 0, 0, getWidth(), getHeight());
-        batch.enableBlending();
+        // Paralax layers
+        // Back layer travels half the speed of scroll
+        // needed to make fade work
+        Color color = new Color(this.getColor().r, this.getColor().g, this.getColor().b, this.getColor().a * parentAlpha);
+        batch.setColor(color);
+
+        Texture back = getScreen().getTexture(GameMenuAssets.getResourcePath(game, GameMenuAssets.GameMenuLayers.BACK));
+        float scrollHalf = (Math.abs(scrollOffset / 2) / getWidth()) * back.getWidth();
+        int srcX = (int) scrollHalf;
+        int srcWidth = (int) (back.getWidth() - (scrollHalf * 2));
+        float x = getX() + Math.abs(Math.min(scrollOffset, 0));
+        float width = getWidth() - Math.abs(scrollOffset);
+        batch.draw(back, x, getY(), width, getHeight(), srcX, 0, srcWidth, back.getHeight(), false, false);
+
+        // Mid layer travels the same speed
+        batch.draw(getScreen().getTexture(GameMenuAssets.getResourcePath(game, GameMenuAssets.GameMenuLayers.MID)), getX(), getY(), getWidth(), getHeight());
+
+        // Foreground layer travels faster and could be wider than screen. Needs to be clipped
+        Texture fore = getScreen().getTexture(GameMenuAssets.getResourcePath(game, GameMenuAssets.GameMenuLayers.FORE));
+        float foreWidth = (getHeight() / fore.getHeight()) * fore.getWidth();
+        batch.draw(fore, getX() - ((foreWidth - getWidth()) / 2) + (scrollOffset / 2), getY(), foreWidth, getHeight());
+
+        super.draw(batch, parentAlpha);
+    }
+
+    @Override
+    public void onScroll(float offset) {
+        scrollOffset = offset;
+        //Log.info(((Object) this).getClass().getName(), "Scroll " + game.name() + ": " + offset);
+    }
+
+    @Override
+    public void onScrolledToPage() {
+        //Log.info(((Object) this).getClass().getName(), "Scrolled to page: " + game.name());
     }
 }
diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/pages/MenuPage.java b/core/src/cz/nic/tablexia/screen/gamemenu/pages/MenuPage.java
index 49d72f41b7fd0ecd1b9c390ccd0579a96dec6521..b00985334a213070b600ce10ac26199bf07632da 100644
--- a/core/src/cz/nic/tablexia/screen/gamemenu/pages/MenuPage.java
+++ b/core/src/cz/nic/tablexia/screen/gamemenu/pages/MenuPage.java
@@ -1,9 +1,29 @@
 package cz.nic.tablexia.screen.gamemenu.pages;
 
+import com.badlogic.gdx.scenes.scene2d.Actor;
 import com.badlogic.gdx.scenes.scene2d.Group;
 
+import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+
 /**
  * Created by lhoracek on 3/4/15.
  */
 public abstract class MenuPage extends Group {
+    private AbstractTablexiaScreen screen;
+
+    public MenuPage(AbstractTablexiaScreen screen) {
+        this.screen = screen;
+    }
+
+    protected AbstractTablexiaScreen getScreen() {
+        return screen;
+    }
+
+    @Override
+    public void setDebug(boolean enabled) {
+        super.setDebug(enabled);
+        for (Actor a : getChildren()) {
+            a.setDebug(enabled);
+        }
+    }
 }
diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java b/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java
index fe32b0c6a8651d8c0aaed0330e14613c0923fbb8..f8c52866a6435566056812848d03ca145dc59ece 100644
--- a/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java
+++ b/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java
@@ -1,27 +1,169 @@
 package cz.nic.tablexia.screen.gamemenu.pages;
 
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.Pixmap;
 import com.badlogic.gdx.graphics.Texture;
-import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.scenes.scene2d.Group;
+import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.InputListener;
+import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+import com.badlogic.gdx.scenes.scene2d.ui.Stack;
+import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
 
-import cz.nic.tablexia.loader.application.ApplicationTextureManager;
+import cz.nic.tablexia.Tablexia;
+import cz.nic.tablexia.TablexiaApplication;
+import cz.nic.tablexia.bus.ApplicationBus;
+import cz.nic.tablexia.menu.MainMenuDefinition;
+import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+import cz.nic.tablexia.screen.encyclopedia.EncyclopediaScreen;
+import cz.nic.tablexia.screen.gamemenu.GameMenuAssets;
+import cz.nic.tablexia.screen.halloffame.HallOfFameScreen;
+import cz.nic.tablexia.screen.profile.ProfileScreen;
+import cz.nic.tablexia.screen.statistics.StatisticsScreen;
+import cz.nic.tablexia.util.Log;
 
 /**
  * Created by lhoracek on 3/4/15.
  */
 public class OfficeMenuPage extends MenuPage {
-    private Texture backgroundTexture;
 
-    public OfficeMenuPage() {
-        //FIXME don't use ApplicationTextureManager
-        backgroundTexture = ApplicationTextureManager.getInstance().getTexture(ApplicationTextureManager.STARTMENU_BACKGROUND);
-        backgroundTexture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
+    public static final Color STREET_COLOR       = Color.YELLOW;
+    public static final Color HALLOFFAME_COLOR   = Color.GREEN;
+    public static final Color STATISTICS_COLOR   = Color.RED;
+    public static final Color ENCYCLOPEDIA_COLOR = Color.BLACK;
+    public static final Color PROFILE_COLOR      = Color.BLUE;
+
+    private Group help;
+
+    private Image hallOfFame;
+    private Image statistics;
+    private Image encyclopedia;
+    private Image street;
+    private Image profile;
+
+
+    public OfficeMenuPage(AbstractTablexiaScreen screen) {
+        super(screen);
+        createImageStack();
+
+        // TODO show help layer button
+
+        addListener(new InputListener() {
+            private Color downColor;
+
+            @Override
+            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
+                super.touchDown(event, x, y, pointer, button);
+                Color color = getTouchedColor(x, y);
+                downColor = color;
+                help.addAction(Actions.fadeOut(0.5f));
+                if (color.equals(ENCYCLOPEDIA_COLOR)) {
+                    encyclopedia.setVisible(true);
+                } else if (color.equals(STATISTICS_COLOR)) {
+                    statistics.setVisible(true);
+                } else if (color.equals(HALLOFFAME_COLOR)) {
+                    hallOfFame.setVisible(true);
+                } else if (color.equals(STREET_COLOR)) {
+                    street.setVisible(true);
+                } else if (color.equals(PROFILE_COLOR)) {
+                    profile.setVisible(true);
+                } else {
+                    return false;
+                }
+                return true;
+            }
+
+            @Override
+            public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
+                super.touchUp(event, x, y, pointer, button);
+                Log.info(((Object) this).getClass().getName(), "Touch up ");
+                hideAllActions();
+            }
+        });
+
+        addListener(new ClickListener() {
+            @Override
+            public void clicked(InputEvent event, float x, float y) {
+                super.clicked(event, x, y);
+                Color color = getTouchedColor(x, y);
+                if (color.equals(ENCYCLOPEDIA_COLOR)) {
+                    ApplicationBus.getInstance().publishAsync(new Tablexia.ChangeScreenEvent(EncyclopediaScreen.class, TablexiaApplication.ScreenTransaction.FADE));
+                } else if (color.equals(STATISTICS_COLOR)) {
+                    ApplicationBus.getInstance().publishAsync(new Tablexia.ChangeScreenEvent(StatisticsScreen.class, TablexiaApplication.ScreenTransaction.FADE));
+                } else if (color.equals(HALLOFFAME_COLOR)) {
+                    ApplicationBus.getInstance().publishAsync(new Tablexia.ChangeScreenEvent(HallOfFameScreen.class, TablexiaApplication.ScreenTransaction.FADE));
+                } else if (color.equals(STREET_COLOR)) {
+                    ApplicationBus.getInstance().publishAsync(new ShowStreetEvent());
+                } else if (color.equals(PROFILE_COLOR)) {
+                    ApplicationBus.getInstance().publishAsync(new Tablexia.ChangeScreenEvent(ProfileScreen.class, TablexiaApplication.ScreenTransaction.FADE));
+                }
+                hideAllActions();
+            }
+        });
     }
 
+    private void createImageStack() {
+        Stack stack = new Stack();
+        stack.setSize(getScreen().getStage().getWidth(), getScreen().getStage().getHeight());
+        stack.setPosition(0, 0);
+        addActor(stack);
+
+        stack.addActor(createImage(GameMenuAssets.OFFICE));
+        stack.addActor(street = createImage(GameMenuAssets.DOOR_PRESSED));
+        stack.addActor(encyclopedia = createImage(GameMenuAssets.ENCYCLOPEDIA_PRESSED));
+        stack.addActor(statistics = createImage(GameMenuAssets.STATISTICS_PRESSED));
+        stack.addActor(hallOfFame = createImage(GameMenuAssets.HALLOFFAME_PRESSED));
+        stack.addActor(createImage(GameMenuAssets.DESK));
+        stack.addActor(profile = createImage(GameMenuAssets.PROFILE_PRESSED));
+
+        hideAllActions();
+
+        help = new Stack();
+        help.setSize(getScreen().getStage().getWidth(), getScreen().getStage().getHeight());
+        help.setPosition(0, 0);
+        stack.addActor(help);
+        Image overlay = createImage(GameMenuAssets.OVERLAY);
+        overlay.getColor().a = 0.5f;
+        help.addActor(overlay);
+        help.addActor(createImage(GameMenuAssets.OFFICE_HELP));
+    }
+
+    private void hideAllActions() {
+        profile.setVisible(false);
+        street.setVisible(false);
+        encyclopedia.setVisible(false);
+        statistics.setVisible(false);
+        hallOfFame.setVisible(false);
+
+    }
+
+    /**
+     * Helper method for creating image instances
+     *
+     * @param texture
+     * @return
+     */
+    private Image createImage(String texture) {
+        Image image = new Image(getScreen().getTexture(texture));
+        return image;
+    }
+
+    private Color getTouchedColor(float x, float y) {
+        Texture clickmap = getScreen().getTexture(GameMenuAssets.OFFICE_CLICKMAP);
+        if (!clickmap.getTextureData().isPrepared()) {
+            clickmap.getTextureData().prepare();
+        }
+
+        Pixmap pixmap = clickmap.getTextureData().consumePixmap();
+        int clickX = (int) (x / getWidth() * clickmap.getWidth());
+        int clickY = clickmap.getHeight() - (int) (y / getHeight() * clickmap.getHeight());
+        return new Color(pixmap.getPixel(clickX, clickY));
+    }
 
-    @Override
-    public void draw(Batch batch, float parentAlpha) {
-        batch.disableBlending();
-        batch.draw(backgroundTexture, getX(), getY(), getWidth(), getHeight());
-        batch.enableBlending();
+    /**
+     * Event fired by clicking on door telling viewpager to page to first game
+     */
+    public static class ShowStreetEvent implements ApplicationBus.ApplicationEvent {
     }
 }
diff --git a/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java b/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java
index 2902da42a24e16a6bf6b6e7c919be00458ff0460..ab4540de92b5599693c68da84ce0edc1ee5a8680 100644
--- a/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java
+++ b/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java
@@ -1,9 +1,8 @@
 package cz.nic.tablexia.screen.loader;
 
 import com.badlogic.gdx.graphics.Texture;
-import com.badlogic.gdx.graphics.Texture.TextureFilter;
-import com.badlogic.gdx.graphics.g2d.Batch;
-import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
 
 import java.util.List;
 
@@ -13,44 +12,46 @@ import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 public class LoaderScreen extends AbstractTablexiaScreen<Void> {
 
     private static final String LOADER_BACKGROUND = "gfx/screen_loader_background.jpg";
-
-    private LoaderBackground background;
-    private Texture backgroundTexture;
-
-    private class LoaderBackground extends Actor {
-
-
-        public LoaderBackground() {
-            backgroundTexture = getTexture(LOADER_BACKGROUND);
-            backgroundTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
-        }
-
-        @Override
-        public void draw(Batch batch, float parentAlpha) {
-            batch.disableBlending();
-            batch.draw(backgroundTexture, 0, 0, getWidth(), getHeight());
-            batch.enableBlending();
-        }
-
-    }
+    private static final String LOADER_SMALL_HAND = "gfx/screen_loader_smallhand.png";
+    private static final String LOADER_BIG_HAND = "gfx/screen_loader_bighand.png";
 
     public LoaderScreen() {
-        super(false, TablexiaAssetManager.StorageType.INTERNAL);
+        super(false, false, TablexiaAssetManager.StorageType.INTERNAL);
     }
 
     @Override
     protected void prepareScreenTextureAssetNames(List<String> textureFileNames) {
         textureFileNames.add(LOADER_BACKGROUND);
+        textureFileNames.add(LOADER_SMALL_HAND);
+        textureFileNames.add(LOADER_BIG_HAND);
     }
 
     @Override
     protected void screenLoaded() {
-        background = new LoaderBackground();
+        Image background = new Image(getTexture(LOADER_BACKGROUND));
+        background.setPosition(0, 0);
+        background.setSize(getStage().getWidth(), getStage().getHeight());
         getStage().addActor(background);
+
+        Image smallhand = new Image(getTexture(LOADER_SMALL_HAND));
+        smallhand.setPosition(getStage().getWidth() * 0.22f, getStage().getHeight() * 0.64f);
+        smallhand.setSize(getStage().getWidth() * 0.01f, getStage().getHeight() * 0.06f);
+        getStage().addActor(smallhand);
+        smallhand.setOrigin(smallhand.getWidth() / 2, 0);
+        smallhand.addAction(Actions.forever(Actions.rotateBy(-360, 6)));
+
+        Image bighand = new Image(getTexture(LOADER_BIG_HAND));
+        bighand.setPosition(getStage().getWidth() * 0.22f, getStage().getHeight() * 0.64f);
+        bighand.setSize(getStage().getWidth() * 0.01f, getStage().getHeight() * 0.06f);
+        getStage().addActor(bighand);
+        bighand.setOrigin(bighand.getWidth() / 2, 0);
+        bighand.addAction(Actions.forever(Actions.rotateBy(-360, 0.5f)));
     }
 
     @Override
-    public void screenResized(int width, int height) {
-        background.setSize(width, height);
+    public Texture getTexture(String textureName) {
+        Texture t = super.getTexture(textureName);
+        t.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
+        return t;
     }
 }
diff --git a/core/src/cz/nic/tablexia/screen/preferences/PreferencesScreen.java b/core/src/cz/nic/tablexia/screen/preferences/PreferencesScreen.java
index e70f383ab8d51d15d5c98f35c6335ecc98e5f6c2..e32b6e3d5a9f7dfe07f35c61a53b5630f82b89f9 100644
--- a/core/src/cz/nic/tablexia/screen/preferences/PreferencesScreen.java
+++ b/core/src/cz/nic/tablexia/screen/preferences/PreferencesScreen.java
@@ -49,6 +49,7 @@ public class PreferencesScreen extends AbstractTablexiaScreen<Void> {
         preferencesContainer.setActor(preferencesLayout);
         preferencesContainer.left().top();
         preferencesContainer.pad(getStage().getWidth() / 10);
+        preferencesContainer.setBounds(0, 0, getStage().getWidth(), getStage().getHeight());
 
         // Languages Label
         Label languagesLabel = new Label(getText(LANGUAGE_LABEL_KEY), labelStyle);
diff --git a/core/src/cz/nic/tablexia/screen/profile/ProfileScreen.java b/core/src/cz/nic/tablexia/screen/profile/ProfileScreen.java
new file mode 100644
index 0000000000000000000000000000000000000000..146490493ed1fc0da1a688746b9ee00c68cfaf5f
--- /dev/null
+++ b/core/src/cz/nic/tablexia/screen/profile/ProfileScreen.java
@@ -0,0 +1,21 @@
+package cz.nic.tablexia.screen.profile;
+
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.scenes.scene2d.ui.Label;
+import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
+import com.badlogic.gdx.scenes.scene2d.ui.Table;
+
+import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+
+public class ProfileScreen extends AbstractTablexiaScreen<Void> {
+
+    @Override
+    protected void screenLoaded() {
+        Label label = new Label(getClass().getSimpleName(), new LabelStyle(getDefaultRegularFont(), Color.WHITE));
+        Table table = new Table();
+        table.add(label);
+        label.setPosition(getStage().getWidth() / 2, getStage().getHeight() / 2);
+        getStage().addActor(label);
+    }
+
+}
diff --git a/core/src/cz/nic/tablexia/screen/viewport/FullscreenImageDebugScreen.java b/core/src/cz/nic/tablexia/screen/viewport/FullscreenImageDebugScreen.java
new file mode 100644
index 0000000000000000000000000000000000000000..62d64ab7a0eeaa9b14075ec63589e971306a25d8
--- /dev/null
+++ b/core/src/cz/nic/tablexia/screen/viewport/FullscreenImageDebugScreen.java
@@ -0,0 +1,57 @@
+package cz.nic.tablexia.screen.viewport;
+
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+
+import java.util.List;
+
+import cz.nic.tablexia.loader.TablexiaAssetManager;
+import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+
+public class FullscreenImageDebugScreen extends AbstractTablexiaScreen<Void> {
+
+    private static final String LOADER_BACKGROUND = "gfx/screen_loader_background.jpg";
+    private static final String LOADER_SMALL_HAND = "gfx/screen_loader_smallhand.png";
+    private static final String LOADER_BIG_HAND = "gfx/screen_loader_bighand.png";
+
+    public FullscreenImageDebugScreen() {
+        super(false, false, TablexiaAssetManager.StorageType.INTERNAL);
+    }
+
+    @Override
+    protected void prepareScreenTextureAssetNames(List<String> textureFileNames) {
+        textureFileNames.add(LOADER_BACKGROUND);
+        textureFileNames.add(LOADER_SMALL_HAND);
+        textureFileNames.add(LOADER_BIG_HAND);
+    }
+
+    @Override
+    protected void screenLoaded() {
+        Image background = new Image(getTexture(LOADER_BACKGROUND));
+        background.setPosition(0, 0);
+        background.setSize(getStage().getWidth(), getStage().getHeight());
+        getStage().addActor(background);
+
+        Image smallhand = new Image(getTexture(LOADER_SMALL_HAND));
+        smallhand.setPosition(getStage().getWidth() * 0.22f, getStage().getHeight() * 0.64f);
+        smallhand.setSize(getStage().getWidth() * 0.01f, getStage().getHeight() * 0.06f);
+        getStage().addActor(smallhand);
+        smallhand.setOrigin(smallhand.getWidth() / 2, 0);
+        smallhand.addAction(Actions.forever(Actions.rotateBy(-360, 6)));
+
+        Image bighand = new Image(getTexture(LOADER_BIG_HAND));
+        bighand.setPosition(getStage().getWidth() * 0.22f, getStage().getHeight() * 0.64f);
+        bighand.setSize(getStage().getWidth() * 0.01f, getStage().getHeight() * 0.06f);
+        getStage().addActor(bighand);
+        bighand.setOrigin(bighand.getWidth() / 2, 0);
+        bighand.addAction(Actions.forever(Actions.rotateBy(-360, 0.5f)));
+    }
+
+    @Override
+    public Texture getTexture(String textureName) {
+        Texture t = super.getTexture(textureName);
+        t.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
+        return t;
+    }
+}
diff --git a/core/src/cz/nic/tablexia/screen/viewport/ViewportDebugScreen.java b/core/src/cz/nic/tablexia/screen/viewport/ViewportDebugScreen.java
new file mode 100644
index 0000000000000000000000000000000000000000..ab27da94d0352bebe2fc8f214cd809a7e933b88b
--- /dev/null
+++ b/core/src/cz/nic/tablexia/screen/viewport/ViewportDebugScreen.java
@@ -0,0 +1,91 @@
+package cz.nic.tablexia.screen.viewport;
+
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.InputListener;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+
+import java.util.List;
+
+import cz.nic.tablexia.TablexiaSettings;
+import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+import cz.nic.tablexia.util.Log;
+
+/**
+ * Created by lhoracek on 4/13/15.
+ */
+public class ViewportDebugScreen extends AbstractTablexiaScreen<Void> {
+
+    private static final String BASE = "screen/debug/";
+
+    @Override
+    protected void prepareScreenTextureAssetNames(List<String> textureFileNames) {
+        textureFileNames.add(BASE + "red.png");
+        textureFileNames.add(BASE + "blue.png");
+        textureFileNames.add(BASE + "yellow.png");
+        textureFileNames.add(BASE + "pink.png");
+        textureFileNames.add(BASE + "black.png");
+        textureFileNames.add(BASE + "checker.png");
+        textureFileNames.add(BASE + "point.png");
+    }
+
+    @Override
+    protected void screenLoaded() {
+        getStage().setDebugAll(true);
+
+        Image large = new Image(getTexture("yellow.png"));
+        large.setSize(TablexiaSettings.getDefaultScreenWidth(), TablexiaSettings.getMinScreenHeight() * 2);
+        large.setPosition(0, TablexiaSettings.getMinScreenHeight() / -2.0f);
+        getStage().addActor(large);
+
+
+        Image widescreen = new Image(getTexture("red.png"));
+        widescreen.setSize(1000, TablexiaSettings.getMinScreenHeight());
+        getStage().addActor(widescreen);
+
+        int size = 10;
+        for (int i = 0; i < size; i++) {
+            for (int j = 0; j < size; j++) {
+                Texture checker = getTexture("checker.png");
+                Image check = new Image(checker);
+                check.setPosition(500 - (check.getWidth() * size / 2) + (i * check.getWidth()), TablexiaSettings.getMinScreenHeight() / 2 - (check.getWidth() * size / 2) + (j * check.getWidth()));
+                getStage().addActor(check);
+            }
+        }
+
+        getStage().addListener(new InputListener() {
+            Image point;
+
+            @Override
+            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
+                Log.debug(getClass(), "Touchdown");
+                point = new Image(getTexture("point.png"));
+                getStage().addActor(point);
+                point.setPosition(x - point.getWidth() / 2, y - point.getHeight() / 2);
+                return true;
+            }
+
+
+            @Override
+            public void touchDragged(InputEvent event, float x, float y, int pointer) {
+                point.setPosition(x - point.getWidth() / 2, y - point.getHeight() / 2);
+            }
+
+            @Override
+            public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
+                Log.debug(getClass(), "Liftoff");
+                point.remove();
+                point = null;
+            }
+        });
+        // TODO
+    }
+
+    @Override
+    public Texture getTexture(String textureName) {
+        Texture texture = super.getTexture(BASE + textureName);
+        texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
+        return texture;
+    }
+
+}
diff --git a/core/src/cz/nic/tablexia/util/Utility.java b/core/src/cz/nic/tablexia/util/Utility.java
new file mode 100644
index 0000000000000000000000000000000000000000..e95fc1306fc99d551eaa75e1273d28c3912751c0
--- /dev/null
+++ b/core/src/cz/nic/tablexia/util/Utility.java
@@ -0,0 +1,19 @@
+package cz.nic.tablexia.util;
+
+import com.badlogic.gdx.utils.reflect.ClassReflection;
+import com.badlogic.gdx.utils.reflect.ReflectionException;
+
+import cz.nic.tablexia.screen.AbstractTablexiaScreen;
+
+public class Utility {
+
+    public static AbstractTablexiaScreen<?> getScreenForScreenClass(Class<? extends AbstractTablexiaScreen<?>> screenClass) {
+        try {
+            return (AbstractTablexiaScreen<?>) ClassReflection.getConstructors(screenClass)[0].newInstance(new Object[]{});
+        } catch (ReflectionException e) {
+            Log.err(Utility.class, "Cannot instantiate screen class: " + screenClass + " ! (Do you have only one parameter less constructor in screen class?)", e);
+        }
+        return null;
+    }
+
+}
diff --git a/core/src/cz/nic/tablexia/util/assetmanager/DirectoryAsset.java b/core/src/cz/nic/tablexia/util/assetmanager/DirectoryAsset.java
new file mode 100644
index 0000000000000000000000000000000000000000..15136168250072e1231f4a139be8a78b946d12dd
--- /dev/null
+++ b/core/src/cz/nic/tablexia/util/assetmanager/DirectoryAsset.java
@@ -0,0 +1,50 @@
+package cz.nic.tablexia.util.assetmanager;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.files.FileHandle;
+
+import java.util.HashMap;
+
+import cz.nic.tablexia.loader.TablexiaAssetManager;
+import cz.nic.tablexia.util.Log;
+
+/**
+ * Created by lhoracek on 4/3/15.
+ */
+public abstract class DirectoryAsset extends HashMap<String, String> {
+    public abstract String getPath();
+
+    public DirectoryAsset() {
+        loadFilesInDir(getPath());
+    }
+
+    private void loadFilesInDir(String path) {
+        for (FileHandle entry : getDirHandle(path).list()) {
+            loadFiles("", entry);
+        }
+    }
+
+    private void loadFiles(String path, FileHandle fh) {
+        if (fh.isDirectory()) {
+            Log.info(getClass().getName(), "Is directory: " + fh.name());
+            for (FileHandle entry : fh.list()) {
+                loadFiles(path + fh.name() + "/", entry);
+            }
+        } else {
+            add(path, fh);
+        }
+    }
+
+    private FileHandle getDirHandle(String path) {
+        FileHandle dirHandle;
+        dirHandle = Gdx.files.external(TablexiaAssetManager.StorageType.EXTERNAL.getStoragePath() + path);
+        return dirHandle;
+    }
+
+    public String add(String path, FileHandle fh) {
+        String fullPath = getPath() + "/" + path + fh.name();
+        String key = path + fh.nameWithoutExtension();
+        Log.info(getClass().getName(), "Adding asset: " + key + " : " + fullPath);
+        return super.put(key, fullPath);
+    }
+}
diff --git a/core/src/cz/nic/tablexia/util/ui/ViewPager.java b/core/src/cz/nic/tablexia/util/ui/ViewPager.java
index fba4df5295d02435ec11746cb1503267f701e1fe..4f63c9811ca3868e22ee7be33bb2f69c07617c3c 100644
--- a/core/src/cz/nic/tablexia/util/ui/ViewPager.java
+++ b/core/src/cz/nic/tablexia/util/ui/ViewPager.java
@@ -14,9 +14,7 @@ import com.badlogic.gdx.utils.Array;
 public class ViewPager extends ScrollPane {
 
     private boolean wasPanDragFling = false;
-
-    private float pageSpacing;
-
+    private float lastX;
     private Table content;
 
     public ViewPager() {
@@ -42,7 +40,11 @@ public class ViewPager extends ScrollPane {
     private void setup() {
         content = new Table();
         super.setWidget(content);
+        content.setSize(100,100);
         content.defaults().space(0);
+        //setClamp(false);
+        //setScrollingDisabled(false, true);
+        setFlingTime(0.1f);
     }
 
     @Override
@@ -67,7 +69,6 @@ public class ViewPager extends ScrollPane {
 
     @Override
     public void act(float delta) {
-        super.act(delta);
         if (wasPanDragFling && !isPanning() && !isDragging() && !isFlinging()) {
             wasPanDragFling = false;
             scrollToPage();
@@ -76,8 +77,43 @@ public class ViewPager extends ScrollPane {
                 wasPanDragFling = true;
             }
         }
+
+
+        if (lastX != getWidget().getX()) {
+            float scrollX = -getWidget().getX();
+            Array<Actor> pages = content.getChildren();
+            float pageX = 0;
+            float pageWidth = 0;
+
+            if (pages.size > 0) {
+                for (Actor a : pages) {
+                    pageX = a.getX();
+                    pageWidth = a.getWidth();
+                    if (scrollX > pageX && scrollX < (pageX + pageWidth)) {
+                        if (a instanceof ScrollListener) {
+                            ScrollListener sl = (ScrollListener) a;
+                            sl.onScroll(-(scrollX - pageX));
+                        }
+                    } else if (scrollX < (pageX) && (scrollX + pageWidth) > pageX) {
+                        if (a instanceof ScrollListener) {
+                            ScrollListener sl = (ScrollListener) a;
+                            sl.onScroll(pageX - scrollX);
+                        }
+                    }
+                    if (pageX == scrollX) {
+                        if (a instanceof ScrollListener) {
+                            ScrollListener sl = (ScrollListener) a;
+                            sl.onScrolledToPage();
+                        }
+                    }
+                }
+            }
+        }
+        lastX = getWidget().getX();
+        super.act(delta);
     }
 
+
     @Override
     @Deprecated
     public void setWidget(Actor widget) {
@@ -95,13 +131,28 @@ public class ViewPager extends ScrollPane {
         }
     }
 
-    public void setPageSpacing(float pageSpacing) {
-        if (content != null) {
-            content.defaults().space(pageSpacing);
-            for (Cell cell : content.getCells()) {
-                cell.space(pageSpacing);
+    /**
+     * Smooth scroll to child with given index
+     *
+     * @param page
+     */
+    public void scrollToPage(int page) {
+        // TODO cleanup
+        if (content.getChildren().size <= page) {
+            throw new IllegalArgumentException("Page index " + page + " out of bounds");
+        }
+        final float width = getWidth();
+        final float maxX = getMaxX();
+
+        float pageX = 0;
+        float pageWidth = 0;
+        if (content.getChildren().size > 0) {
+            for (int i = 0; i <= page; i++) {
+                Actor a = content.getChildren().get(i);
+                pageX = a.getX();
+                pageWidth = a.getWidth();
             }
-            content.invalidate();
+            setScrollX(MathUtils.clamp(pageX - (width - pageWidth) / 2, 0, maxX));
         }
     }
 
@@ -127,5 +178,9 @@ public class ViewPager extends ScrollPane {
         }
     }
 
+    public static interface ScrollListener {
+        public void onScroll(float offset);
 
+        public void onScrolledToPage();
+    }
 }
diff --git a/core/src/cz/nic/tablexia/util/ui/XFillViewport.java b/core/src/cz/nic/tablexia/util/ui/XFillViewport.java
index 6f9a192ae6d2aa2d54538ee7d8112485584eb355..831a9ac5c06b710f0c2051dc35b4e88a2812a4db 100644
--- a/core/src/cz/nic/tablexia/util/ui/XFillViewport.java
+++ b/core/src/cz/nic/tablexia/util/ui/XFillViewport.java
@@ -1,5 +1,6 @@
 package cz.nic.tablexia.util.ui;
 
+import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.graphics.Camera;
 import com.badlogic.gdx.graphics.OrthographicCamera;
 import com.badlogic.gdx.utils.viewport.Viewport;
@@ -12,9 +13,6 @@ import cz.nic.tablexia.util.Log;
  */
 public class XFillViewport extends Viewport {
 
-
-    private float worldWidth, worldHeight;
-
     /**
      * Creates a new viewport using a new {@link com.badlogic.gdx.graphics.OrthographicCamera} with no maximum world size.
      */
@@ -31,10 +29,36 @@ public class XFillViewport extends Viewport {
         setCamera(camera);
     }
 
+    private int screenX, screenY, screenWidth, screenHeight;
+    private float cameraYOffset;
+
+
     @Override
     public void update(int screenWidth, int screenHeight, boolean centerCamera) {
-        int height = (int) Math.min(screenHeight, screenWidth * TablexiaSettings.getMaximumRatio());
-        setScreenBounds(0, Math.max(0, (screenHeight - height) / 2), screenWidth, height);
+        float newWorldHeight = getWorldWidth() / ((float) screenWidth / (float) screenHeight);
+
+        // FIT into screen keeping at least minimum ration
+        this.screenX = (newWorldHeight < TablexiaSettings.getMinScreenHeight()) ? ((int) ((screenWidth - (screenHeight / TablexiaSettings.getMaximumRatio())) / 2)) : 0;
+        this.screenY = 0;
+        this.screenWidth = (newWorldHeight < TablexiaSettings.getMinScreenHeight()) ? ((int) (screenHeight / TablexiaSettings.getMaximumRatio())) : screenWidth;
+        this.screenHeight = screenHeight;
+        setScreenBounds(screenX,screenY,this.screenWidth,this.screenHeight);
+        // SET NEW WORLD HEIGHT
+        this.setWorldHeight(newWorldHeight < TablexiaSettings.getMinScreenHeight() ? TablexiaSettings.getMinScreenHeight() : newWorldHeight); // World width dooes not change
+        cameraYOffset = (getWorldHeight() - TablexiaSettings.getMinScreenHeight()) / 2;
+
+        Log.info(getClass().getName(), "New viewport size (min: " + TablexiaSettings.getMinScreenHeight() + ") update: " + screenWidth + "x" + screenHeight + " - position: " + screenX + "x" + screenY + " - bounds: " + this.screenWidth + "x" + this.screenHeight + " - world: " + getWorldWidth() + "x" + getWorldHeight() + " - y offset: " + cameraYOffset);
         apply(centerCamera);
     }
+
+    @Override
+    public void apply(boolean centerCamera) {
+        Gdx.gl.glViewport(screenX, screenY, screenWidth, screenHeight);
+        getCamera().viewportWidth = getWorldWidth();
+        getCamera().viewportHeight = getWorldHeight();
+        if (centerCamera) getCamera().position.set(getWorldWidth() / 2, getWorldHeight() / 2, 0);
+        getCamera().position.y -= cameraYOffset;
+        getCamera().update();
+    }
+
 }
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/AbstractButtonDialog.java b/core/src/cz/nic/tablexia/util/ui/dialog/AbstractButtonDialog.java
index 326a6b426391d8bd379cf8f647282882fcbd37c1..857bbf21a4c05cf159406bc4518436be2c819123 100644
--- a/core/src/cz/nic/tablexia/util/ui/dialog/AbstractButtonDialog.java
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/AbstractButtonDialog.java
@@ -1,37 +1,36 @@
 package cz.nic.tablexia.util.ui.dialog;
 
-import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.Color;
 import com.badlogic.gdx.graphics.g2d.NinePatch;
-import com.badlogic.gdx.scenes.scene2d.InputEvent;
-import com.badlogic.gdx.scenes.scene2d.ui.Skin;
 import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
 import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
 import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;
 
+import cz.nic.tablexia.loader.application.ApplicationFontManager;
 import cz.nic.tablexia.util.ui.dialog.text.DialogTextContent;
 
 /**
  * Created by Václav Tarantík on 9.4.15.
  */
-public abstract class AbstractButtonDialog extends TablexiaDialog {
+public abstract class AbstractButtonDialog extends TextDialog {
+
+    private static final Color DEFAULT_BUTTON_TEXT_COLOR = Color.BLACK;
+    private static final String DEFAULT_BUTTON_TEXT_FONT = ApplicationFontManager.APPLICATION_DEFAULT_FONT_REGULAR;
+
     private static final String BTN_DISABLED_ATLAS_NAME = "tablexiabutton_disabled";
-    private static final float BUTTON_WIDTH_RATIO_TO_DIALOG_WIDTH = 0.3f;
-    private static final float BUTTON_HEIGHT_RATIO = 0.53f;
+    private static final float BUTTON_WIDTH_RATIO_TO_DIALOG_WIDTH = 0.27f;
+    private static final float BUTTON_HEIGHT_RATIO = 0.5f;
 
     private static final String BTN_DRAWABLE_PRESSED_ENDING = "_pressed";
     private static final String BTN_DRAWABLE_UNPRESSED_ENDING = "_unpressed";
 
     public AbstractButtonDialog(float x, float y, float width, float height, BackGroundType backGroundType, DialogTextContent dialogTextContent) {
-        super(x, y, width, height, backGroundType, dialogTextContent);
+        super(x, y, width, height, backGroundType,dialogTextContent);
     }
 
-    public void createButton(ButtonType buttonType, String buttonText,ClickListener clickListener){
+    public void createButton(ButtonType buttonType, String buttonText, ClickListener clickListener){
         if(buttonType!=null){
 
-            // usikin.json is the system default skin used by libgdx
-            TextButton textButton =  new TextButton(buttonText, new Skin(Gdx.files.internal("uiskin.json")));
-
-
             NinePatch up = buttonAtlas.createPatch(buttonType.getButtonResourceName()+BTN_DRAWABLE_UNPRESSED_ENDING);
             NinePatchDrawable npdUp = new NinePatchDrawable(up);
 
@@ -41,12 +40,17 @@ public abstract class AbstractButtonDialog extends TablexiaDialog {
             NinePatch dis = buttonAtlas.createPatch(BTN_DISABLED_ATLAS_NAME);
             NinePatchDrawable npdDis = new NinePatchDrawable(dis);
 
-            textButton.setStyle(new TextButton.TextButtonStyle(npdUp, npdDown, npdDis, getStyle().titleFont));
+            TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle(npdUp, npdDown, npdDis, ApplicationFontManager.getInstance().getFont(DEFAULT_BUTTON_TEXT_FONT));
+            textButtonStyle.fontColor = DEFAULT_BUTTON_TEXT_COLOR;
+            TextButton textButton = new TextButton(buttonText, textButtonStyle);
+
             textButton.addListener(clickListener);
 
-            float buttonWidth = getPrefWidth()* BUTTON_WIDTH_RATIO_TO_DIALOG_WIDTH;
-            float buttonHeight = buttonWidth*BUTTON_HEIGHT_RATIO;
-            getButtonTable().add(textButton).width(buttonWidth).height(buttonHeight);
+            float buttonWidth = getWidth() * BUTTON_WIDTH_RATIO_TO_DIALOG_WIDTH;
+            float buttonHeight = buttonWidth * BUTTON_HEIGHT_RATIO;
+
+            button(textButton);
+            getButtonTable().getCell(textButton).width(buttonWidth).height(buttonHeight).spaceLeft(buttonWidth / 3);
 
         }else{
             throw new IllegalArgumentException("Invalid dialog type. Buttons not supported for this type.");
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/ImageDialog.java b/core/src/cz/nic/tablexia/util/ui/dialog/ImageDialog.java
index ea3cc18aac79f1c314956d0a61287776c00b46ae..9c729eac590d7042484ccb026600a9314364ccbe 100644
--- a/core/src/cz/nic/tablexia/util/ui/dialog/ImageDialog.java
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/ImageDialog.java
@@ -4,36 +4,39 @@ import com.badlogic.gdx.graphics.Texture;
 import com.badlogic.gdx.scenes.scene2d.ui.Image;
 import com.badlogic.gdx.scenes.scene2d.ui.Table;
 
-import java.util.List;
-
 import cz.nic.tablexia.util.ui.dialog.text.DialogTextContent;
 
 /**
  * Created by Václav Tarantík on 19.3.15.
  */
-public class ImageDialog extends TablexiaDialog {
+public class ImageDialog extends TextDialog {
+    private Table imageTable;
     private Texture[] textures;
 
     public ImageDialog(float x, float y,float width, float height,BackGroundType backGroundType,  DialogTextContent dialogTextContent,Texture... textures) {
         super(x,y,width,height, backGroundType,dialogTextContent);
         this.textures = textures;
-
-        prepareContent(dialogTextContent);
+        imageTable = new Table();
     }
 
-    private void prepareContent(DialogTextContent dialogTextContent){
+    protected void prepareContent(){
+        super.prepareContent();
         getContentTable().row();
         prepareImages();
     }
 
     private void prepareImages(){
-        Table imageGroup = new Table();
 
         for(Texture texture:textures){
-            Image image = new Image(texture);
-            imageGroup.add(image).padBottom(20f);
-            imageGroup.row();
+            addImage(texture);
         }
-        getContentTable().add(imageGroup).width(width/2);
+        getContentTable().add(imageTable).width(getWidth() / 2).height(getHeight()/2);
     }
+
+    protected void addImage(Texture texture){
+        Image image = new Image(texture);
+        imageTable.add(image).padBottom(20f);
+        imageTable.row();
+    }
+
 }
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/SingleButtonDialog.java b/core/src/cz/nic/tablexia/util/ui/dialog/SingleButtonDialog.java
index 43340697462f6f498ae11690efab15e33acfe0e0..e4c4a110132313e1d833f6f3254a1596b24f282a 100644
--- a/core/src/cz/nic/tablexia/util/ui/dialog/SingleButtonDialog.java
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/SingleButtonDialog.java
@@ -1,12 +1,7 @@
 package cz.nic.tablexia.util.ui.dialog;
 
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.graphics.g2d.NinePatch;
 import com.badlogic.gdx.scenes.scene2d.InputEvent;
-import com.badlogic.gdx.scenes.scene2d.ui.Skin;
-import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
 import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
-import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;
 
 import cz.nic.tablexia.util.ui.dialog.text.DialogTextContent;
 
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaDialog.java b/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaDialog.java
index 343837777bc88cf042c5dd8765f9b7d959662219..eff62ca0f228aad4dc0bb04a54cb0dd23533e9b3 100644
--- a/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaDialog.java
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaDialog.java
@@ -2,14 +2,12 @@ package cz.nic.tablexia.util.ui.dialog;
 
 import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.graphics.Color;
-import com.badlogic.gdx.graphics.g2d.NinePatch;
 import com.badlogic.gdx.graphics.g2d.TextureAtlas;
 import com.badlogic.gdx.math.Interpolation;
 import com.badlogic.gdx.scenes.scene2d.Stage;
 import com.badlogic.gdx.scenes.scene2d.actions.Actions;
 import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
 import com.badlogic.gdx.scenes.scene2d.ui.Label;
-import com.badlogic.gdx.scenes.scene2d.ui.Skin;
 import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;
 
 import cz.nic.tablexia.loader.application.ApplicationFontManager;
@@ -21,15 +19,10 @@ import static com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence;
  * Created by Václav Tarantík on 17.3.15.
  */
 public class TablexiaDialog extends Dialog {
-    protected static Skin skin;
+
     public static TextureAtlas backgroundAtlas;
     public static TextureAtlas buttonAtlas;
 
-    protected float width;
-    protected float height;
-    protected float x;
-    protected float y;
-    protected BackGroundType backGroundType;
     protected DialogTextContent dialogTextContent;
 
     public enum BackGroundType {
@@ -46,11 +39,6 @@ public class TablexiaDialog extends Dialog {
         BackGroundType(String dialogBackgroundTextureName){
             this.dialogBackgroundTextureName = dialogBackgroundTextureName;
         }
-
-        public String getDialogBackgroundTextureName(){
-            return dialogBackgroundTextureName;
-        }
-
     }
 
     public enum ButtonType{
@@ -70,47 +58,32 @@ public class TablexiaDialog extends Dialog {
     }
 
     static {
-        //uiskin.json is libgdx system default skin
-        skin = new Skin(Gdx.files.internal("uiskin.json"));
         backgroundAtlas = new TextureAtlas(Gdx.files.internal("atlases/dialog_background.atlas"));
         buttonAtlas = new TextureAtlas(Gdx.files.internal("atlases/buttons_atlas.pack"));
     }
 
-    public TablexiaDialog(float x, float y,float width,float height, BackGroundType backGroundType,DialogTextContent dialogTextContent) {
-        super("",skin);
+    public TablexiaDialog(float x, float y,float width,float height, BackGroundType backGroundType) {
+        super("", new WindowStyle(ApplicationFontManager.getInstance().getDefaultApplicationRegularFont(),
+                                  Color.BLACK,
+                                  new NinePatchDrawable(backgroundAtlas.createPatch(backGroundType.dialogBackgroundTextureName))));
+
         setModal(true);
         setMovable(false);
         setResizable(false);
 
-        this.x = x;
-        this.y = y;
-        this.width = width;
-        this.height = height;
-        this.backGroundType = backGroundType;
-        this.dialogTextContent = dialogTextContent;
-
-        NinePatch np = backgroundAtlas.createPatch(backGroundType.dialogBackgroundTextureName);
-        NinePatchDrawable npd = new NinePatchDrawable(np);
-        setBackground(npd);
-        prepareTextContent();
+        setBounds(x, y, width, height);
+        getBackground().setMinWidth(width);
+        getBackground().setMinHeight(height);
     }
 
     @Override
     public Dialog show(Stage stage) {
+        prepareContent();
         show(stage, sequence(Actions.alpha(0), Actions.fadeIn(0.4f, Interpolation.fade)));
-        setBounds(x,y,width,height);
         return this;
     }
 
-    protected void prepareTextContent(){
-        Label.LabelStyle labelStyle = new Label.LabelStyle(ApplicationFontManager.getInstance().getFont(ApplicationFontManager.APPLICATION_DEFAULT_FONT_REGULAR),Color.BLACK);
-        if(dialogTextContent.getTitle() != null && !dialogTextContent.getTitle().equals("")){
-            Label titleLabel = new Label(dialogTextContent.getTitle(),labelStyle);
-            getContentTable().add(titleLabel).center()  ;
-            getContentTable().row();
-        }
-        Label label = new Label(dialogTextContent.getContent(),labelStyle);
-        label.setWrap(true);
-        getContentTable().add(label).left().top().expand().fillX();
+    protected void prepareContent(){
+        //no content here
     }
 }
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/TextDialog.java b/core/src/cz/nic/tablexia/util/ui/dialog/TextDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..ccd69cbeb24048f6d0389342db44d09c635faa06
--- /dev/null
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/TextDialog.java
@@ -0,0 +1,37 @@
+package cz.nic.tablexia.util.ui.dialog;
+
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.scenes.scene2d.ui.Label;
+
+import cz.nic.tablexia.loader.application.ApplicationFontManager;
+import cz.nic.tablexia.util.ui.dialog.text.DialogTextContent;
+
+/**
+ * Created by Václav Tarantík on 24.4.15.
+ */
+public class TextDialog extends TablexiaDialog {
+    private static final float TITLE_FONT_SCALE = 0.7f;
+    private static final float CONTENT_FONT_SCALE = 0.5f;
+    private DialogTextContent dialogTextContent;
+
+    public TextDialog(float x, float y, float width, float height, BackGroundType backGroundType, DialogTextContent dialogTextContent) {
+        super(x, y, width, height, backGroundType);
+        this.dialogTextContent = dialogTextContent;
+    }
+
+    @Override
+    protected void prepareContent() {
+        Label.LabelStyle titleLabelStyle = new Label.LabelStyle(ApplicationFontManager.getInstance().getFont(ApplicationFontManager.APPLICATION_DEFAULT_FONT_BOLD), Color.BLACK);
+        titleLabelStyle.font.setScale(TITLE_FONT_SCALE);
+        if(dialogTextContent.getTitle() != null && !dialogTextContent.getTitle().equals("")){
+            Label titleLabel = new Label(dialogTextContent.getTitle(),titleLabelStyle);
+            getContentTable().add(titleLabel).center()  ;
+            getContentTable().row();
+        }
+        Label.LabelStyle contentLabelStyle = new Label.LabelStyle(ApplicationFontManager.getInstance().getFont(ApplicationFontManager.APPLICATION_DEFAULT_FONT_REGULAR), Color.BLACK);
+        contentLabelStyle.font.setScale(CONTENT_FONT_SCALE);
+        Label label = new Label(dialogTextContent.getContent(),contentLabelStyle);
+        label.setWrap(true);
+        getContentTable().add(label).left().top().expand().fillX();
+    }
+}
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/TwoButtonDialog.java b/core/src/cz/nic/tablexia/util/ui/dialog/TwoButtonDialog.java
index 60c16aff2d01680bdbad1660ef319a0484928e6d..462f59bbe1f392356cde0e8990cc0b149691e37c 100644
--- a/core/src/cz/nic/tablexia/util/ui/dialog/TwoButtonDialog.java
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/TwoButtonDialog.java
@@ -1,12 +1,7 @@
 package cz.nic.tablexia.util.ui.dialog;
 
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.graphics.g2d.NinePatch;
 import com.badlogic.gdx.scenes.scene2d.InputEvent;
-import com.badlogic.gdx.scenes.scene2d.ui.Skin;
-import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
 import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
-import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;
 
 import cz.nic.tablexia.util.ui.dialog.text.DialogTextContent;
 
@@ -14,14 +9,29 @@ import cz.nic.tablexia.util.ui.dialog.text.DialogTextContent;
  * Created by Václav Tarantík on 26.3.15.
  */
 public abstract class TwoButtonDialog extends AbstractButtonDialog {
-    public TwoButtonDialog(float x, float y,float width, float height, BackGroundType backGroundType,DialogTextContent dialogTextContent, ButtonType leftButtonType, ButtonType rightButtonType,String leftButtonText, String rightButtonText) {
-        super(x,y,width, height, backGroundType,dialogTextContent);
+    private ButtonType leftButtonType;
+    private  ButtonType rightButtonType;
+    private String leftButtonText;
+    private String rightButtonText;
 
-        createButton(leftButtonType,leftButtonText,new ClickListener() {
+    public TwoButtonDialog(float x, float y, float width, float height, BackGroundType backGroundType,DialogTextContent dialogTextContent, ButtonType leftButtonType, ButtonType rightButtonType,String leftButtonText, String rightButtonText) {
+        super(x, y, width, height, backGroundType, dialogTextContent);
+        this.leftButtonType = leftButtonType;
+        this.rightButtonType = rightButtonType;
+        this.leftButtonText = leftButtonText;
+        this.rightButtonText = rightButtonText;
+    }
+
+    @Override
+    protected void prepareContent() {
+        super.prepareContent();
+        createButton(leftButtonType, leftButtonText, new ClickListener() {
             @Override
             public void clicked(InputEvent event, float x, float y) {
                 leftButtonAction();
-            };
+            }
+
+            ;
         });
 
         createButton(rightButtonType,rightButtonText,new ClickListener() {
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/text/DialogTextContent.java b/core/src/cz/nic/tablexia/util/ui/dialog/text/DialogTextContent.java
index 2a7e31e10b3298bb8770d09bb861cde354fbba83..9cff9a0adc70e2301877bed283756354e7343fb2 100644
--- a/core/src/cz/nic/tablexia/util/ui/dialog/text/DialogTextContent.java
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/text/DialogTextContent.java
@@ -4,28 +4,25 @@ package cz.nic.tablexia.util.ui.dialog.text;
  * Created by Václav Tarantík on 27.3.15.
  */
 public class DialogTextContent {
+
     private String title;
     private String content;
 
-    public DialogTextContent(String title,String content){
+    public DialogTextContent(String content) {
+        this(null, content);
+    }
+
+    public DialogTextContent(String title, String content) {
         this.title = title;
         this.content = content;
     }
 
-
     public String getTitle() {
         return title;
     }
 
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
     public String getContent() {
         return content;
     }
 
-    public void setContent(String content) {
-        this.content = content;
-    }
 }
diff --git a/desktop/build.gradle b/desktop/build.gradle
index 3bddac4fcaf8618aa1c6d2473524bbc7a59035dc..180dfe2a02529075d3a148c93c7781ee10bbbf72 100644
--- a/desktop/build.gradle
+++ b/desktop/build.gradle
@@ -24,8 +24,7 @@ task debugJar(type: Jar) {
     manifest {
         attributes 'Main-Class': project.mainClassName
         attributes 'Build-Type': 'debug'
-        attributes 'Version-Name': version
-        attributes 'Application-Id': rootProject.applicationIdDebug
+        attributes 'Version-Name': tablexiaVersionName
     }
 }
 
@@ -39,8 +38,7 @@ task releaseJar(type: Jar) {
     manifest {
         attributes 'Main-Class': project.mainClassName
         attributes 'Build-Type': 'release'
-        attributes 'Version-Name': version
-        attributes 'Application-Id': rootProject.applicationIdRelease
+        attributes 'Version-Name': tablexiaVersionName
     }
 }
 
diff --git a/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java b/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java
index d2fdb15fde3de41e89a53631b93417f7bb96bf33..e9bbd105644580e38b9e1667aa2a04d63f006544 100644
--- a/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java
+++ b/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java
@@ -8,43 +8,49 @@ import com.jcabi.manifests.Manifests;
 import java.util.Locale;
 
 import cz.nic.tablexia.Tablexia;
+import cz.nic.tablexia.TablexiaSettings;
 
 public class DesktopLauncher {
 
-    public static final String BUILD_VARIANT_MANIFEST_ATTRIBUTE     = "Build-Type";
-    public static final String VERSION_NAME_MANIFEST_ATTRIBUTE      = "Version-Name";
-    public static final String APPLICATION_ID_MANIFEST_ATTRIBUTE    = "Application-Id";
+    private static final String BUILD_VARIANT_MANIFEST_ATTRIBUTE     = "Build-Type";
+    private static final String VERSION_NAME_MANIFEST_ATTRIBUTE      = "Version-Name";
 
-    public static final String DESKTOP_ICON_PATH                    = "icon/";
-    public static final String DESKTOP_ICON_16                      = DESKTOP_ICON_PATH + "desktop_icon_16.png";
-    public static final String DESKTOP_ICON_32                      = DESKTOP_ICON_PATH + "desktop_icon_32.png";
-    public static final String DESKTOP_ICON_128                     = DESKTOP_ICON_PATH + "desktop_icon_128.png";
-    public static final String DESKTOP_ICON_DEBUG_16                = DESKTOP_ICON_PATH + "desktop_icon_debug_16.png";
-    public static final String DESKTOP_ICON_DEBUG_32                = DESKTOP_ICON_PATH + "desktop_icon_debug_32.png";
-    public static final String DESKTOP_ICON_DEBUG_128               = DESKTOP_ICON_PATH + "desktop_icon_debug_128.png";
+    private static final String DESKTOP_ICON_PATH                    = "icon/";
+    private static final String DESKTOP_ICON_16                      = DESKTOP_ICON_PATH + "desktop_icon_16.png";
+    private static final String DESKTOP_ICON_32                      = DESKTOP_ICON_PATH + "desktop_icon_32.png";
+    private static final String DESKTOP_ICON_128                     = DESKTOP_ICON_PATH + "desktop_icon_128.png";
+    private static final String DESKTOP_ICON_DEBUG_16                = DESKTOP_ICON_PATH + "desktop_icon_debug_16.png";
+    private static final String DESKTOP_ICON_DEBUG_32                = DESKTOP_ICON_PATH + "desktop_icon_debug_32.png";
+    private static final String DESKTOP_ICON_DEBUG_128               = DESKTOP_ICON_PATH + "desktop_icon_debug_128.png";
+    private static final String DESKTOP_ICON_DEVEL_16                = DESKTOP_ICON_PATH + "desktop_icon_devel_16.png";
+    private static final String DESKTOP_ICON_DEVEL_32                = DESKTOP_ICON_PATH + "desktop_icon_devel_32.png";
+    private static final String DESKTOP_ICON_DEVEL_128               = DESKTOP_ICON_PATH + "desktop_icon_devel_128.png";
 
     public static void main(String[] arg) {
 
         String buildType = loadAttributeFromManifest(BUILD_VARIANT_MANIFEST_ATTRIBUTE);
         String versionName = loadAttributeFromManifest(VERSION_NAME_MANIFEST_ATTRIBUTE);
-        String applicationId = loadAttributeFromManifest(APPLICATION_ID_MANIFEST_ATTRIBUTE);
 
 	    LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
-	    config.resizable = false;
+	    config.resizable = buildType == null || buildType.equals(TablexiaSettings.BuildType.DEVEL.getKey());
 	    config.width = 1280;
 	    config.height = 800;
 
-        if (buildType == null || buildType.equals("debug")) {
+        if (buildType == null || buildType.equals(TablexiaSettings.BuildType.DEVEL.getKey())) {
+            config.addIcon(DESKTOP_ICON_DEVEL_16, Files.FileType.Internal);
+            config.addIcon(DESKTOP_ICON_DEVEL_32, Files.FileType.Internal);
+            config.addIcon(DESKTOP_ICON_DEVEL_128, Files.FileType.Internal);
+        } else if (buildType.equals(TablexiaSettings.BuildType.DEBUG.getKey())) {
             config.addIcon(DESKTOP_ICON_DEBUG_16, Files.FileType.Internal);
             config.addIcon(DESKTOP_ICON_DEBUG_32, Files.FileType.Internal);
             config.addIcon(DESKTOP_ICON_DEBUG_128, Files.FileType.Internal);
-        } else if (buildType.equals("release")) {
+        } else if (buildType.equals(TablexiaSettings.BuildType.RELEASE.getKey())) {
             config.addIcon(DESKTOP_ICON_16, Files.FileType.Internal);
             config.addIcon(DESKTOP_ICON_32, Files.FileType.Internal);
             config.addIcon(DESKTOP_ICON_128, Files.FileType.Internal);
         }
 
-	    new LwjglApplication(new Tablexia(buildType, Locale.getDefault(), versionName, applicationId), config);
+	    new LwjglApplication(new Tablexia(buildType, Locale.getDefault(), versionName, true), config);
     }
 
     private static String loadAttributeFromManifest(String attributeName) {
diff --git a/gradle.properties b/gradle.properties
index fa55fd1e14b8d2fed73f35d83db8fd615562e510..db8bf5542f9905910659f2361eeaaf4a8496bf94 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,3 +1,3 @@
-org.gradle.daemon=true
-org.gradle.jvmargs=-Xms128m -Xmx512m
-org.gradle.configureondemand=true
\ No newline at end of file
+org.gradle.daemon=false
+org.gradle.jvmargs=-Xms256m -Xmx1024m
+org.gradle.configureondemand=true
diff --git a/ios/Info.plist.xml b/ios/Info.plist.xml
index 048a1c631968d02b02e16c136f10b9c3c524d4f5..fbe480ed333133bfb6797a815bda628129f43bd3 100644
--- a/ios/Info.plist.xml
+++ b/ios/Info.plist.xml
@@ -22,6 +22,8 @@
     <string>????</string>
     <key>CFBundleVersion</key>
     <string>${app.build}</string>
+    <key>cz.nic.tablexia.BuildType</key>
+    <string>${app.buildtype}</string>
     <key>LSRequiresIPhoneOS</key>
     <true/>
     <key>UIViewControllerBasedStatusBarAppearance</key>
@@ -49,8 +51,8 @@
         <dict>
             <key>CFBundleIconFiles</key>
             <array>
-                <string>Icon</string>
-                <string>Icon-72</string>
+                <string>${app.icon}</string>
+                <string>${app.icon}-72</string>
             </array>
         </dict>
     </dict>
diff --git a/ios/build.gradle b/ios/build.gradle
index c7d47dbbd283cfb7ee7343007e0e0bce4d7e5e9c..7d2d7ca3aab7aac54e7e53794fa6d8f710360439 100644
--- a/ios/build.gradle
+++ b/ios/build.gradle
@@ -3,10 +3,37 @@ sourceSets.main.java.srcDirs = [ "src/" ]
 sourceCompatibility = '1.7'
 [compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
 
+robovm {
+	ipaArchs = "thumbv7:arm64"
+    iosSkipSigning = false
+}
+
 ext {
 	mainClassName = "cz.nic.tablexia.IOSLauncher"
 }
 
+// Updates or create a robovm.properties file.
+def updateRoboVMProperties(String buildType, String applicationId, String iconName) {
+    Properties props = new Properties()
+    def propsFile = file('robovm.properties')
+
+    if (!propsFile.exists()) {
+        propsFile.createNewFile();
+    }
+
+    props.load(propsFile.newDataInputStream())
+    props.setProperty('app.name', appName)
+    props.setProperty('app.icon', iconName)
+    props.setProperty('app.id', applicationId)
+    props.setProperty('app.mainclass', mainClassName)
+    props.setProperty('app.version', tablexiaVersionName)
+    props.setProperty('app.buildtype', buildType)
+    props.setProperty('app.build', '' + tablexiaVersionCode)
+    props.setProperty('app.executable', appName + '-' + buildType + '-' + tablexiaVersionName)
+
+    props.store(propsFile.newDataOutputStream(), '')
+}
+
 // Extracts native libs (*.a) from the native-ios.jar and places them
 // under build/libs/ios/.
 task copyNatives << {
@@ -49,15 +76,61 @@ task updateRoboVMXML << {
   printer.print(config)
 }
 
+tasks.launchIPadSimulator.doFirst {
+    robovm.iosSignIdentity = TABLEXIA_IOS_SIGNING_IDENTITY
+    updateRoboVMProperties("devel", applicationIdDevel, 'Icon_devel')
+}
+
+tasks.launchIPhoneSimulator.doFirst {
+    robovm.iosSignIdentity = TABLEXIA_IOS_SIGNING_IDENTITY
+    updateRoboVMProperties("devel", applicationIdDevel, 'Icon_devel')
+}
+
+tasks.launchIOSDevice.doFirst {
+    robovm.iosSignIdentity = TABLEXIA_IOS_SIGNING_IDENTITY
+    updateRoboVMProperties("devel", applicationIdDevel, 'Icon_devel')
+}
+
+tasks.create(name: "createDebugIPA", type: org.robovm.gradle.tasks.CreateIPATask) {
+    doFirst {
+    robovm.iosSignIdentity = TABLEXIA_IOS_SIGNING_IDENTITY
+	robovm.iosProvisioningProfile = TABLEXIA_IOS_DEBUG_PROVISIONING
+        updateRoboVMProperties("debug", applicationIdDebug, 'Icon_debug')
+    }
+}
+
+tasks.create(name: "createReleaseIPA", type: org.robovm.gradle.tasks.CreateIPATask) {
+    doFirst {
+    robovm.iosSignIdentity = TABLEXIA_IOS_SIGNING_IDENTITY
+	robovm.iosProvisioningProfile = TABLEXIA_IOS_RELEASE_PROVISIONING
+        updateRoboVMProperties("release", applicationIdRelease, 'Icon_release')
+    }
+}
+
+task createIPAFiles() {
+    dependsOn createDebugIPA
+    dependsOn createReleaseIPA
+}
+
+launchIPadSimulator.dependsOn assemble
+launchIPadSimulator.dependsOn updateRoboVMXML
+launchIPhoneSimulator.dependsOn assemble
+launchIPhoneSimulator.dependsOn updateRoboVMXML
+launchIOSDevice.dependsOn assemble
+launchIOSDevice.dependsOn updateRoboVMXML
+
 updateRoboVMXML.dependsOn copyNatives
-build.dependsOn updateRoboVMXML
+build.dependsOn createDebugIPA
+build.dependsOn createReleaseIPA
 tasks.eclipse.dependsOn updateRoboVMXML
 
-launchIPhoneSimulator.dependsOn build
-launchIPadSimulator.dependsOn build
-launchIOSDevice.dependsOn build
-createIPA.dependsOn build
+//launchIPhoneSimulator.dependsOn build
+//launchIPadSimulator.dependsOn build
+//launchIOSDevice.dependsOn build
+//createIPA.dependsOn build
 
+createDebugIPA.dependsOn updateRoboVMXML
+createReleaseIPA.dependsOn updateRoboVMXML
 
 eclipse.project {
     name = appName + "-ios"
diff --git a/ios/data/Icon-72.png b/ios/data/Icon-72.png
deleted file mode 100644
index d28a5256ca00d606594dd5b0058f5ed42840174c..0000000000000000000000000000000000000000
Binary files a/ios/data/Icon-72.png and /dev/null differ
diff --git a/ios/data/Icon-72@2x.png b/ios/data/Icon-72@2x.png
deleted file mode 100644
index 3fb40ba40e41684704e93d504a06917a656ca3d9..0000000000000000000000000000000000000000
Binary files a/ios/data/Icon-72@2x.png and /dev/null differ
diff --git a/ios/data/Icon.png b/ios/data/Icon.png
deleted file mode 100644
index f9d82ced2018dfbdef51edb90ae19a14cada498f..0000000000000000000000000000000000000000
Binary files a/ios/data/Icon.png and /dev/null differ
diff --git a/ios/data/Icon@2x.png b/ios/data/Icon@2x.png
deleted file mode 100644
index 724ae2382544092422f52a7a8528aa9738d44915..0000000000000000000000000000000000000000
Binary files a/ios/data/Icon@2x.png and /dev/null differ
diff --git a/ios/data/Icon_debug-72.png b/ios/data/Icon_debug-72.png
new file mode 100755
index 0000000000000000000000000000000000000000..2f653df9fcf632a97127e4a10f762f83600e965b
Binary files /dev/null and b/ios/data/Icon_debug-72.png differ
diff --git a/ios/data/Icon_debug-72@2x.png b/ios/data/Icon_debug-72@2x.png
new file mode 100755
index 0000000000000000000000000000000000000000..01d91594bb34e9092d6b826f1c571379ce743d3f
Binary files /dev/null and b/ios/data/Icon_debug-72@2x.png differ
diff --git a/ios/data/Icon_debug.png b/ios/data/Icon_debug.png
new file mode 100755
index 0000000000000000000000000000000000000000..f9593f442a715060e60613d49141f3d83debffec
Binary files /dev/null and b/ios/data/Icon_debug.png differ
diff --git a/ios/data/Icon_debug@2x.png b/ios/data/Icon_debug@2x.png
new file mode 100755
index 0000000000000000000000000000000000000000..a0e4fc9fcb98a33ecad8f3ba12e6cd81c189f2ae
Binary files /dev/null and b/ios/data/Icon_debug@2x.png differ
diff --git a/ios/data/Icon_devel-72.png b/ios/data/Icon_devel-72.png
new file mode 100644
index 0000000000000000000000000000000000000000..9096d0cb3158564b00c17c06f80491e7259061ca
Binary files /dev/null and b/ios/data/Icon_devel-72.png differ
diff --git a/ios/data/Icon_devel-72@2x.png b/ios/data/Icon_devel-72@2x.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe0a8afead262813bc0f12681c495639133c45aa
Binary files /dev/null and b/ios/data/Icon_devel-72@2x.png differ
diff --git a/ios/data/Icon_devel.png b/ios/data/Icon_devel.png
new file mode 100644
index 0000000000000000000000000000000000000000..3797cfc1ee9827f90ee19732edffeec57198bb52
Binary files /dev/null and b/ios/data/Icon_devel.png differ
diff --git a/ios/data/Icon_devel@2x.png b/ios/data/Icon_devel@2x.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa8acd9147e43ed0db69d0144cce3a6a4030533a
Binary files /dev/null and b/ios/data/Icon_devel@2x.png differ
diff --git a/ios/data/Icon_release-72.png b/ios/data/Icon_release-72.png
new file mode 100755
index 0000000000000000000000000000000000000000..44f6830878e0e6fbe21315ef3a91d93ce0af1f1c
Binary files /dev/null and b/ios/data/Icon_release-72.png differ
diff --git a/ios/data/Icon_release-72@2x.png b/ios/data/Icon_release-72@2x.png
new file mode 100755
index 0000000000000000000000000000000000000000..7d21f227cba47cdbcd85a2d53ccca19f6b2a5dea
Binary files /dev/null and b/ios/data/Icon_release-72@2x.png differ
diff --git a/ios/data/Icon_release.png b/ios/data/Icon_release.png
new file mode 100755
index 0000000000000000000000000000000000000000..f99f707a57e68475c838bcc0ad46e32172b3de84
Binary files /dev/null and b/ios/data/Icon_release.png differ
diff --git a/ios/data/Icon_release@2x.png b/ios/data/Icon_release@2x.png
new file mode 100755
index 0000000000000000000000000000000000000000..ba49c295b73efda3cec47d85eafac0996bbc5fd0
Binary files /dev/null and b/ios/data/Icon_release@2x.png differ
diff --git a/ios/src/cz/nic/tablexia/IOSLauncher.java b/ios/src/cz/nic/tablexia/IOSLauncher.java
index 0626c283d6e384472b9ef3267f6020cfdda3ad83..44c0ce49ae506fe40a76054c3a6b2886e73a47b0 100644
--- a/ios/src/cz/nic/tablexia/IOSLauncher.java
+++ b/ios/src/cz/nic/tablexia/IOSLauncher.java
@@ -1,20 +1,27 @@
 package cz.nic.tablexia;
 
-import org.robovm.apple.foundation.NSAutoreleasePool;
-import org.robovm.apple.uikit.UIApplication;
-
 import com.badlogic.gdx.backends.iosrobovm.IOSApplication;
 import com.badlogic.gdx.backends.iosrobovm.IOSApplicationConfiguration;
 
-import java.util.Locale;
+import org.robovm.apple.foundation.NSAutoreleasePool;
+import org.robovm.apple.foundation.NSBundle;
+import org.robovm.apple.foundation.NSDictionary;
+import org.robovm.apple.foundation.NSString;
+import org.robovm.apple.uikit.UIApplication;
 
-import cz.nic.tablexia.Tablexia;
+import java.util.Locale;
 
 public class IOSLauncher extends IOSApplication.Delegate {
     @Override
     protected IOSApplication createApplication() {
         IOSApplicationConfiguration config = new IOSApplicationConfiguration();
-        return new IOSApplication(new Tablexia(null, Locale.getDefault(), null, null), config);
+
+        NSDictionary infoDictionary = NSBundle.getMainBundle().getInfoDictionary();
+        String buildType = infoDictionary.get(new NSString("cz.nic.tablexia.BuildType")).toString();
+        String versionName = infoDictionary.get(new NSString("CFBundleShortVersionString")).toString();
+
+        //TODO check application state
+        return new IOSApplication(new Tablexia(buildType, Locale.getDefault(), versionName, false), config);
     }
 
     public static void main(String[] argv) {