Transform result info view into a panel

Change-Id: I20bb8af6aad0ec425e56b9abcd02a066bc9ad99c
diff --git a/dev/js/src/buttongroup.js b/dev/js/src/buttongroup.js
index 6da1cb7..b782754 100644
--- a/dev/js/src/buttongroup.js
+++ b/dev/js/src/buttongroup.js
@@ -13,7 +13,7 @@
     _init : function (classes) {
       var e = document.createElement('div');
       var cl = e.classList;
-      if (classes !== undefined) {
+      if (classes) {
         cl.add.apply(cl,classes);
       };
       cl.add('button-group');
diff --git a/dev/js/src/init.js b/dev/js/src/init.js
index f2744c7..2380db8 100644
--- a/dev/js/src/init.js
+++ b/dev/js/src/init.js
@@ -21,6 +21,8 @@
   'lib/alertify',
   'session',
   'selectMenu',
+  'panel',
+  'view/koralquery',
   'api',
   'mailToChiffre',
   'lib/highlight/highlight.pack',
@@ -34,7 +36,9 @@
              vcArray,
              alertifyClass,
              sessionClass,
-             selectMenuClass) {
+             selectMenuClass,
+             panelClass,
+             kqClass) {
 
   // Localization values
   const loc = KorAP.Locale;
@@ -63,7 +67,7 @@
   domReady(function (event) {
     var obj = {};
 
-    // What should be visible?
+    // What should be visible in the beginning?
     var show = KorAP.session.get('show') || {};
 
     /**
@@ -180,7 +184,9 @@
       ).limit(5);
     };
 
-    var result = d.getElementById('resultinfo');
+    var resultInfo = d.getElementById('resultinfo');
+
+    /*
     var resultButton;
     if (result != null) {
 
@@ -188,11 +194,31 @@
       resultButton = buttonGroupClass.create(['result']);
       result.appendChild(resultButton.element());
     };
+    */
 
+    /**
+     * Add result panel
+     */
+    var resultPanel;
+    if (resultInfo != null) {
+      resultPanel = panelClass.create(['result']);
+
+      // Move buttons to resultinfo
+      resultInfo.appendChild(resultPanel.actions.element());
+
+      
+      var sb = d.getElementById('search');
+      sb.insertBefore(resultPanel.element(), sb.firstChild);
+
+    };
+
+    
     // There is a koralQuery
-    if (KorAP.koralQuery !== undefined) {
+    if (KorAP.koralQuery !== undefined) {    
+      
+      if (resultInfo !== null) {
 
-      if (result !== null) {
+        /*
         var kq;
 
         var showKQ = function () {
@@ -220,6 +246,18 @@
 
         // Add KoralQuery button
         resultButton.add(loc.SHOW_KQ, ['show-kq','button-icon'], showKQ);
+        */
+
+        resultPanel.actions.add(loc.SHOW_KQ, ['show-kq','button-icon'], function () {
+
+          // Show only once
+          if (this._kq && this._kq.shown()) {
+            return;
+          };
+          
+          this._kq = kqClass.create();
+          this.add(this._kq);
+        });
       };
 
       if (KorAP.koralQuery["errors"]) {
@@ -242,23 +280,33 @@
       };
 
       // Session has KQ visibility stored
+      /**
+       * TODO:
       if (show["kq"])
         showKQ.apply();
+      */
     };
 
     // There is more than 0 matches and there is a resultButton
     if (i > 0) {
 
-      if (resultButton !== null) {
+      if (resultPanel !== null) {
         /**
          * Toggle the alignment (left <=> right)
          */
-
+        /*
         resultButton.add(loc.TOGGLE_ALIGN, ['align','right','button-icon'], function (e) {
           var ol = d.querySelector('#search > ol');
           ol.toggleClass("align-left", "align-right");
           this.toggleClass("left", "right");
         });
+        */
+
+        resultPanel.actions.add(loc.TOGGLE_ALIGN, ['align','right','button-icon'], function (e) {
+          var ol = d.querySelector('#search > ol');
+          ol.toggleClass("align-left", "align-right");
+          this.button.toggleClass("left", "right");
+        });
       };
     };
 
diff --git a/dev/js/src/match.js b/dev/js/src/match.js
index 3576867..3140de1 100644
--- a/dev/js/src/match.js
+++ b/dev/js/src/match.js
@@ -194,7 +194,7 @@
       if (!refLine)
         return;
 
-      var btns = buttonGroupClass.create(['action', 'bottom']);
+      var btns = buttonGroupClass.create(['action', 'bottom','button-panel']);
 
       // Add meta button
       btns.add(
diff --git a/dev/js/src/panel.js b/dev/js/src/panel.js
index 498a7f1..9d7968f 100644
--- a/dev/js/src/panel.js
+++ b/dev/js/src/panel.js
@@ -1,32 +1,40 @@
 /**
  * Create a panel for a certain aspect of the system, like
  * the result, a match, or the VC.
+ *
+ * The buttons are associated with the panel's views,
+ * though they are integrated independently
  */
 define(['buttongroup', 'util'], function (buttonGroupClass) {
 
   return {
-
-    // TODO:
-    //   Support classes
-    create : function (viewpos = 'up') {
-      return Object.create(this)._init(viewpos);
+    create : function (classes) {
+      return Object.create(this)._init(classes);
     },
 
-    _init : function (viewpos) {
+
+    // Override by inheriting object
+    _init : function (classes) {
       this.views = [];
 
-      this._viewpos = viewpos;
-
-      
       /**
        * Main action buttons for the panel,
        * may be at the bottom (for matches)
        * or as tabs (for the result).
        */
-      this.actions = buttonGroupClass.create(['action', 'panel']);
+
+      this._classes = classes;
+      var c = ['action', 'button-panel'];
+      if (classes)
+        c.push.apply(c,classes);
+      this.actions = buttonGroupClass.create(c).bind(this);
+
+      // Warning: This is circular
+      this.actions.panel = this;
       return this;
     },
 
+    
     /**
      * The element of the panel
      */
@@ -36,32 +44,33 @@
 
       // Create panel element
       var e = document.createElement('div');
-      e.classList.add('panel');
+      var cl = e.classList;
+      cl.add('panel');
+   
+      if (this._classes)
+        cl.add.apply(cl, this._classes);
 
-      if (this._viewpos == 'up') {
-        this._viewE = e.addE('div');
-      };
+      this._viewE = e.addE('div');
 
-      e.appendChild(this.actions.element());
-
-      if (this._viewpos == 'down') {
-        this._viewE = e.addE('div');
-      };
+      // Per default the action buttons are below the view
+      // and integrated
+      var aElem = this.actions.element();
+      if (!aElem.parentNode)
+        e.appendChild(aElem);
 
       this._element = e;
       return e;
     },
 
 
-    /**
+    /*
      * The element of the views
      */
-    viewElement : function () {
+    _viewElement : function () {
       this.element();
       return this._viewE;
     },
 
-
     /**
      * Add a view to the panel
      */
@@ -72,7 +81,7 @@
 
       // Append element to panel element
 
-      this.viewElement().appendChild(
+      this._viewElement().appendChild(
         view.element()
       );
 
@@ -89,27 +98,5 @@
         }
       }
     },
-
-    /**
-     * Elements before the action buttons
-     * TODO:
-     *   Maybe rename actionLine?
-     */
-    beforeActions : function (element) {
-      if (arguments.length > 0)
-        this._beforeActions = element;
-
-      return this._beforeActions;
-    },
-
-    /**
-     * Element after the action buttons
-     */
-    afterActions : function (element) {
-      if (arguments.length > 0)
-        this._afterActions = element;
-
-      return this._afterActions;
-    }
   }
 });
diff --git a/dev/js/src/view.js b/dev/js/src/view.js
index 2eb5dd0..4a4dc03 100644
--- a/dev/js/src/view.js
+++ b/dev/js/src/view.js
@@ -6,26 +6,34 @@
 define(['buttongroup', 'util'], function (buttonGroupClass) {
 
   return {
-
-    // TODO:
-    //   Support classes
-    create : function () {
-      return Object.create(this)._init();
+    create : function (classes) {
+      return Object.create(this)._init(classes);
     },
 
-    _init : function () {
-      // ..
+    // Override by inheriting object
+    _init : function (classes) {
       this.panel = undefined;
+      this._classes = classes;
+      this._shown = false;
 
       // The buttonclass is bind to the view
-      this.actions = buttonGroupClass.create(['action', 'view']).bind(this);
+      var c = ['action', 'button-view'];
+      if (classes)
+        c.push.apply(null,classes);
+      
+      this.actions = buttonGroupClass.create(c).bind(this);
+
       this.actions.add('close', ['button-icon','close'], function (e) {
         this.close();
       });
 
+      // Warning: This is circular
+      this.actions.view = this;
+
       return this;
     },
 
+    
     /**
      * Element of the view
      */
@@ -35,7 +43,16 @@
 
       // Create panel element
       var e = document.createElement('div');
-      e.classList.add('view');
+
+      var cl = e.classList;
+      cl.add('view');
+      if (this._classes)
+        cl.add.apply(cl, this._classes);
+
+      if (this.show !== undefined)
+        e.appendChild(this.show());
+
+      this._shown = true;
 
       e.appendChild(this.actions.element());
 
@@ -43,6 +60,14 @@
       return e;
     },
 
+
+    /**
+     * Is the object shown?
+     */
+    shown : function () {
+      return this._shown;
+    },
+    
     /**
      * Close the view.
      */
@@ -50,6 +75,21 @@
       var e = this.element();
       e.parentNode.removeChild(e);
       this.panel.delView(this);
+      this._shown = false;
+    },
+
+
+    /**
+     * Upgrade this object to another object,
+     * while private data stays intact.
+     *
+     * @param {Object] An object with properties.
+     */
+    upgradeTo : function (props) {
+      for (var prop in props) {
+        this[prop] = props[prop];
+      };
+      return this;
     }
   };
 });
diff --git a/dev/js/src/view/koralquery.js b/dev/js/src/view/koralquery.js
new file mode 100644
index 0000000..583b196
--- /dev/null
+++ b/dev/js/src/view/koralquery.js
@@ -0,0 +1,30 @@
+define([
+  'view',
+  'lib/highlight/highlight.pack',
+], function (viewClass) {
+  return {
+    create : function (classes) {
+      return Object.create(viewClass)._init(classes).upgradeTo(this);
+    },
+
+    /**
+     * KoralQuery view element
+     */
+    show : function () {
+      if (this._show)
+        return this._show;
+
+      var kq = document.createElement('div');
+      kq.setAttribute('id', 'koralquery');
+
+      var kqInner = kq.addE('div');
+      kqInner.innerHTML = JSON.stringify(KorAP.koralQuery, null, '  ');
+
+      // Highlight the view
+      hljs.highlightBlock(kqInner);
+
+      this._show = kq;
+      return kq;
+    }
+  }
+});