Transform result info view into a panel

Change-Id: I20bb8af6aad0ec425e56b9abcd02a066bc9ad99c
diff --git a/dev/demo/panel.html b/dev/demo/panel.html
index 0a65a3f..f309cbd 100644
--- a/dev/demo/panel.html
+++ b/dev/demo/panel.html
@@ -18,15 +18,23 @@
 });
 
 
-require(['buttongroup', 'panel','view'], function (btnClass, panelClass, viewClass) {
-  var panel = panelClass.create('up');
+require(['buttongroup', 'panel', 'view/koralquery'], function (btnClass, panelClass, kqClass) {
+  KorAP.koralQuery = {
+    '@type' : "https://beispiel",
+    'key' : 'Cool'
+  };
+
+  var panel = panelClass.create();
   var actions = panel.actions;
+
   actions.add('Meta',['meta'], function () {
     console.log(this.button.classList.contains('meta'));
-    view = viewClass.create();
+    view = kqClass.create();
     panel.add(view);
   });
+
   var list = actions.addList('More', ['list']);
+
   list.readItems([
     ['cool', 'cool', function (e, action) { console.log('really' + this.action()) }],
     ['very cool', 'veryCool', function (e, action) { console.log('very cool') }]
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;
+    }
+  }
+});
diff --git a/dev/scss/main/buttongroup.scss b/dev/scss/main/buttongroup.scss
index acd3094..2f4d750 100644
--- a/dev/scss/main/buttongroup.scss
+++ b/dev/scss/main/buttongroup.scss
@@ -14,36 +14,69 @@
       }
     }
   }
-}
 
-.button-group:not(.view) > span {
-  box-shadow: $choose-box-shadow;
-  font-size: 9pt;
-  line-height: 1.5em;
-  padding: 0 4px;
-  display: inline-block;
-  @include choose-item;
-  border-style: solid;
-  border-width: $border-size 0;
-  &:hover {
-	  @include choose-hover;
+  &.button-panel {
+    > span {
+      box-shadow: $choose-box-shadow;
+      font-size: 9pt;
+      line-height: 1.5em;
+      padding: 0 4px;
+      display: inline-block;
+      @include choose-item;
+      border-style: solid;
+      border-width: $border-size 0;
+      &:hover {
+	      @include choose-hover;
+      }
+      &:first-child {
+	      border: {
+	      left-width: $border-size;
+	      top-left-radius: $standard-border-radius;
+	      bottom-left-radius: $standard-border-radius;
+	    }
+      }
+      &:last-child {
+	      border: {
+	      right-width: $border-size;
+	      top-right-radius: $standard-border-radius;
+	      bottom-right-radius: $standard-border-radius;
+      }
+      }
+    }
   }
-  &:first-child {
-	  border: {
-	    left-width: $border-size;
-	    top-left-radius: $standard-border-radius;
-	    bottom-left-radius: $standard-border-radius;
-	  }
-  }
-  &:last-child {
-	  border: {
-	    right-width: $border-size;
-	    top-right-radius: $standard-border-radius;
-	    bottom-right-radius: $standard-border-radius;
+  &.button-view {
+    display: block;
+    position: absolute;
+    right: 0;
+    top: 0;
+    z-index: 20;
+    margin: 0;
+    padding: 0;
+    width: $right-match-distance;
+    > span:first-child {
+      margin-top: $border-size
+    }
+    > span {
+      display: block;
+      border-width: 0;
+      text-decoration:none;
+      text-align: center;
+      font-style: normal;
+      
+      &.download::after {
+	      font-family: 'FontAwesome';
+	      content: $fa-download;
+      }
+      
+      &.close::after {
+	      font-family: 'FontAwesome';
+	      content: $fa-close;
+      }
     }
   }
 }
- 
+
+
 ul.button-group-list {
   border-top-right-radius: 8px;
   z-index: 150;
@@ -59,29 +92,3 @@
 }
 
 
-.button-group.view {
-  display: block;
-  position: absolute;
-  right: 0;
-  top: 0;
-  z-index: 20;
-  margin: 0;
-  padding: 0;
-  width: $right-match-distance;
-  > span {
-    border-width: 0;
-    text-decoration:none;
-    text-align: center;
-    font-style: normal;
-    
-    &.download::after {
-	    font-family: 'FontAwesome';
-	    content: $fa-download;
-    }
-    
-    &.close::after {
-	    font-family: 'FontAwesome';
-	    content: $fa-close;
-    }
-  }
-}
diff --git a/dev/scss/main/koralquery.scss b/dev/scss/main/koralquery.scss
index 1aec746..6a9550d 100644
--- a/dev/scss/main/koralquery.scss
+++ b/dev/scss/main/koralquery.scss
@@ -4,9 +4,7 @@
 $border-size: 2px;
 
 #koralquery {
-  border: 1px solid $kwic-border;
   white-space: pre;
-  background-color: $dark-orange;
   > div {
     overflow-x: auto;
     font-size: 85%;
diff --git a/dev/scss/main/matchinfo.scss b/dev/scss/main/matchinfo.scss
index 334ac74..212fad0 100644
--- a/dev/scss/main/matchinfo.scss
+++ b/dev/scss/main/matchinfo.scss
@@ -30,6 +30,8 @@
   display: none !important;
 }
 
+// TODO:
+//   This is now a view
 div.matchinfo {
   position: relative;
   width: 100%;
diff --git a/dev/scss/main/panel.scss b/dev/scss/main/panel.scss
index 25d541b..960066d 100644
--- a/dev/scss/main/panel.scss
+++ b/dev/scss/main/panel.scss
@@ -5,22 +5,31 @@
   position: relative;
   width: 100%;
   display: block;
-  padding-top: $border-size;
-  background-color: $dark-orange;
-  border: {
-    style: solid;
-    color: $dark-orange;
-    width: 0;
+  > div {
+    /*
+    border: {
+      style: solid;
+      width: $border-size;
+    }
+    &:empty {
+      border-width: 0;
+    }
+   */
   }
 }
 
 div.view {
   position: relative;
+  padding-top: $border-size;
   display: block;
-  min-height: 40px;
-  background-color: $middle-green;
   width: 100%;
   .button-group {
     color: white;
   }
 }
+
+
+#search div.view {
+  border: 1px solid $kwic-border;
+  background-color: $dark-orange;
+}
\ No newline at end of file
diff --git a/dev/scss/main/resultinfo.scss b/dev/scss/main/resultinfo.scss
index 0ad4fc1..f53de78 100644
--- a/dev/scss/main/resultinfo.scss
+++ b/dev/scss/main/resultinfo.scss
@@ -1,7 +1,6 @@
 @charset "utf-8";
 @import "../util";
 
-$border-size : 1px;
 
 #resultinfo {
   clear: both;
@@ -19,7 +18,8 @@
 }
 
 // Specify result button group layout
-.result.button-group {
+.result.button-group.button-panel {
+  width: auto;
   vertical-align: bottom;
   display: inline-block;
   line-height: 1.3em;