// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.define('media', function() {
  'use strict';

  /**
   * This class represents a file cached by net.
   */
  function CacheEntry() {
    this.read_ = new media.DisjointRangeSet;
    this.written_ = new media.DisjointRangeSet;
    this.available_ = new media.DisjointRangeSet;

    // Set to true when we know the entry is sparse.
    this.sparse = false;
    this.key = null;
    this.size = null;

    // The <details> element representing this CacheEntry.
    this.details_ = document.createElement('details');
    this.details_.className = 'cache-entry';
    this.details_.open = false;

    // The <details> summary line. It contains a chart of requested file ranges
    // and the url if we know it.
    var summary = document.createElement('summary');

    this.summaryText_ = document.createTextNode('');
    summary.appendChild(this.summaryText_);

    summary.appendChild(document.createTextNode(' '));

    // Controls to modify this CacheEntry.
    var controls = document.createElement('span');
    controls.className = 'cache-entry-controls';
    summary.appendChild(controls);
    summary.appendChild(document.createElement('br'));

    // A link to clear recorded data from this CacheEntry.
    var clearControl = document.createElement('a');
    clearControl.href = 'javascript:void(0)';
    clearControl.onclick = this.clear.bind(this);
    clearControl.textContent = '(clear entry)';
    controls.appendChild(clearControl);

    this.details_.appendChild(summary);

    // The canvas for drawing cache writes.
    this.writeCanvas = document.createElement('canvas');
    this.writeCanvas.width = media.BAR_WIDTH;
    this.writeCanvas.height = media.BAR_HEIGHT;
    this.details_.appendChild(this.writeCanvas);

    // The canvas for drawing cache reads.
    this.readCanvas = document.createElement('canvas');
    this.readCanvas.width = media.BAR_WIDTH;
    this.readCanvas.height = media.BAR_HEIGHT;
    this.details_.appendChild(this.readCanvas);

    // A tabular representation of the data in the above canvas.
    this.detailTable_ = document.createElement('table');
    this.detailTable_.className = 'cache-table';
    this.details_.appendChild(this.detailTable_);
  }

  CacheEntry.prototype = {
    /**
     * Mark a range of bytes as read from the cache.
     * @param {int} start The first byte read.
     * @param {int} length The number of bytes read.
     */
    readBytes: function(start, length) {
      start = parseInt(start);
      length = parseInt(length);
      this.read_.add(start, start + length);
      this.available_.add(start, start + length);
      this.sparse = true;
    },

    /**
     * Mark a range of bytes as written to the cache.
     * @param {int} start The first byte written.
     * @param {int} length The number of bytes written.
     */
    writeBytes: function(start, length) {
      start = parseInt(start);
      length = parseInt(length);
      this.written_.add(start, start + length);
      this.available_.add(start, start + length);
      this.sparse = true;
    },

    /**
     * Merge this CacheEntry with another, merging recorded ranges and flags.
     * @param {CacheEntry} other The CacheEntry to merge into this one.
     */
    merge: function(other) {
      this.read_.merge(other.read_);
      this.written_.merge(other.written_);
      this.available_.merge(other.available_);
      this.sparse = this.sparse || other.sparse;
      this.key = this.key || other.key;
      this.size = this.size || other.size;
    },

    /**
     * Clear all recorded ranges from this CacheEntry and redraw this.details_.
     */
    clear: function() {
      this.read_ = new media.DisjointRangeSet;
      this.written_ = new media.DisjointRangeSet;
      this.available_ = new media.DisjointRangeSet;
      this.generateDetails();
    },

    /**
     * Helper for drawCacheReadsToCanvas() and drawCacheWritesToCanvas().
     *
     * Accepts the entries to draw, a canvas fill style, and the canvas to
     * draw on.
     */
    drawCacheEntriesToCanvas: function(entries, fillStyle, canvas) {
      // Don't bother drawing anything if we don't know the total size.
      if (!this.size) {
        return;
      }

      var width = canvas.width;
      var height = canvas.height;
      var context = canvas.getContext('2d');
      var fileSize = this.size;

      context.fillStyle = '#aaa';
      context.fillRect(0, 0, width, height);

      function drawRange(start, end) {
        var left = start / fileSize * width;
        var right = end / fileSize * width;
        context.fillRect(left, 0, right - left, height);
      }

      context.fillStyle = fillStyle;
      entries.map(function(start, end) {
        drawRange(start, end);
      });
    },

    /**
     * Draw cache writes to the given canvas.
     *
     * It should consist of a horizontal bar with highlighted sections to
     * represent which parts of a file have been written to the cache.
     *
     * e.g. |xxxxxx----------x|
     */
    drawCacheWritesToCanvas: function(canvas) {
      this.drawCacheEntriesToCanvas(this.written_, '#00a', canvas);
    },

    /**
     * Draw cache reads to the given canvas.
     *
     * It should consist of a horizontal bar with highlighted sections to
     * represent which parts of a file have been read from the cache.
     *
     * e.g. |xxxxxx----------x|
     */
    drawCacheReadsToCanvas: function(canvas) {
      this.drawCacheEntriesToCanvas(this.read_, '#0a0', canvas);
    },

    /**
     * Update this.details_ to contain everything we currently know about
     * this file.
     */
    generateDetails: function() {
      function makeElement(tag, content) {
        var toReturn = document.createElement(tag);
        toReturn.textContent = content;
        return toReturn;
      }

      this.details_.id = this.key;
      this.summaryText_.textContent = this.key || 'Unknown File';

      this.detailTable_.textContent = '';
      var header = document.createElement('thead');
      var footer = document.createElement('tfoot');
      var body = document.createElement('tbody');
      this.detailTable_.appendChild(header);
      this.detailTable_.appendChild(footer);
      this.detailTable_.appendChild(body);

      var headerRow = document.createElement('tr');
      headerRow.appendChild(makeElement('th', 'Read From Cache'));
      headerRow.appendChild(makeElement('th', 'Written To Cache'));
      header.appendChild(headerRow);

      var footerRow = document.createElement('tr');
      var footerCell = document.createElement('td');
      footerCell.textContent = 'Out of ' + (this.size || 'unkown size');
      footerCell.setAttribute('colspan', 2);
      footerRow.appendChild(footerCell);
      footer.appendChild(footerRow);

      var read = this.read_.map(function(start, end) {
        return start + ' - ' + end;
      });
      var written = this.written_.map(function(start, end) {
        return start + ' - ' + end;
      });

      var length = Math.max(read.length, written.length);
      for (var i = 0; i < length; i++) {
        var row = document.createElement('tr');
        row.appendChild(makeElement('td', read[i] || ''));
        row.appendChild(makeElement('td', written[i] || ''));
        body.appendChild(row);
      }

      this.drawCacheWritesToCanvas(this.writeCanvas);
      this.drawCacheReadsToCanvas(this.readCanvas);
    },

    /**
     * Render this CacheEntry as a <li>.
     * @return {HTMLElement} A <li> representing this CacheEntry.
     */
    toListItem: function() {
      this.generateDetails();

      var result = document.createElement('li');
      result.appendChild(this.details_);
      return result;
    }
  };

  return {
    CacheEntry: CacheEntry
  };
});
