commit 820ef2f053e431f9b28287a948fcf882af83216e
Author: Kostas Papadimitriou <kpap@grnet.gr>
Date:   Fri Sep 23 16:32:47 2011 +0300

    Create view redesign

diff --git a/db/fixtures/flavors.json b/db/fixtures/flavors.json
index 2588c3b..77c961f 100644
--- a/db/fixtures/flavors.json
+++ b/db/fixtures/flavors.json
@@ -267,5 +267,27 @@
             "ram": 4096,
             "disk": 40
         }
+    },
+
+    {
+        "model": "db.Flavor",
+        "pk": 28,
+        "fields": {
+            "cpu": 2,
+            "ram": 4096,
+            "disk": 10
+        }
+    },
+
+    {
+        "model": "db.Flavor",
+        "pk": 29,
+        "fields": {
+            "cpu": 1,
+            "ram": 1024,
+            "disk": 10
+        }
     }
+
+
 ]
diff --git a/ui/static/main.css b/ui/static/main.css
index 49516f0..cba5447 100644
--- a/ui/static/main.css
+++ b/ui/static/main.css
@@ -1231,7 +1231,7 @@ button.prev:hover {
     margin-top: 4px;
 }
 
-div.image {
+.icon div.image {
     clear: both;
     display: block;
     margin-bottom: 3px;
@@ -4769,30 +4769,6 @@ table.list-machines .wave {
     color: #fff;
 }
 
-#createvm-overlay-content {
-    padding: 0;
-}
-
-.create-vm .header-step.current {
-    font-weight: bold;
-}
-
-.create-vm .create-step-cont {
-    margin: 20px;
-    min-height: 240px;
-}
-.create-vm .create-controls {
-    padding: 10px;
-}
-
-.create-vm ul li {
-    cursor: pointer;
-    padding: 4px;
-}
-
-.create-vm ul li.selected {
-    background-color: #aaa;
-}
 
 .cont-toggler {
     background-image: url("./down-arrow.png");
@@ -4902,3 +4878,353 @@ table.list-machines .wave {
     background-position: center center;
     color: transparent;
 }
+
+#createvm-overlay-content {
+    padding: 0;
+}
+
+.create-vm .image-details.selected .size {
+    color: #eee;
+}
+
+.create-vm .image-details p {
+    font-size: 0.8em;
+    padding-left: 27px;
+    display:block;
+}
+
+.create-vm .image-details .size {
+    margin-top: 2px;
+    font-size: 0.8em;
+    color: #aaa;
+    position: absolute;
+    right:5px;
+    top: 5px;
+}
+
+.create-vm .step-cont {
+    margin: 15px;
+}
+
+.create-vm .create-step-cont {
+    min-height: 250px;
+    float: left;
+    width: 584px;
+}
+
+.create-vm .create-controls {
+    padding: 10px;
+    border-top: 1px solid #ddd;
+}
+
+.create-vm .empty {
+    font-size: 0.8em;
+    color: #444;
+}
+
+.create-vm h4 {
+    color: #5CA1C0;
+    margin-bottom: 0.5em;
+    font-family: arial;
+}
+.create-vm ul li {
+    cursor: pointer;
+    padding: 4px;
+    font-size: 0.9em;
+}
+
+.create-vm ul li.selected {
+    background-color: #5CA1C0;
+    color: #fff;
+}
+
+.create-vm .images-list-cont {
+    width: 40%;
+    float: left;
+    padding-left: 3%;
+    padding-right: 3%;
+}
+
+.create-vm .images-filter-cont, .create-vm .flavors-predefined-cont {
+    width: 18%;
+    padding-right: 4%;
+    float:left;
+    border-right: 1px solid #A1C8DB;
+    overflow: auto;
+}
+
+.create-vm .flavor-options-cont {
+    width: 74%;
+    float: left;
+    margin-left: 20px;
+}
+
+.create-vm .flavor-options-cont .flavor-options li:hover {
+    background-image:-webkit-linear-gradient(top, #E8F4FA, #D1E7F0);
+    background-image:linear-gradient(top, #E8F4FA, #D1E7F0);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#E8F4FA', endColorstr='#D1E7F0', GradientType=0);
+}
+
+.create-vm .flavor-options-cont .flavor-options li.disabled * {
+    color: #eee !important;
+}
+
+.create-vm .flavor-options-cont .flavor-options li.disabled {
+    background-image:linear-gradient(top, #aaa, #ddd);
+    background-image:-webkit-linear-gradient(top, #aaa, #ddd);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#aaaaaa', endColorstr='#dddddd', GradientType=0);
+}
+
+.create-vm .flavor-options-cont .flavor-options li.selected {
+    background-image:linear-gradient(top, #FF9955, #E88B4D);
+    background-image:-webkit-linear-gradient(top, #FF9955, #E88B4D);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF9955', endColorstr='#5CA1C0', GradientType=0);
+    border: 1px solid #C97943;
+}
+
+.create-vm .predefined-list li.disabled {
+    color: #ddd !important;
+}
+
+.create-vm .flavor-options-cont .flavor-options li {
+    display: block;
+    float: left;
+    margin-right: 10px;
+    padding: 10px 15px;
+    border: 1px solid #aaa;
+    background-image:-webkit-linear-gradient(top, #D1E7F0, #E8F4FA);
+    background-image:linear-gradient(top, #D1E7F0, #E8F4FA);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#D1E7F0', endColorstr='#E8F4FA', GradientType=0);
+}
+
+.create-vm .flavor-options-cont .flavor-options {
+    margin-bottom: 25px;
+}
+
+.create-vm .flavor-options .metric {
+    font-size: 0.8em;
+    margin-left: 2px;
+}
+
+.create-vm .flavor-options span.title {
+    color: #444;
+}
+
+.create-vm .flavor-options span.desc {
+    display: block;
+    color: #aaa;
+    font-weight: normal;
+    font-size: 0.8em;
+    float: right;
+    margin-top: 4px;
+}
+
+.create-vm .flavor-options .selected .value {
+    color: #FFF;
+}
+
+.create-vm .flavor-options .value {
+    font-weight: bold;
+    color: #5CA1C0;
+}
+
+.create-vm .flavor-options-cont h4 {
+    border-bottom: 1px solid #A1C8DB;
+    padding-bottom: 5px;
+}
+
+.create-vm .images-info-cont {
+    width: 28%;
+    padding-left: 3%;
+    float: left;
+    border-left: 1px solid #A1C8DB;
+}
+
+.create-vm .images-info-cont h4 {
+    color: #FF9955;
+    margin-bottom: 1em;
+    font-size: 1.2em;
+}
+
+.create-vm .images-info-cont span.title {
+    color: #4085A5;
+    display: block;
+    margin-bottom: 2px;
+    font-size: 0.8em;
+}
+
+.create-vm .type-filter li {
+    font-size: 0.8em;
+    font-weight: bold;
+    padding: 4px;
+    margin-bottom: 0px;
+    
+}
+
+.create-vm .images-list .image-details:hover {
+    background-color: #eee;
+}
+
+.create-vm .images-list .image-details.selected:hover {
+    background-color: #5CA1C0;
+}
+
+.create-vm .images-list .image-details.selected {
+    /*font-weight: bold;*/
+}
+
+.create-vm .images-list .image-details {
+    padding: 6px;
+    margin-bottom:4px;
+    position: relative;
+}
+
+.create-vm .images-list .image-details img {
+    vertical-align: middle;
+    margin-right: 10px;
+}
+
+.create-vm .images-info-cont .image-detail:last-child p {
+    border-bottom: none;
+}
+
+.create-vm .images-info-cont h4 img {
+    vertical-align: middle;
+    margin-right: 7px;
+    margin-bottom: 5px;
+}
+
+.create-vm .images-info-cont .description p {
+    font-size: 0.8em;
+}
+
+.create-vm .images-info-cont p {
+    margin-bottom: 7px;
+    font-size: 0.9em;
+    border-bottom: 1px solid #A1C8DB;
+    padding-bottom: 7px;
+}
+
+.create-vm .step-header {
+    padding: 10px;
+    padding-bottom:0;
+    margin-bottom: 10px;
+    background-color: #A1C8DB;
+    border-bottom: 1px solid #aaa;
+    position: relative;
+}
+
+.create-vm .step-header .header-step .info span.subtitle {
+    font-size: 1.2em;
+    color: #fff;
+    font-weight: bold;
+}
+
+.create-vm .step-header .header-step .info span {
+    float: none;
+    text-align: right;
+}
+
+.create-vm .step-header .header-step .info {
+    position: absolute;
+    right: 15px;
+    top: 20px;
+    font-size: 0.8em;
+}
+
+.create-vm .step-header .header-step span {
+    float: left;
+    display: block;
+}
+
+.create-vm .steps-container {
+    width: 2000em;
+}
+
+.create-vm .step-header .header-step .title {
+    margin-top: 20px;
+    font-size: 1em;
+    margin-left: 10px;
+}
+
+#createvm-overlay-content {
+    width: 584px;
+    overflow: hidden;
+}
+
+.create-vm .step-header .header-step .num {
+    font-size: 4em;
+    margin-bottom: -5px;
+    font-family: 'Ubuntu';
+    font-weight: normal !important;
+}
+
+.create-vm .step-header .header-step {
+    color: #DCEBF1;
+    margin-bottom: -6px;
+    width: 25%;
+    padding-left: 0%;
+    display: block;
+    float: left;
+}
+
+.create-vm .step-header .header-step.current {
+    color: #387693;
+}
+
+.create-vm .image-filters-title {
+    margin-top: 1em;
+    margin-bottom: 0.5em;
+}
+
+.create-vm .create-step-cont span.clear {
+    font-size: 0.8em;
+    font-weight: bold;
+    color: #A1C8DB;
+    display: block;
+}
+
+.create-vm .category-filters li {
+    float:left;
+    display: block;
+    padding: 4px;
+    background-color: #eee;
+    margin-right: 5px;
+    font-size: 0.9em;
+    margin-bottom: 5px;
+}
+
+.create-vm .vm-confirm .rename input {
+    font-size: 1.4em;
+    padding: 1%;
+    width: 93%;
+    padding-left: 30px;
+    background-position: 7px center;
+    background-repeat: no-repeat;
+}
+
+.create-vm .vm-confirm .rename label {
+    display: block;
+}
+
+.create-vm .vm-confirm .confirm-conts {
+    margin-top: 20px;
+}
+
+.create-vm .vm-confirm .confirm-cont {
+    width: 30%;
+    margin-right: 2%;
+    border-right: 1px solid #A1C8DB;
+    float: left;
+}
+
+.create-vm .vm-confirm .confirm-cont. ul li {
+    padding:0;
+    margin:0;
+    margin-bottom: 5px;
+}
+
+.create-vm .vm-confirm .confirm-cont.meta {
+    margin-right:0;
+    border-right: none;
+}
diff --git a/ui/static/snf/js/models.js b/ui/static/snf/js/models.js
index b0ef533..086d527 100644
--- a/ui/static/snf/js/models.js
+++ b/ui/static/snf/js/models.js
@@ -128,7 +128,11 @@
         path: 'images',
 
         get_size: function() {
-            return this.get('metadata') ? this.get('metadata').values.size : undefined;
+            return parseInt(this.get('metadata') ? this.get('metadata').values.size : -1)
+        },
+
+        get_os: function() {
+            return this.get("OS");
         }
     });
 
@@ -138,7 +142,12 @@
 
         details_string: function() {
             return "{0} CPU, {1}MB, {2}GB".format(this.get('cpu'), this.get('ram'), this.get('disk'));
-        }
+        },
+
+        get_disk_size: function() {
+            return parseInt(this.get("disk") * 1000)
+        },
+
     });
     
     //network vms list helper
@@ -1039,11 +1048,6 @@
 
         parse: function (resp, xhr) {
             // FIXME: depricated global var
-            window.networks = resp.networks ? resp.networks.values : {}; 
-            if (window.update_networks_view) {
-                update_networks_view(undefined, resp);
-            }
-
             if (!resp) { return []};
                
             var data = _.map(resp.networks.values, _.bind(this.parse_net_api_data, this));
@@ -1085,7 +1089,6 @@
 
         parse: function (resp, xhr) {
             // FIXME: depricated global var
-            window.images = resp.images.values;
             var data = _.map(resp.images.values, _.bind(this.parse_meta, this));
             return resp.images.values;
         },
@@ -1131,44 +1134,53 @@
 
         parse: function (resp, xhr) {
             // FIXME: depricated global var
-            window.flavors = resp.flavors.values;
             return resp.flavors.values;
         },
 
-        for_image: function(img) {
-            var size = parseInt(img.get("size"));
-            return _.select(this.active(), function(el) {
-                return parseInt(parseInt(el.get("disk")) * 1000) >= size;
-            })
+        unavailable_values_for_image: function(img, flavors) {
+            var flavors = flavors || this.active();
+            var size = img.get_size();
+            
+            var index = {cpu:[], disk:[], ram:[]};
+
+            _.each(this.active(), function(el) {
+                var img_size = size;
+                var flv_size = el.get_disk_size();
+                if (flv_size < img_size) {
+                    if (index.disk.indexOf(flv_size) == -1) {
+                        index.disk.push(flv_size);
+                    }
+                };
+            });
+            
+            return index;
         },
-        
+
         get_flavor: function(cpu, mem, disk, filter_list) {
             if (!filter_list) { filter_list = this.models };
             return this.select(function(flv){
                 if (flv.get("cpu") == cpu + "" &&
                    flv.get("ram") == mem + "" &&
                    flv.get("disk") == disk + "" &&
-                   filter_list.indexOf(flv) > -1)
-                {
-                    return true;
-                }
+                   filter_list.indexOf(flv) > -1) { return true; }
             })[0]
         },
-
+        
         get_data: function(lst) {
             var data = {'cpu': [], 'mem':[], 'disk':[]};
+
             _.each(lst, function(flv) {
-                if (data.cpu.indexOf(flv.cpu) == -1) {
-                    data.cpu[data.cpu.length] = flv.cpu;
+                if (data.cpu.indexOf(flv.get("cpu")) == -1) {
+                    data.cpu.push(flv.get("cpu"));
                 }
-                if (data.cpu.indexOf(flv.mem) == -1) {
-                    data.mem[data.mem.length] = flv.mem;
+                if (data.mem.indexOf(flv.get("ram")) == -1) {
+                    data.mem.push(flv.get("ram"));
                 }
-                if (data.disk.indexOf(flv.disk) == -1) {
-                    data.disk[data.disk.length] = flv.disk;
+                if (data.disk.indexOf(flv.get("disk")) == -1) {
+                    data.disk.push(flv.get("disk"));
                 }
             })
-
+            
             return data;
         },
 
@@ -1187,17 +1199,8 @@
         parse: function (resp, xhr) {
             // FIXME: depricated after refactoring
             var data = resp;
-            if (data && data.servers && data.servers.values.length > 0) {
-                if (window.update_servers_data) {
-                    update_servers_data(data.servers.values, data)
-                }
-                if (window.update_machines_view) {
-                    update_machines_view(data);
-                    //update_network_names(data);
-                }
-            }
             if (!resp) { return [] };
-            data = _.map(resp.servers.values, _.bind(this.parse_vm_api_data, this));
+            data = _.filter(_.map(resp.servers.values, _.bind(this.parse_vm_api_data, this)), function(v){return v});
             return data;
         },
         
@@ -1224,6 +1227,15 @@
         },
 
         parse_vm_api_data: function(data) {
+
+            // do not add non existing DELETED entries
+            if (data.status && data.status == "DELETED") {
+                if (!this.get(data.id)) {
+                    console.error("non exising deleted vm", data)
+                    return false;
+                }
+            }
+
             // OS attribute
             if (this.has_meta(data)) {
                 data['OS'] = data.metadata.values.OS || "undefined";
diff --git a/ui/static/snf/js/ui/web/ui_create_view.js b/ui/static/snf/js/ui/web/ui_create_view.js
index 1fde0f4..dbcb02f 100644
--- a/ui/static/snf/js/ui/web/ui_create_view.js
+++ b/ui/static/snf/js/ui/web/ui_create_view.js
@@ -64,7 +64,7 @@
         initialize: function(view) {
             this.parent = view;
             this.el = view.$("div.create-step-cont.step-" + this.step);
-            this.header = view.$(".subheader .step-" + this.step);
+            this.header = this.$(".step-header .step-" + this.step);
             this.view_id = "create_step_" + this.step;
 
             views.CreateVMStepView.__super__.initialize.apply(this);
@@ -74,6 +74,7 @@
             // show current
             this.el.show();
             this.header.addClass("current");
+            this.header.show();
             this.update_layout();
         },
 
@@ -86,46 +87,166 @@
         initialize: function() {
             views.CreateImageSelectView.__super__.initialize.apply(this, arguments);
 
-            this.predefined = this.$(".predefined-images ul");
-            this.custom = this.$(".predefined-images ul");
-            this.selected_image = undefined;
-            this.reset_images();
+            // elements
+            this.images_list = this.$(".images-list-cont ul");
+            this.image_details = this.$(".images-info-cont");
+            this.image_details_desc = this.$(".images-info-cont .description p");
+            this.image_details_title = this.$(".images-info-cont h4");
+            this.image_details_size = this.$(".images-info-cont .size p");
+            this.image_details_os = this.$(".images-info-cont .os p");
+            this.image_details_kernel = this.$(".images-info-cont .kernel p");
+            this.image_details_gui = this.$(".images-info-cont .gui p");
+
+            this.types = this.$(".type-filter li");
+            this.categories_list = this.$(".category-filters");
+
+            // params initialization
+            this.type_selections = ["system", "custom"]
+            this.selected_type = "system";
+            this.selected_categories = [];
+            this.images = [];
+
+            // update
+            this.update_images();
+
+            // handlers initialization
+            this.init_handlers();
+            this.init_position();
+        },
+
+        init_position: function() {
+            //this.el.css({position: "absolute"});
+            //this.el.css({top:"10px"})
+        },
+        
+        init_handlers: function() {
+            var self = this;
+            this.types.live("click", function() {
+                self.select_type($(this).attr("id").replace("type-select-",""));
+            })
+        },
+
+        update_images: function() {
+            this.images = storage.images.active();
+            this.images_ids = _.map(this.images, function(img){return img.id});
+            if (this.selected_type == "custom") { this.images = []; this.images_ids = []; }
+
+            return this.images;
         },
 
         update_layout: function() {
+            this.select_type(this.selected_type);
+        },
+        
+        get_categories: function(images) {
+            return [];
+            return ["Desktop", "Server", "Linux", "Windows"];
+        },
+
+        reset_categories: function() {
+            var categories = this.get_categories(this.images);
+            this.categories_list.find("li").remove();
+
+            _.each(categories, _.bind(function(cat) {
+                var el = $("<li />");
+                el.text(cat);
+                this.categories_list.append(el);
+            }, this));
+
+            if (!categories.length) { 
+                this.categories_list.parent().find(".clear").hide();
+                this.categories_list.parent().find(".empty").show();
+            } else {
+                this.categories_list.parent().find(".clear").show();
+                this.categories_list.parent().find(".empty").hide();
+            }
+        },
+        
+        select_type: function(type) {
+            this.selected_type = type;
+            this.types.removeClass("selected");
+            this.types.filter("#type-select-" + this.selected_type).addClass("selected");
+
+            this.reset_categories();
+            this.update_images();
+            this.reset_images();
+            this.select_image();
         },
 
         select_image: function(image) {
-            if (!image) {
-                image = storage.images.at(0);
+            if (!image && this.images_ids.length) {
+                if (this.selected_image && this.images_ids.indexOf(this.selected_image.id) > -1) {
+                    image = this.selected_image;
+                } else {
+                    image = storage.images.get(this.images_ids[0]);
+                }
             }
 
+            if (!this.images_ids.length) { image = this.selected_image || undefined };
+            
             this.selected_image = image;
-            this.trigger("change", this.selected_image);
+            this.trigger("change", image);
             
-            this.predefined.find(".image-details").removeClass("selected");
-            this.predefined.find(".image-details#create-vm-image-" + this.selected_image.id).addClass("selected")
+            if (image) {
+                this.image_details.show();
+                this.images_list.find(".image-details").removeClass("selected");
+                this.images_list.find(".image-details#create-vm-image-" + this.selected_image.id).addClass("selected");
+                
+                this.image_details_desc.text(image.get("description"));
+                
+                var img = snf.ui.helpers.os_icon_tag(image.get("OS"))
+                this.image_details_title.html(img + image.get("name"));
+                this.image_details_os.text(_(image.get("OS")).capitalize());
+                this.image_details_kernel.text(image.get("kernel"));
+
+                var size = util.readablizeBytes(parseInt(image.get("size")) * 1000000);
+                this.image_details_size.text(size);
+                this.image_details_gui.text(image.get("GUI"));
+
+            } else {
+                this.image_details.hide();
+            }
         },
 
         reset_images: function() {
-            this.$(".image-details").remove();
-            _.each(storage.images.active(), _.bind(function(img){
+            this.images_list.find("li").remove();
+            _.each(this.images, _.bind(function(img){
                 this.add_image(img);
             }, this))
+            
+            if (this.images.length) {
+                this.images_list.parent().find(".empty").hide();
+            } else {
+                this.images_list.parent().find(".empty").show();
+            }
 
             this.select_image();
             
             var self = this;
-            this.predefined.find(".image-details").click(function(){
+            this.images_list.find(".image-details").click(function(){
                 self.select_image($(this).data("image"));
-            })
+            });
+            
+            util.equalHeights(this.$(".images-filter-cont"), this.$(".images-list-cont"), this.$(".images-info-cont"));
+        },
+
+        show: function() {
+            views.CreateImageSelectView.__super__.show.apply(this, arguments);
+            util.equalHeights(this.$(".images-filter-cont"), this.$(".images-list-cont"), this.$(".images-info-cont"));
         },
 
         add_image: function(img) {
-            var image = $('<li id="create-vm-image-{1}" class="image-details">{0}</li>'.format(img.get("name"), img.id));
+            var image = $(('<li id="create-vm-image-{1}"' +
+                           'class="image-details clearfix">{2}{0}' +
+                           '<p>{4}</p><span class="size">{3}' +
+                           '</span></li>').format(img.get("name"), 
+                                                  img.id, 
+                                                  snf.ui.helpers.os_icon_tag(img.get("OS")),
+                                                  util.readablizeBytes(parseInt(img.get("size"))*1000000),
+                                                  util.truncate(img.get("description"),35)));
             image.data("image", img);
             image.data("image_id", img.id);
-            this.predefined.append(image);
+            this.images_list.append(image);
         },
 
         reset: function() {
@@ -144,16 +265,18 @@
             views.CreateFlavorSelectView.__super__.initialize.apply(this, arguments);
             this.parent.bind("image:change", _.bind(this.handle_image_change, this));
 
-            this.cpus = this.$(".flavors-cpu-list")
-            this.disks = this.$(".flavors-disk-list")
-            this.mems = this.$(".flavors-mem-list")
+            this.cpus = this.$(".flavors-cpu-list");
+            this.disks = this.$(".flavors-disk-list");
+            this.mems = this.$(".flavors-mem-list");
 
-            this.reset();
-            this.update_layout();
+            this.predefined_flavors = SUGGESTED_FLAVORS;
+            this.predefined = this.$(".predefined-list");
+            this.update_predefined_flavors();
         },
 
         handle_image_change: function(data) {
             this.current_image = data;
+            this.update_valid_predefined();
             this.update_flavors_data();
             this.reset_flavors();
             this.update_layout();
@@ -164,23 +287,137 @@
             this.create_flavors();
         },
 
+        update_predefined_flavors: function() {
+            this.predefined.find("li").remove();
+            _.each(this.predefined_flavors, _.bind(function(val, key) {
+                var el = $(('<li class="predefined-selection" id="predefined-flavor-{0}">' +
+                           '{1}</li>').format(key, key));
+
+                this.predefined.append(el);
+                el.data({flavor: storage.flavors.get_flavor(val.cpu, val.ram, val.disk, this.flavors)})
+                el.click(_.bind(function() {
+                    this.handle_predefined_click(el);
+                }, this))
+            }, this));
+            this.update_valid_predefined();
+        },
+
+        handle_predefined_click: function(el) {
+            if (el.hasClass("disabled")) { return };
+            this.set_current(el.data("flavor"))
+        },
+
+        update_valid_predefined: function() {
+            this.update_unavailable_values();
+            var self = this;
+            this.valid_predefined = _.select(_.map(this.predefined_flavors, function(flv, key){
+                var existing = storage.flavors.get_flavor(flv.cpu, flv.ram, flv.disk, self.flavors);
+                // non existing
+                if (!existing) {
+                    return false;
+                }
+                
+                // not available for image
+                if (self.unavailable_values && self.unavailable_values.disk.indexOf(existing.get_disk_size()) > -1) {
+                    return false
+                }
+
+                return key;
+            }), function(ret) { return ret });
+            
+            $("li.predefined-selection").addClass("disabled");
+            _.each(this.valid_predefined, function(key) {
+                $("#predefined-flavor-" + key).removeClass("disabled");
+            })
+        },
+
+        update_selected_predefined: function() {
+            var self = this;
+            this.predefined.find("li").removeClass("selected");
+
+            _.each(this.valid_predefined, function(key){
+                var flv = self.predefined_flavors[key];
+                var exists = storage.flavors.get_flavor(flv.cpu, flv.ram, flv.disk, self.flavors);
+
+                if (exists && (exists.id == self.current_flavor.id)) {
+                    $("#predefined-flavor-" + key).addClass("selected");
+                }
+            })
+        },
+        
         update_flavors_data: function() {
-            this.flavors = storage.flavors.for_image(this.current_image);
+            this.flavors = storage.flavors.active();
             this.flavors_data = storage.flavors.get_data(this.flavors);
-
-            if (this.flavors.indexOf(this.current_flavor) == -1) {
-                this.set_current(this.flavors[0]);
+            
+            var self = this;
+            var set = false;
+            
+            // FIXME: validate current flavor
+            
+            if (!this.current_flavor) {
+                _.each(this.valid_predefined, function(key) {
+                    var flv = self.predefined_flavors[key];
+                    var exists = storage.flavors.get_flavor(flv.cpu, flv.ram, flv.disk, self.flavors);
+                    if (exists && !set) {
+                        self.set_current(exists);
+                        set = true;
+                    }
+                })
             }
+
+            this.update_unavailable_values();
         },
 
+        update_unavailable_values: function() {
+            if (!this.current_image) { this.unavailable_values = {disk:[], ram:[], cpu:[]}; return };
+            this.unavailable_values = storage.flavors.unavailable_values_for_image(this.current_image);
+        },
+        
+        flavor_is_valid: function(flv) {
+            if (!flv) { return false };
+            var existing = storage.flavors.get_flavor(flv.get("cpu"), flv.get("ram"), flv.get("disk"), this.flavors);
+            if (!existing) { return false };
+            if (this.unavailable_values && this.unavailable_values.disk.indexOf(flv.get("disk") > -1)) {
+                return false
+            }
+            return true;
+        },
+            
         set_current: function(flv) {
+            //console.log(flv);
+            //if (!this.flavor_is_valid(flv)) { flv = undefined };
+            
+            console.log(flv);
             this.current_flavor = flv;
             this.trigger("change");
             this.update_selected_flavor();
+            this.update_selected_predefined();
+        },
+        
+        select_default_flavor: function() {
+               
+        },
+
+        update_selected_from_ui: function() {
+            this.set_current(this.ui_selected());
+        },
+        
+        update_disabled_flavors: function() {
+            this.$(".flavor-options.disk li").removeClass("disabled");
+            if (!this.unavailable_values) { return }
+
+            this.$(".flavor-options.disk li").each(_.bind(function(i, el){
+                var el_value = $(el).data("value") * 1000;
+                if (this.unavailable_values.disk.indexOf(el_value) > -1) {
+                    $(el).addClass("disabled");
+                };
+            }, this));
         },
 
         create_flavors: function() {
-            var flavors = this.get_flavors();
+            var flavors = this.get_active_flavors();
+            var valid_flavors = this.get_valid_flavors();
+
             _.each(flavors, _.bind(function(flv){
                 this.add_flavor(flv);
             }, this));
@@ -188,54 +425,79 @@
             var self = this;
             this.$(".flavor-options li.option").click(function(){
                 var el = $(this);
+
+                if (el.hasClass("disabled")) { return }
+
                 el.parent().find(".option").removeClass("selected");
                 el.addClass("selected");
+                
+                if (el.hasClass("mem")) { this.last_choice = "mem" }
+                if (el.hasClass("cpu")) { this.last_choice = "cpu" }
+                if (el.hasClass("disk")) { this.last_choice = "disk" }
+
                 self.update_selected_from_ui();
             })
         },
         
         ui_selected: function() {
-            args = [this.$(".option.cpu.selected").data("value"), 
+            var args = [this.$(".option.cpu.selected").data("value"), 
                 this.$(".option.mem.selected").data("value"), 
                 this.$(".option.disk.selected").data("value"),
             this.flavors];
 
-            storage.flavors.apply(storage.flavors, args)
+            var flv = storage.flavors.get_flavor.apply(storage.flavors, args);
+            return flv;
         },
 
         update_selected_flavor: function() {
+            var flv = this.current_flavor;
+            this.$(".option").removeClass("selected");
 
+            this.$(".option.cpu.value-" + flv.get("cpu")).addClass("selected");
+            this.$(".option.mem.value-" + flv.get("ram")).addClass("selected");
+            this.$(".option.disk.value-" + flv.get("disk")).addClass("selected");
         },
 
         add_flavor: function(flv) {
             var values = {'cpu': flv.get('cpu'), 'mem': flv.get('ram'), 'disk': flv.get('disk')};
-            
+
+            disabled = "";
+
             if (this.$('li.option.cpu.value-{0}'.format(values.cpu)).length == 0) {
-                var cpu = $('<li class="option cpu value-{0}">{0}</li>'.format(values.cpu)).data('value', values.cpu);
+                var cpu = $(('<li class="option cpu value-{0} {1}">' + 
+                             '<span class="value">{0}</span>' + 
+                             '<span class="metric">x</span></li>').format(values.cpu, disabled)).data('value', values.cpu);
+
                 this.cpus.append(cpu);
             }
             if (this.$('li.option.mem.value-{0}'.format(values.mem)).length == 0) {
-                var mem = $('<li class="option mem value-{0}">{0}</li>'.format(values.mem)).data('value', values.mem);
+                var mem = $(('<li class="option mem value-{0}">' + 
+                             '<span class="value">{0}</span>' + 
+                             '<span class="metric">MB</span></li>').format(values.mem)).data('value', values.mem);
+
                 this.mems.append(mem);
             }
             if (this.$('li.option.disk.value-{0}'.format(values.disk)).length == 0) {
-                var disk = $('<li class="option disk value-{0}">{0}</li>'.format(values.disk)).data('value', values.disk);
+                var disk = $(('<li class="option disk value-{0}">' + 
+                              '<span class="value">{0}</span>' + 
+                              '<span class="metric">GB</span></li>').format(values.disk)).data('value', values.disk);
+
                 this.disks.append(disk);
             }
             
         },
+        
+        get_active_flavors: function() {
+            return storage.flavors.active();
+        },
 
-        get_flavors: function() {
+        get_valid_flavors: function() {
             return this.flavors;
         },
 
         update_layout: function() {
-            var flv = this.current_flavor;
-            this.$(".option.value").removeClass("selected");
-
-            this.$(".option.cpu.value-" + flv.get("cpu")).addClass("selected");
-            this.$(".option.mem.value-" + flv.get("ram")).addClass("selected");
-            this.$(".option.disk.value-" + flv.get("disk")).addClass("selected");
+            this.update_selected_flavor();
+            this.update_disabled_flavors();
         },
 
         reset: function() {
@@ -263,8 +525,9 @@
         },
 
         init_handlers: function() {
-            this.name.bind("keypress", _.bind(function() {
+            this.name.bind("keypress", _.bind(function(e) {
                 this.name_changed = true;
+                if (e.keyCode == 13) { this.parent.submit() };    
             }, this));
 
             this.name.bind("click", _.bind(function() {
@@ -278,22 +541,36 @@
             views.CreateSubmitView.__super__.show.apply(this, arguments);
             this.update_layout();
         },
+        
+        update_image_details: function() {
+            var image = this.parent.get_params().image;
+
+            function set_img_detail(sel, key) {
+                if (!key) { key = image.get(key) };
+                this.$(".confirm-cont.image .image-" + sel + " .value").text(key)
+            }
+            
+            set_img_detail("description");
+            set_img_detail("name");
+            set_img_detail("os", image.get("OS"));
+        },
 
         update_layout: function() {
             var params = this.parent.get_params();
+
+            if (!params.image) { return }
             var vm_name = "My {0} server".format(params.image.get("name"));
             var orig_name = vm_name;
             
             var existing = true;
             var j = 0;
-            while (existing) {
+            while (existing && !this.name_changed) {
                 var existing = storage.vms.select(function(vm){return vm.get("name") == vm_name}).length
                 if (existing) {
                     j++;
                     vm_name = orig_name + " " + j;
                 }
             }
-
             if (!_(this.name.val()).trim() || !this.name_changed) {
                 this.name.val(vm_name);
             }
@@ -302,9 +579,19 @@
             this.confirm.find("li.cpu .value").text(params.flavor.get("cpu"));
             this.confirm.find("li.mem .value").text(params.flavor.get("ram"));
             this.confirm.find("li.disk .value").text(params.flavor.get("disk"));
+
+            if (!this.name_changed) {
+                this.name.select().focus();
+            }
+            
+            var img = snf.ui.helpers.os_icon_path(params.image.get("OS"))
+            this.name.css({backgroundImage:"url({0})".format(img)})
+
+            this.update_image_details();
         },
 
         reset: function() {
+            this.name_changed = false;
             this.update_layout();
         },
 
@@ -375,12 +662,15 @@
         },
 
         submit: function() {
+            if (this.submiting) { return };
             var data = this.get_params();
             if (this.validate(data)) {
                 this.submit_btn.addClass("in-progress");
+                this.submiting = true;
                 storage.vms.create(data.name, data.image, data.flavor, {}, {}, _.bind(function(data){
                     this.close_all();
-                    this.password_view.show(data.server.adminPass);
+                    this.password_view.show(data.server.adminPass, data.server.id);
+                    this.submiting = false;
                 }, this));
             }
         },
@@ -409,8 +699,10 @@
         },
 
         beforeOpen: function() {
+            this.submiting = false;
             this.reset();
             this.current_step = 1;
+            this.$(".steps-container").css({"margin-left":0 + "px"});
             this.show_step(1);
         },
 
@@ -423,13 +715,15 @@
             }
                 
             // hide other
-            this.$(".subheader .header-step").removeClass("current");
-            this.$(".create-step-cont").hide();
+            //this.$(".step-header .header-step").removeClass("current").hide();
+            //this.$(".create-step-cont").hide();
+            var width = this.el.find('.container').width();
+            var left = (step -1) * width * -1;
+            this.$(".steps-container").css({"margin-left":left + "px"});
             
             this.steps[step].show();
             this.current_step = step;
             this.current_view = this.steps[step];
-            //
             this.update_controls();
         },
 
diff --git a/ui/static/snf/js/utils.js b/ui/static/snf/js/utils.js
index aa791f9..65694b5 100644
--- a/ui/static/snf/js/utils.js
+++ b/ui/static/snf/js/utils.js
@@ -131,6 +131,13 @@
         return uri;
     }
 
+    synnefo.util.equalHeights = function() {
+        var max_height = 0;
+        var selectors = _.toArray(arguments);
+
+        // TODO: implement me
+    }
+
     synnefo.util.truncate = function(string, size, append, words) {
         if (string.length <= size) {
             return string;
@@ -224,6 +231,23 @@
         } catch (err) {}
         return "";
     },
+    
+    synnefo.util.array_combinations = function(arr) {
+        if (arr.length == 1) {
+            return arr[0];
+        } else {
+            var result = [];
+
+            // recur with the rest of array
+            var allCasesOfRest = synnefo.util.array_combinations(arr.slice(1));  
+            for (var i = 0; i < allCasesOfRest.length; i++) {
+                for (var j = 0; j < arr[0].length; j++) {
+                    result.push(arr[0][j] + "-" + allCasesOfRest[i]);
+                }
+            }
+            return result;
+        }
+    }
 
     synnefo.util.parse_api_error = function(arguments) {
         arguments = arguments[0];
diff --git a/ui/templates/partials/create_vm.html b/ui/templates/partials/create_vm.html
index c9086e0..12a8dbe 100644
--- a/ui/templates/partials/create_vm.html
+++ b/ui/templates/partials/create_vm.html
@@ -1,66 +1,200 @@
 {% load i18n %}
-<div id="createvm-overlay-content" class="hidden vm-meta create-vm">
-    <div class="subheader">
-        <span class="header-step step-1">1 <span>{% trans "Image" %}</span></span>
-        <span class="header-step step-2">2 <span>{% trans "Flavor" %}</span></span>
-        <span class="header-step step-3">3 <span>{% trans "Name" %}</span></span>
-        </div>
-
-        <div class="steps-containter">
-            <div class="step-1 select-image create-step-cont">
-                <div class="predefined-images">
-                    <ul class="images-list">
-                    </ul>
+<div id="createvm-overlay-content" class="hidden create-vm">
+    <div class="steps-container clearfix">
+        <div class="step-1 select-image create-step-cont clearfix">
+            <div class="clearfix step-header">
+                <span class="header-step step-1 clearfix">
+                    <span class="num">1/3</span>
+                    <span class="title">
+                        {% trans "Image" %}
+                    </span>
+                    <div class="info">
+                        <span class="subtitle">
+                            {% trans "Select an OS" %}
+                        </span>
+                        <span class="description">
+                            {% trans "Choose your preferred image" %}
+                        </span>
+                    </div>
+                </span>
+            </div>
+            <div class="step-cont clearfix">
+                <div class="images-filter-cont">
+                    <div class="images-filters">
+                        <div class="image-types-cont">
+                            <h4>Image type</h4>
+                            <ul class="type-filter">
+                                <li id="type-select-system">System</li>
+                                <li id="type-select-custom">Custom</li>
+                            </ul>
+                        </div>
+                        <div class="categories-filters-cont">
+                            <h4 class="image-filters-title">Categories </h4>
+                            <ul class="category-filters clearfix"></ul>
+                            <span class="clear">{% trans "clear categories" %}</span>
+                            <span class="empty">{% trans "no categories available" %}</span>
+                        </div>
+                    </div>
                 </div>
-                <div class="custom-images">
-                    <ul class="images-list">
-                    </ul>
+                <div class="images-list-cont">
+                    <h4>{% trans "Available images" %}</h4>
+                        <ul class="images-list">
+                        </ul>
+                        <span class="empty">{% trans "no images available" %}</span>
                 </div>
-            </div>
-            <div class="step-2 select-flavor create-step-cont">
-                <div class="flavor-options cpu">
-                    <h4>{% trans "cpu" %}</h4>
-                    <ul class="flavors-cpu-list flavor-opts-list">
-                    </ul>
+                <div class="images-info-cont">
+                    <h4>Image title</h4>
+                    <div class="image-detail description">
+                        <span class="title">{% trans "Description" %}</span>
+                        <p></p>
+                    </div>
+                    <div class="image-detail os">
+                        <span class="title">{% trans "OS" %}</span>
+                        <p></p>
+                    </div>
+                    <div class="image-detail size">
+                        <span class="title">{% trans "Size" %}</span>
+                        <p></p>
+                    </div>
+                    <div class="image-detail gui">
+                        <span class="title">{% trans "GUI" %}</span>
+                        <p></p>
+                    </div>
+                    <div class="image-detail kernel">
+                        <span class="title">{% trans "Kernel" %}</span>
+                        <p></p>
+                    </div>
                 </div>
-                <div class="flavor-options mem">
-                    <h4>{% trans "mem" %}</h4>
-                    <ul class="flavors-mem-list flavor-opts-list">
-                    </ul>
+            </div>
+        </div>
+        <div class="step-2 select-flavor create-step-cont">
+            <div class="clearfix step-header">
+                <span class="header-step step-2 clearfix">
+                    <span class="num">2/3</span>
+                    <span class="title">
+                        {% trans "Flavor" %}
+                    </span>
+                    <div class="info">
+                        <span class="subtitle">
+                            {% trans "Select CPUs, RAM and Disk Size" %}
+                        </span>
+                        <span class="description">
+                            {% trans "Available options are filtered based on the selected image" %}
+                        </span>
+                    </div>
+                </span>
+            </div>
+            <div class="step-cont clearfix">
+                <div class="flavors-predefined-cont">
+                    <div class="flavors-predefined">
+                        <h4>{% trans "Predefined" %}</h4>
+                        <ul class="predefined-list">
+                        </ul>
+                    </div>
                 </div>
-                <div class="flavor-options disk">
-                    <h4>{% trans "disk" %}</h4>
-                    <ul class="flavors-disk-list flavor-opts-list">
-                    </ul>
+                <div class="flavor-options-cont">
+                    <div class="flavor-options-inner-cont clearfix">
+                        <div class="flavor-options cpu clearfix">
+                            <h4 class="clearfix"><span class="title">{% trans "CPUs" %}</span>
+                                <span class="desc">{% trans "Choose number of CPU cores" %}</span>
+                            </h4>
+                            <ul class="flavors-cpu-list flavor-opts-list clearfix">
+                            </ul>
+                        </div>
+                        <div class="flavor-options mem clearfix">
+                            <h4 class="clearfix"><span class="title">{% trans "Memory size" %}</span>
+                                <span class="desc">{% trans "Choose memory size" %}</span>
+                            </h4>
+                            <ul class="flavors-mem-list flavor-opts-list clearfix">
+                            </ul>
+                        </div>
+                        <div class="flavor-options disk clearfix">
+                            <h4 class="clearfix"><span class="title">{% trans "Disk size" %}</span>
+                                <span class="desc">{% trans "Choose disk size" %}</span>
+                            </h4>
+                            <ul class="flavors-disk-list flavor-opts-list clearfix">
+                            </ul>
+                        </div>
+                    </div>
                 </div>
             </div>
-            <div class="step-3 select-name create-step-cont">
+        </div>
+        <div class="step-3 vm-confirm create-step-cont">
+            <div class="clearfix step-header">
+                <span class="header-step step-3 clearfix">
+                    <span class="num">3/3</span>
+                    <span class="title">
+                        {% trans "Name" %}
+                    </span>
+                    <div class="info">
+                        <span class="subtitle">
+                            {% trans "Confirm your settings" %}
+                        </span>
+                        <span class="description">
+                            {% trans "Confirm that the options you have selected are correct" %}
+                        </span>
+                    </div>
+                </span>
+            </div>
+            <div class="step-cont clearfix">
                 <div class="rename">
                     <div class="form-field">
-                        <label for="">{% trans "Machine name" %}</label>
-                        <input type="text" name="create-vm-name" />
+                        <h4>
+                            <label for="create-vm-name">{% trans "Machine name" %}</label>
+                        </h4>
+                        <input type="text" name="create-vm-name" id="create-vm-name" />
                     </div>
-                    <div class="confirm-params">
-                        <ul>
-                            <li class="param cpu">
-                                <span class="key">{% trans "Image" %}</span>
-                                <span class="value"></span>
-                            </li>
-                            <li class="param cpu">
-                                <span class="key">{% trans "CPUs" %}</span>
-                                <span class="value"></span>
-                            </li>
-                            <li class="param mem">
-                                <span class="key">{% trans "RAM" %}</span>
-                                <span class="value"></span>
-                            </li>
-                            <li class="param disk">
-                                <span class="key">{% trans "System disk" %}</span>
-                                <span class="value"></span>
-                            </li>
-                        </ul>
+                    
+                    <div class="confirm-conts clearfix">
+                        <div class="confirm-cont image">
+                            <h4>{% trans "Image" %}</h4>
+                            <ul class="confirm-params">
+                                <li class="param image-name">
+                                    <h4 class="value"></h4>
+                                </li>
+                                <li class="param image-description">
+                                    <span class="title">{% trans "Description" %}</span>
+                                    <span class="value"></span>
+                                </li>
+                                <li class="param image-os">
+                                    <span class="title">{% trans "OS" %}</span>
+                                    <span class="value"></span>
+                                </li>
+                                <li class="param image-size">
+                                    <span class="title">{% trans "Size" %}</span>
+                                    <span class="value"></span>
+                                </li>
+                                <li class="param image-gui">
+                                    <span class="title">{% trans "GUI" %}</span>
+                                    <span class="value"></span>
+                                </li>
+                                <li class="param image-kernel">
+                                    <span class="title">{% trans "Kernel" %}</span>
+                                    <span class="value"></span>
+                                </li>
+                            </ul>
+                        </div>
+                        <div class="confirm-cont flavor">
+                            <h4>{% trans "Flavor" %}</h4>
+                            <ul class="confirm-params">
+                                <li class="param cpu">
+                                    <span class="key">{% trans "Image" %}</span>
+                                    <span class="value"></span>
+                                </li>
+                            </ul>
+                        </div>
+                        <div class="confirm-cont meta">
+                            <h4>{% trans "Metadata" %}</h4>
+                            <ul class="confirm-params">
+                                <li class="param cpu">
+                                    <span class="key">{% trans "Image" %}</span>
+                                    <span class="value"></span>
+                                </li>
+                            </ul>
+                        </div>
                     </div>
                 </div>
+            </div>
     </div>
 </div>
 <div class="create-controls clearfix">
