Index: /trunk/common/db/tags.php
===================================================================
--- /trunk/common/db/tags.php	(revision 1144)
+++ /trunk/common/db/tags.php	(working copy)
@@ -5,7 +5,7 @@
 require_once(IA_ROOT_DIR."common/cache.php");
 
 // Get list of all tag names, filtered by type and parent
-function tag_get_all($types = null, $parent = null) {
+function tag_get_all($types = null, $parent = null, $order_by_type = false) {
     $query = "SELECT id, name, type, parent FROM ia_tags";
     $where = array();
     if (!is_null($types)) {
@@ -25,7 +25,10 @@
     if (count($where)) {
         $query .= sprintf(" WHERE %s", implode(" AND ", $where));
     }
-    $query .= " ORDER BY name";
+    // FIXME: Ugly hack
+    if ($order_by_type)
+        $query .= " ORDER BY type, name"; else
+        $query .= " ORDER BY name";
     return db_fetch_all($query);
 }
 
@@ -272,4 +275,9 @@
             db_escape($obj), db_escape($tag_id), db_quote($obj_id));
     db_query($query);
 }
+
+// Get color scheme
+function tag_get_color_scheme($tag) {
+    return $tag["id"] % 6;
+}
 ?>
Index: /trunk/common/db/task.php
===================================================================
--- /trunk/common/db/task.php	(revision 1144)
+++ /trunk/common/db/task.php	(working copy)
@@ -224,6 +224,7 @@
     }
 
     if (count($tag_ids) > 0) {
+        // FIXME: split tags according to type and build where accordingly (type_1_tag OR type_1_tag OR type_1_tag) AND (type_2_tag OR type_2_tag) etc.
         $tag_filter = "AND ".tag_build_where('task', $tag_ids);
     } else {
         $tag_filter = "";
Index: /trunk/www/controllers/task.php
===================================================================
--- /trunk/www/controllers/task.php	(revision 1144)
+++ /trunk/www/controllers/task.php	(working copy)
@@ -411,20 +411,14 @@
         $task['authors'] = task_get_authors($task['task_id']);
     }
 
-    // Fetch the tags and all their parents so they can be displayed
-    // in a tree-like fashion
     if (count($tags) > 0) {
-        while ((
-            $new_tags = array_unique(array_merge($tags, tag_get_parents($tags)))
-        ) != $tags) {
-            $tags = $new_tags;
-        }
-        $tags = tag_build_tree(tag_get_by_ids($tags));
+        $view['title'] = "Rezultatele filtrării";
+    } else {
+        $view['title'] = "Filtrează problemele";
     }
 
-    $view['title'] = "Rezultatele filtrării";
     $view['tasks'] = $tasks;
-    $view['tags'] = $tags;
+    $view['tags'] = tag_get_by_ids($tags);
     execute_view_die('views/task_filter_results.php', $view);
 }
 
Index: /trunk/www/format/format.php
===================================================================
--- /trunk/www/format/format.php	(revision 1144)
+++ /trunk/www/format/format.php	(working copy)
@@ -286,4 +286,18 @@
     return $res;
 }
 
+// Format a checkbox with label
+function format_checkbox($id, $content, $attr = array(), $lb_attr) {
+    log_assert(is_array($attr), '$attr is not an array');
+
+    $check_attr = $attr;
+    $check_attr["type"] = "checkbox";
+    $check_attr["id"] = $id;
+
+    $label_attr = $lb_attr;
+    $label_attr["for"] = $id;
+
+    $html = format_tag("label", format_tag("input", null, $check_attr, false) . " " . $content, $label_attr, false);
+    return $html;
+}
 ?>
Index: /trunk/www/macros/macro_algorithmtags.php
===================================================================
--- /trunk/www/macros/macro_algorithmtags.php	(revision 1144)
+++ /trunk/www/macros/macro_algorithmtags.php	(working copy)
@@ -55,7 +55,7 @@
             $subtags_html[] = '<div class="sub_tag_name">'.$tag_link.'</div>';
         }
 
-        $color_scheme = $tag_id % 6;
+        $color_scheme = tag_get_color_scheme($tag);
         $tag_link = format_link(url_task_search(array($tag_id)), $tag_name, true, array('class' => 'tag_search_anchor'));
         $html_code .= '
         <li style="display: none;" class="tags_list_item">
