//
// Applesoft BASIC in Javascript
// Low Resolution Graphics (LoRes) Emulation
//

// Copyright (C) 2009-2011 Joshua Bell
//
// 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.


// Usage:
//
//   var lores = new LoRes( element, width, height )
//   lores.clear()
//   lores.setColor( color_index )
//   lores.plot( x, y )
//   lores.hlin( x1, x2, y )
//   lores.vlin( x1, x2, y )
//   lores.show( bool )
//   color_index = lores.getPixel( x, y )
//   { width: w, height: h } = lores.getScreenSize()
//
// Example:
//
//   <style>
//     .loresPixel { width: 14px; height: 8px; }
//   </style>
//   <script>
//     lores = new LoRes( document.getElementById( 'lores' ), 40, 40 );
//     interpreter = new BasicInterpreter( tty, lores, paddle );
//   </script>
//   <div id="lores"></div>

function LoRes(element, width, height) {

  /*jslint browser: true*/

  var COLORS, // Apple II to HTML color table
        loresPixel = [], // element references
        pixels = [], // color values
        color = 0; // current color

  // Colors c/o USENET:
  // Date: Wed, 05 Sep 2007 01:04:20 +0200
  // From: Linards Ticmanis <ticmanis@gmx.de>
  // Newsgroups: comp.sys.apple2
  // Subject: Re: Double hires mode color artifacts
  // Message-ID: <46dde477$0$4527$9b4e6d93@newsspool3.arcor-online.net>

  COLORS = [
        '#000000', // Black
        '#901740', // Deep Red
        '#402ca5', // Dark Blue
        '#d043e5', // Purple
        '#006940', // Dark Green
        '#808080', // Gray 1
        '#2f95e5', // Medium Blue
        '#bfabff', // Light Blue
        '#402400', // Brown        // WAS #405400, error pointed out by MJM
        '#d06a1a', // Orange
        '#808080', // Gray 2
        '#ff96bf', // Pink
        '#2fbc1a', // Light Green
        '#bfd35a', // Yellow
        '#6fe8bf', // Aquamarine
        '#ffffff'  // White
        ];

  function init() {
    var x, y, table, tbody, tr, td;

    pixels = [];
    pixels.length = width * height;
    loresPixel = [];
    loresPixel.length = width * height;

    table = document.createElement('table');
    table.className = 'loresDisplay';

    tbody = document.createElement('tbody');
    for (y = 0; y < height; y += 1) {
      tr = document.createElement('tr');
      tr.className = 'loresRow';
      for (x = 0; x < width; x += 1) {
        td = document.createElement('td');
        td.className = 'loresPixel';
        td.style.backgroundColor = 'black';

        loresPixel[y * width + x] = td;
        pixels[y * width + x] = 0;

        tr.appendChild(td);
      }
      tbody.appendChild(tr);
    }
    table.appendChild(tbody);

    element.innerHTML = "";
    element.appendChild(table);
  }

  this.clear = function() {
    var x, y, pixel;
    for (y = 0; y < height; y += 1) {
      for (x = 0; x < width; x += 1) {
        pixel = loresPixel[y * width + x];
        pixel.style.backgroundColor = "black";
        pixels[y * width + x] = 0;
      }
    }

  };

  this.setColor = function(newColor) {
    color = Math.floor(newColor) % COLORS.length;
  };
  
  function plot(x, y) {
    var pixel = loresPixel[y * width + x];
    if (pixel) {
      pixel.style.backgroundColor = COLORS[color];
      pixels[y * width + x] = color;
    }
  }

  this.plot = function(x, y) {
    plot(x, y);
  };

  this.getPixel = function(x, y) {
    if (0 <= x && x < width &&
            0 <= y && y < height) {

      return pixels[y * width + x];
    }
    else {
      return 0;
    }
  };

  this.hlin = function(x1, x2, y) {
    var x;
    if (x1 > x2) {
      x = x1;
      x1 = x2;
      x2 = x;
    }

    for (x = x1; x <= x2; x += 1) {
      plot(x, y);
    }
  };

  this.vlin = function(y1, y2, x) {
    var y;
    if (y1 > y2) {
      y = y1;
      y1 = y2;
      y2 = y;
    }

    for (y = y1; y <= y2; y += 1) {
      plot(x, y);
    }
  };

  this.getScreenSize = function() {
    return { width: width, height: height };
  };

  this.show = function(state) {
    element.style.visibility = state ? "visible" : "hidden";

  };
  
  //----------------------------------------------------------------------
  // Constructor Logic
  //----------------------------------------------------------------------

  init();
}



