/**
 * @fileoverview Controls for the Geodetic Velocities visualization.
 *
 * @license Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

var geovelo;
geovelo = geovelo || {};

/**
 * Implements controls for the visualization.
 *
 * @param {Element} containerElement The DOM element into which to insert.
 */
geovelo.Controls = function(containerElement) {

  // Local reference to the geovelo settings object, throw if missing.
  var settings = geovelo.settings;
  if (!settings) {
    throw Error('geovelo.settings is missing!');
  }

  // DOM element into which to insert the controls.
  this.domElement = document.createElement('div');
  if (containerElement) {
    containerElement.appendChild(this.domElement);
  }

  // String that displays the current status of the visualization.
  this.status = 'waiting for data';

  // Percentage progress of the current operation, a number from 0 to 100.
  this.progress = 0;

  // Insert hidden file input for loading local data.
  var loadFileInput = this.loadFileInput = document.createElement('input');
  loadFileInput.style.display = 'none';
  loadFileInput.type = 'file';
  loadFileInput
      .addEventListener('change', this.loadFileChange.bind(this), false);
  this.domElement.appendChild(loadFileInput);

  // Instance of dat.GUI for managing most visualization controls.
  var gui = this.gui = new dat.GUI({
    autoPlace: false,
    width: 300
  });
  gui.add(this, 'status').listen();
  gui.add(this, 'progress', 0, 100).listen();

  // Collection of folders which have been added to the gui.
  var folders = this.folders = {};

  // Add buttons for downloading data and loading a local file.
  var folder = folders.data =
      gui.addFolder(settings.data.displayName || 'data');
  folder.add(this, 'downloadData').name('Download data.');
  folder.add(this, 'loadFile').name('Load local file.');

  // Object holding visualization state based on settings, bucketed by area.
  var state = this.state = {};

  // Build out local state object and gui representation from settings.
  Object.keys(settings).forEach(function(folderName) {
    var folderSettings = settings[folderName];
    var folderState = state[folderName] = {};
    var folder = folders[folderName];
    if (!folder) {
      folder = folders[folderName] =
          gui.addFolder(folderSettings.displayName || folderName);
    }
    if (folderSettings.open) {
      folder.open();
    }

    // Build out a control for each of the folder's options.
    Object.keys(folderSettings.options).forEach(function(optionName) {
      var option = folderSettings.options[optionName];
      folderState[optionName] = option.defaultValue;
      var ctrl = folder.add(folderState, optionName);
      if ('min' in option) {
        ctrl = ctrl.min(option.min);
      }
      if ('max' in option) {
        ctrl = ctrl.max(option.max);
      }
      if ('step' in option) {
        ctrl = ctrl.step(option.step);
      }
      ctrl = ctrl.listen();
      if ('displayName' in option) {
        ctrl = ctrl.name(option.displayName);
      }

      // Fire a custom 'settings-changed' event on the gui's DOM element when
      // a setting changes.
      ctrl.onChange(function(value) {
        var event = new CustomEvent('settings-changed', {
              bubbles: true,
              detail: {
                folderName: folderName,
                optionName: optionName,
                value: value
              }
            });
        gui.domElement.dispatchEvent(event);
      });
    });
  });

  // Finally, attach gui DOM element to the provided container element.
  this.domElement.appendChild(gui.domElement);

};

/**
 * Given a date, compute and set the sampleStart index.
 */
geovelo.Controls.prototype.setSampleStartDate = function(date) {

};

/**
 * On the next tick, parse incoming text as JSON, then proceed to prepare the
 * data as necessary.
 */
geovelo.Controls.prototype.parseText = function(text) {
  this.status = 'parsing data...';
  requestAnimationFrame(function() {
    try {
      var data = JSON.parse(text);
      this.prepareData(data);
    } catch (err) {
      this.status = 'ERROR: Invalid JSON.';
    }
  }.bind(this));
};

/**
 * Once raw data is ready (either downloaded or loaded locally from a file) we
 * need to apply corrections and compute intermediate values (like medians).
 */
geovelo.Controls.prototype.prepareData = function(data) {
  this.status = 'preparing data...';
  requestAnimationFrame(function() {
    geovelo.data.fillBeaconGaps(data);
    this.gui.domElement.dispatchEvent(
        new CustomEvent('data-ready', { bubbles: true, detail: data }));
  }.bind(this));
};

/**
 * Download a data file directly from the server.
 */
geovelo.Controls.prototype.downloadData = function() {

  this.status = 'downloading data...';

  // Update progress bar as download proceeds.
  var startTime = Date.now();
  var xhr = new XMLHttpRequest();
  xhr.addEventListener('progress', function(event) {
    var duration = Date.now() - startTime;
    var rate = event.loaded / duration;
    if (event.lengthComputable) {
      this.progress = 100 * event.loaded / event.total;
    } else {
      var totalGuess = 2e8;  // Assume file size is around 200MB.
      var threshold = 97;  // Maximum progress to show.
      this.progress = Math.min(100 * event.loaded / totalGuess, threshold);
    }
  }.bind(this), false);

  // Handle errors, or abort by the user.
  var handleError = function(event) {
    this.progress = 0;
    this.status = 'ERROR: Download failed.';
  }.bind(this);
  xhr.addEventListener('abort', handleError);
  xhr.addEventListener('error', handleError);

  // When the file is loaded, parse it.
  xhr.addEventListener('load', function(event) {
    this.progress = 100;
    this.parseText(xhr.responseText);
  }.bind(this));

  // Kick off the request.
  xhr.open('GET', 'data/beacon-data.json');
  xhr.send();
};

/**
 * Called when the user clicks the Load button on the controls. Triggers the
 * native file input's chooser dialog via a synthetic click event.
 */
geovelo.Controls.prototype.loadFile = function() {
  var event = document.createEvent('MouseEvents');
  event.initMouseEvent(
      'click', true, true, window,
      0, 0, 0, 0, 0,
      false, false, false, false,
      0, null
  );
  this.loadFileInput.value = null;
  this.loadFileInput.dispatchEvent(event);
};

/**
 * Called when the user has selected a file from the native file chooser for
 * the load file input.
 */
geovelo.Controls.prototype.loadFileChange = function(event) {

  // Get the file.
  var file = event.target.files[0];
  if (file) {
    this.status = 'reading data...';
  } else {
    this.status = 'ERROR: No file chosen.';
    return;
  }

  // Set up a file reader.
  var reader = new FileReader();
  reader.onload = function(event) {
    this.parseText(event.target.result);
  }.bind(this);
  reader.onprogress = function(event) {
    if (event.lengthComputable) {
      this.progress = 100 * event.loaded / event.total;
    }
  }.bind(this);
  reader.readAsText(file);

};