Index: /trunk/www/macros/macro_tasks.php
===================================================================
--- /trunk/www/macros/macro_tasks.php	(revision 1144)
+++ /trunk/www/macros/macro_tasks.php	(working copy)
@@ -201,7 +201,6 @@
     if ($show_ratings) {
         $column_infos[] = array(
                 'html_title' => 'Dificultate',
-                'title_css_class' => 'new_feature',
                 'css_class' => 'rating',
                 'key' => 'rating',
                 'valform' => 'format_rating_column',
Index: /trunk/www/static/css/screen.css
===================================================================
--- /trunk/www/static/css/screen.css	(revision 1144)
+++ /trunk/www/static/css/screen.css	(working copy)
@@ -752,7 +752,7 @@
 
 .wiki_text_block a.wiki_link_external {
     color: #549DC6;
-	background: transparent url(../images/external.png) no-repeat scroll center right;
+    background: transparent url(../images/external.png) no-repeat scroll center right;
     padding-right: 13px;
 }
 
@@ -1554,7 +1554,7 @@
 
 ul.tag_filters {
     line-height: 1.5em;
-    margin: 0 .5em .5em 2em;
+    margin: 0 .5em .5em 3em;
 }
 
 /* Proper Security UI */
@@ -1571,7 +1571,7 @@
 .new_feature:after {
     color: red;
     font-weight: bold;
-    content: "nou!";
+    content: " nou!";
     font-size: 10px;
     vertical-align: super;
 }
@@ -1585,3 +1585,28 @@
 table.sortable th {
     cursor: pointer;
 }
+
+/* Show pointer cursor on labels */
+label {
+    cursor: pointer;
+}
+
+/* Get rid of bullets in filtering lists */
+.no_bullets {
+    list-style: none;
+}
+
+/* Float task filter columns */
+/* I don't like it... can we, maybe, put the filters on the left of the tasks table?
+
+#filters_container > li {
+    float: left;
+    width: 375px;
+    display: block;
+}
+
+#task_search_form .clear {
+    width: 100%;
+    height: 0px;
+    clear: both;
+}*/
Index: /trunk/www/static/css/sitewide.css
===================================================================
--- /trunk/www/static/css/sitewide.css	(revision 1144)
+++ /trunk/www/static/css/sitewide.css	(working copy)
@@ -289,11 +289,12 @@
     background-color: #DDE;
     -moz-border-radius: 4px;
     -webkit-border-radius: 4px;
-    font-size: 11px;
+    font-size: 12px;
     padding-top: 0.2em;
     padding-bottom: 0.2em;
     padding-right: 0.3em;
     padding-left: 0.3em;
+    line-height: 1.8em;
 }
 
 .tag_name {
@@ -302,11 +303,12 @@
     font-weight: bold;
     -moz-border-radius: 5px;
     -webkit-border-radius: 5px;
-    font-size: 10px;
+    font-size: 11px;
     padding-top: 0.2em;
     padding-bottom: 0.2em;
     padding-right: 0.4em;
     padding-left: 0.4em;
+    line-height: 1.8em;
 }
 
 a.sub_tag_search_anchor {
Index: /trunk/www/static/js/taskfilter.js
===================================================================
--- /trunk/www/static/js/taskfilter.js	(revision 0)
+++ /trunk/www/static/js/taskfilter.js	(revision 0)
@@ -0,0 +1,81 @@
+// namespace TaskFilter
+function TaskFilter() {
+	function addEvent ( elem, type, func ) {
+		if (elem.attachEvent) {
+			elem.attachEvent('on'+type, func);
+		} else {
+			elem.addEventListener(type, func, false);
+		}
+	}
+
+	function hide ( elem ) { elem.style.display = 'none'; }
+
+	function show ( elem ) { elem.style.display = 'block'; }
+
+	function toggle ( elem ) {
+		if (elem.style.display == 'none') {
+			show(elem);
+		} else {
+			traverseByTag(elem, 'input', function (elem) {
+					if (elem.checked) {
+						elem.checked = false;
+						toggleChild(elem);
+					}
+				});
+			hide(elem);
+		}
+	}
+
+	function getChild ( elem ) {
+		if (elem.nodeName.toLowerCase() == "input") {
+			return elem.parentNode.parentNode.lastChild;
+		} else {
+			return elem.parentNode.lastChild;
+		}
+	}
+
+	function toggleChild ( elem ) {
+		child = getChild(elem);
+		if (child != elem && child != elem.parentNode)
+			toggle(child);
+	}
+
+	function traverseByTag ( elem, tag, preAction, postAction ) {
+		for (var i = 0; i < elem.children.length; ++i) {
+			if (elem.children[i].nodeName.toLowerCase() == tag.toLowerCase() && typeof(preAction) != 'undefined') {
+				preAction(elem.children[i]);
+			}
+			traverseByTag(elem.children[i], tag, preAction, postAction);
+			if (elem.children[i].nodeName.toLowerCase() == tag.toLowerCase() && typeof(postAction) != 'undefined') {
+				postAction(elem.children[i]);
+			}
+		}
+	}
+
+	function load() {
+		var container = document.getElementById('filters_container');
+		if (container == null) return false;
+		traverseByTag(container, "ul", hide);
+		traverseByTag(container, "span", function ( elem ) {
+				addEvent(elem, 'click', function ( ev ) { toggleChild(ev.target ? ev.target : ev.srcElement); });
+			});
+		traverseByTag(container, "input", function ( elem ) {
+				addEvent(elem, 'click', function ( ev ) { toggleChild(ev.target ? ev.target : ev.srcElement); });
+			});
+		traverseByTag(container, "input", function ( elem ) {
+				if (elem.checked) {
+					show(elem.parentNode.parentNode.parentNode);
+					child = getChild(elem);
+					if (child != elem && child != elem.parentNode)
+						show(child);
+				}
+			});
+		return true;
+	}
+	this.load = load;
+
+	addEvent(window, 'load', this.load);
+};
+
+var myTaskFilter = new TaskFilter();
+
Index: /trunk/www/views/header.php
===================================================================
--- /trunk/www/views/header.php	(revision 1144)
+++ /trunk/www/views/header.php	(working copy)
@@ -72,6 +72,7 @@
     <script type="text/javascript" src="<?= html_escape(url_static('js/foreach.js')) ?>"></script>
     <script type="text/javascript" src="<?= html_escape(url_static('js/sorttable.js')) ?>"></script>
     <script type="text/javascript" src="<?= html_escape(url_static('js/tablednd.js')) ?>"></script>
+    <script type="text/javascript" src="<?= html_escape(url_static('js/taskfilter.js')) ?>"></script>
 
     <script type="text/javascript" src="http://summify.com/client/v1/249f00c6/client.js"></script>
 
Index: /trunk/www/views/task_filter_results.php
===================================================================
--- /trunk/www/views/task_filter_results.php	(revision 1144)
+++ /trunk/www/views/task_filter_results.php	(working copy)
@@ -61,7 +61,21 @@
     }
 }
 
-function tag_print($tags) {
+function tag_in_array ( $field, $search, $array ) {
+    if (is_null($array))
+        return false;
+    foreach ($array as $value) {
+        if ($value[$field] == $search[$field]) {
+            return true;
+        }
+    }
+    return false;
+}
+
+function tag_print_checkboxes($tags, $type = "", $level = 0) {
+    global $view, $color;
+    if ($level == 0) $color = 0;
+
     if (count($tags) == 0) {
         return "";
     }
@@ -76,25 +90,71 @@
         "algorithm" => "Algoritm",
         "tag" => "Tag"
     );
-    $output = '<ul class="tag_filters">';
+
+    if ($level == 0)
+        $output = format_tag("span", $tag_types[$type], array("class" => "tag_name color_scheme_5", "style" => "cursor: pointer; font-size: 12px;")); else
+        $output = "";
+    $output .= '<ul class="tag_filters no_bullets">';
     foreach ($tags as $tag) {
-        $output .= sprintf("<li>%s%s</li>",
-            format_link(url_task_search(array($tag["id"])), sprintf("%s: %s",
-                $tag_types[$tag["type"]], $tag["name"])),
-            tag_print(getattr($tag, "sub_tags", array()))
-        );
+        if ($level > 0 || $tag["type"] == $type) {
+            $check_attr = array("name" => "tag_id[]", "value" => $tag["id"]);
+            if (tag_in_array("id", $tag, $view["tags"])) {
+                $check_attr["checked"] = "checked";
+            }
+
+            if ($level > 0)
+                $text = sprintf("%s: %s", $tag_types[$tag["type"]], $tag["name"]); else
+                $text = $tag["name"];
+
+            if ($tag["parent"] == 0 && $tag["type"] != "author") {
+                $label_attr = array(
+                    "class" => "tag_name color_scheme_" . $color
+                );
+                $color = ($color + 1) % 6;
+            } else {
+                $label_attr = array(
+                    "class" => "sub_tag_name"
+                );
+            }
+            $output .= format_tag("li",
+                format_checkbox("tag_" . $tag["id"], $text, $check_attr, $label_attr) . tag_print_checkboxes(getattr($tag, "sub_tags", array()), $type, $level+1),
+                array(), false);
+        }
     }
     $output .= "</ul>";
     return $output;
 }
 
-echo "<h1>Rezultatele filtrării</h1>";
-echo tag_print($view["tags"]);
+
+echo "<h1>" . $view["title"] . "</h1>";
+echo format_open_tag("form", array("id" => "task_search_form", "name" => "task_search_form", "action" => ""));
+
+$print_types = array(
+    "author",
+    "contest",
+    "age_group",
+    "method"
+);
+
+$all_tags = tag_build_tree(tag_get_all());
+
+$html = "";
+foreach ($print_types as $type) {
+    $html .= "<li>";
+    $html .= tag_print_checkboxes($all_tags, $type);
+    $html .= "</li>";
+}
+
+echo format_tag("ul", $html, array("id" => "filters_container", "class" => "no_bullets"), false);
+//echo format_tag("div", " ", array("class" => "clear"));
+echo format_tag("input", null, array("type" => "submit", "value" => "Filtreaza"));
+echo "</form>";
+
 $tasks = $view['tasks'];
 $options = pager_init_options();
 $options['total_entries'] = count($tasks);
 $options['row_style'] = 'task_row_style';
-$options['css_class'] = 'tasks fill-screen filter_results';
+$options['css_class'] = 'tasks fill-screen filter_results sortable';
 $options['show_count'] = true;
 $options['show_display_entries'] = false;
 
