/*!
 * segment-display.js
 *
 * Copyright 2012, Rüdiger Appel
 * http://www.3quarks.com
 * Published under Creative Commons 3.0 License.
 *
 * Date: 2012-02-14
 * Version: 1.0.0
 *
 * Dokumentation: http://www.3quarks.com/de/Segmentanzeige
 * Documentation: http://www.3quarks.com/en/SegmentDisplay
 */

// Segment display types
SegmentDisplay.SevenSegment    = 7;
SegmentDisplay.FourteenSegment = 14;
SegmentDisplay.SixteenSegment  = 16;

// Segment corner types
SegmentDisplay.SymmetricCorner = 0;
SegmentDisplay.SquaredCorner   = 1;
SegmentDisplay.RoundedCorner   = 2;


function SegmentDisplay(displayId) {
  this.displayId       = displayId;
  this.pattern         = '##:##:##';
  this.value           = '12:34:56';
  this.digitHeight     = 20;
  this.digitWidth      = 10;
  this.digitDistance   = 2.5;
  this.displayAngle    = 12;
  this.segmentWidth    = 2.5;
  this.segmentDistance = 0.2;
  this.segmentCount    = SegmentDisplay.SevenSegment;
  this.cornerType      = SegmentDisplay.RoundedCorner;
  this.colorOn         = 'rgb(233, 93, 15)';
  this.colorOff        = 'rgb(75, 30, 5)';
};

SegmentDisplay.prototype.setValue = function(value) {
  this.value = value;
  this.draw();
};

SegmentDisplay.prototype.draw = function() {
  var display = document.getElementById(this.displayId);
  if (display) {
    var context = display.getContext('2d');
    if (context) {
      // clear canvas
      context.clearRect(0, 0, display.width, display.height);

      // compute and check display width
      var width = 0;
      var first = true;
      if (this.pattern) {
        for (var i = 0; i < this.pattern.length; i++) {
          var c = this.pattern.charAt(i).toLowerCase();
          if (c == '#') {
            width += this.digitWidth;
          } else if (c == '.' || c == ':') {
            width += this.segmentWidth;
          } else if (c != ' ') {
            return;
          }
          width += first ? 0 : this.digitDistance;
          first = false;
        }
      }
      if (width <= 0) {
        return;
      }

      // compute skew factor
      var angle = -1.0 * Math.max(-45.0, Math.min(45.0, this.displayAngle));
      var skew  = Math.tan((angle * Math.PI) / 180.0);

      // compute scale factor
      var scale = Math.min(display.width / (width + Math.abs(skew * this.digitHeight)), display.height / this.digitHeight);

      // compute display offset
      var offsetX = (display.width - (width + skew * this.digitHeight) * scale) / 2.0;
      var offsetY = (display.height - this.digitHeight * scale) / 2.0;

      // context transformation
      context.save();
      context.translate(offsetX, offsetY);
      context.scale(scale, scale);
      context.transform(1, 0, skew, 1, 0, 0);

      // draw segments
      var xPos = 0;
      var size = (this.value) ? this.value.length : 0;
      for (var i = 0; i < this.pattern.length; i++) {
        var mask  = this.pattern.charAt(i);
        var value = (i < size) ? this.value.charAt(i).toLowerCase() : ' ';
        xPos += this.drawDigit(context, xPos, mask, value);
      }

      // finish drawing
      context.restore();
    }
  }
};

SegmentDisplay.prototype.drawDigit = function(context, xPos, mask, c) {
  switch (mask) {
    case '#':
      var r = Math.sqrt(this.segmentWidth * this.segmentWidth / 2.0);
      var d = Math.sqrt(this.segmentDistance * this.segmentDistance / 2.0);
      var e = d / 2.0;
      var f = (this.segmentWidth - d) * Math.sin((45.0 * Math.PI) / 180.0);
      var g = f / 2.0;
      var h = (this.digitHeight - 3.0 * this.segmentWidth) / 2.0;
      var w = (this.digitWidth - 3.0 * this.segmentWidth) / 2.0;
      var s = this.segmentWidth / 2.0;
      var t = this.digitWidth / 2.0;

      // draw segment a (a1 and a2 for 16 segments)
      if (this.segmentCount == 16) {
        var x = xPos;
        var y = 0;
        context.fillStyle = this.getSegmentColor(c, null, '02356789abcdefgiopqrstz@%');
        context.beginPath();
        switch (this.cornerType) {
          case SegmentDisplay.SymmetricCorner:
            context.moveTo(x + s + d, y + s);
            context.lineTo(x + this.segmentWidth + d, y);
            break;
          case SegmentDisplay.SquaredCorner:
            context.moveTo(x + s + e, y + s - e);
            context.lineTo(x + this.segmentWidth, y);
            break;
          default:
            context.moveTo(x + this.segmentWidth - f, y + this.segmentWidth - f - d);
            context.quadraticCurveTo(x + this.segmentWidth - g, y, x + this.segmentWidth, y);
        }
        context.lineTo(x + t - d - s, y);
        context.lineTo(x + t - d, y + s);
        context.lineTo(x + t - d - s, y + this.segmentWidth);
        context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
        context.fill();

        var x = xPos;
        var y = 0;
        context.fillStyle = this.getSegmentColor(c, null, '02356789abcdefgiopqrstz@');
        context.beginPath();
        context.moveTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
        context.lineTo(x + t + d + s, y + this.segmentWidth);
        context.lineTo(x + t + d, y + s);
        context.lineTo(x + t + d + s, y);
        switch (this.cornerType) {
          case SegmentDisplay.SymmetricCorner:
            context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
            context.lineTo(x + this.digitWidth - s - d, y + s);
            break;
          case SegmentDisplay.SquaredCorner:
            context.lineTo(x + this.digitWidth - this.segmentWidth, y);
            context.lineTo(x + this.digitWidth - s - e, y + s - e);
            break;
          default:
            context.lineTo(x + this.digitWidth - this.segmentWidth, y);
            context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y, x + this.digitWidth - this.segmentWidth + f, y + this.segmentWidth - f - d);
        }
        context.fill();

      } else {
        var x = xPos;
        var y = 0;
        context.fillStyle = this.getSegmentColor(c, '02356789acefp', '02356789abcdefgiopqrstz@');
        context.beginPath();
        switch (this.cornerType) {
          case SegmentDisplay.SymmetricCorner:
            context.moveTo(x + s + d, y + s);
            context.lineTo(x + this.segmentWidth + d, y);
            context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
            context.lineTo(x + this.digitWidth - s - d, y + s);
            break;
          case SegmentDisplay.SquaredCorner:
            context.moveTo(x + s + e, y + s - e);
            context.lineTo(x + this.segmentWidth, y);
            context.lineTo(x + this.digitWidth - this.segmentWidth, y);
            context.lineTo(x + this.digitWidth - s - e, y + s - e);
            break;
          default:
            context.moveTo(x + this.segmentWidth - f, y + this.segmentWidth - f - d);
            context.quadraticCurveTo(x + this.segmentWidth - g, y, x + this.segmentWidth, y);
            context.lineTo(x + this.digitWidth - this.segmentWidth, y);
            context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y, x + this.digitWidth - this.segmentWidth + f, y + this.segmentWidth - f - d);
        }
        context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
        context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
        context.fill();
      }

      // draw segment b
      x = xPos + this.digitWidth - this.segmentWidth;
      y = 0;
      context.fillStyle = this.getSegmentColor(c, '01234789adhpy', '01234789abdhjmnopqruwy');
      context.beginPath();
      switch (this.cornerType) {
        case SegmentDisplay.SymmetricCorner:
          context.moveTo(x + s, y + s + d);
          context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
          break;
        case SegmentDisplay.SquaredCorner:
          context.moveTo(x + s + e, y + s + e);
          context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
          break;
        default:
          context.moveTo(x + f + d, y + this.segmentWidth - f);
          context.quadraticCurveTo(x + this.segmentWidth, y + this.segmentWidth - g, x + this.segmentWidth, y + this.segmentWidth);
      }
      context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
      context.lineTo(x + s, y + h + this.segmentWidth + s - d);
      context.lineTo(x, y + h + this.segmentWidth - d);
      context.lineTo(x, y + this.segmentWidth + d);
      context.fill();

      // draw segment c
      x = xPos + this.digitWidth - this.segmentWidth;
      y = h + this.segmentWidth;
      context.fillStyle = this.getSegmentColor(c, '013456789abdhnouy', '01346789abdghjmnoqsuw@', '%');
      context.beginPath();
      context.moveTo(x, y + this.segmentWidth + d);
      context.lineTo(x + s, y + s + d);
      context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
      context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
      switch (this.cornerType) {
        case SegmentDisplay.SymmetricCorner:
          context.lineTo(x + s, y + h + this.segmentWidth + s - d);
          context.lineTo(x, y + h + this.segmentWidth - d);
          break;
        case SegmentDisplay.SquaredCorner:
          context.lineTo(x + s + e, y + h + this.segmentWidth + s - e);
          context.lineTo(x, y + h + this.segmentWidth - d);
          break;
        default:
          context.quadraticCurveTo(x + this.segmentWidth, y + h + this.segmentWidth + g, x + f + d, y + h + this.segmentWidth + f); //
          context.lineTo(x, y + h + this.segmentWidth - d);
      }
      context.fill();

      // draw segment d (d1 and d2 for 16 segments)
      if (this.segmentCount == 16) {
        x = xPos;
        y = this.digitHeight - this.segmentWidth;
        context.fillStyle = this.getSegmentColor(c, null, '0235689bcdegijloqsuz_=@');
        context.beginPath();
        context.moveTo(x + this.segmentWidth + d, y);
        context.lineTo(x + t - d - s, y);
        context.lineTo(x + t - d, y + s);
        context.lineTo(x + t - d - s, y + this.segmentWidth);
        switch (this.cornerType) {
          case SegmentDisplay.SymmetricCorner:
            context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
            context.lineTo(x + s + d, y + s);
            break;
          case SegmentDisplay.SquaredCorner:
            context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
            context.lineTo(x + s + e, y + s + e);
            break;
          default:
            context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
            context.quadraticCurveTo(x + this.segmentWidth - g, y + this.segmentWidth, x + this.segmentWidth - f, y + f + d);
            context.lineTo(x + this.segmentWidth - f, y + f + d);
        }
        context.fill();

        x = xPos;
        y = this.digitHeight - this.segmentWidth;
        context.fillStyle = this.getSegmentColor(c, null, '0235689bcdegijloqsuz_=@', '%');
        context.beginPath();
        context.moveTo(x + t + d + s, y + this.segmentWidth);
        context.lineTo(x + t + d, y + s);
        context.lineTo(x + t + d + s, y);
        context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
        switch (this.cornerType) {
          case SegmentDisplay.SymmetricCorner:
            context.lineTo(x + this.digitWidth - s - d, y + s);
            context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
            break;
          case SegmentDisplay.SquaredCorner:
            context.lineTo(x + this.digitWidth - s - e, y + s + e);
            context.lineTo(x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
            break;
          default:
            context.lineTo(x + this.digitWidth - this.segmentWidth + f, y + f + d);
            context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y + this.segmentWidth, x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
        }
        context.fill();
      }
      else {
        x = xPos;
        y = this.digitHeight - this.segmentWidth;
        context.fillStyle = this.getSegmentColor(c, '0235689bcdelotuy_', '0235689bcdegijloqsuz_=@');
        context.beginPath();
        context.moveTo(x + this.segmentWidth + d, y);
        context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
        switch (this.cornerType) {
          case SegmentDisplay.SymmetricCorner:
            context.lineTo(x + this.digitWidth - s - d, y + s);
            context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
            context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
            context.lineTo(x + s + d, y + s);
            break;
          case SegmentDisplay.SquaredCorner:
            context.lineTo(x + this.digitWidth - s - e, y + s + e);
            context.lineTo(x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
            context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
            context.lineTo(x + s + e, y + s + e);
            break;
          default:
            context.lineTo(x + this.digitWidth - this.segmentWidth + f, y + f + d);
            context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y + this.segmentWidth, x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
            context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
            context.quadraticCurveTo(x + this.segmentWidth - g, y + this.segmentWidth, x + this.segmentWidth - f, y + f + d);
            context.lineTo(x + this.segmentWidth - f, y + f + d);
        }
        context.fill();
      }

      // draw segment e
      x = xPos;
      y = h + this.segmentWidth;
      context.fillStyle = this.getSegmentColor(c, '0268abcdefhlnoprtu', '0268acefghjklmnopqruvw@');
      context.beginPath();
      context.moveTo(x, y + this.segmentWidth + d);
      context.lineTo(x + s, y + s + d);
      context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
      context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
      switch (this.cornerType) {
        case SegmentDisplay.SymmetricCorner:
          context.lineTo(x + s, y + h + this.segmentWidth + s - d);
          context.lineTo(x, y + h + this.segmentWidth - d);
          break;
        case SegmentDisplay.SquaredCorner:
          context.lineTo(x + s - e, y + h + this.segmentWidth + s - d + e);
          context.lineTo(x, y + h + this.segmentWidth);
          break;
        default:
          context.lineTo(x + this.segmentWidth - f - d, y + h + this.segmentWidth + f);
          context.quadraticCurveTo(x, y + h + this.segmentWidth + g, x, y + h + this.segmentWidth);
      }
      context.fill();

      // draw segment f
      x = xPos;
      y = 0;
      context.fillStyle = this.getSegmentColor(c, '045689abcefhlpty', '045689acefghklmnopqrsuvwy@', '%');
      context.beginPath();
      context.moveTo(x + this.segmentWidth, y + this.segmentWidth + d);
      context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
      context.lineTo(x + s, y + h + this.segmentWidth + s - d);
      context.lineTo(x, y + h + this.segmentWidth - d);
      switch (this.cornerType) {
        case SegmentDisplay.SymmetricCorner:
          context.lineTo(x, y + this.segmentWidth + d);
          context.lineTo(x + s, y + s + d);
          break;
        case SegmentDisplay.SquaredCorner:
          context.lineTo(x, y + this.segmentWidth);
          context.lineTo(x + s - e, y + s + e);
          break;
        default:
          context.lineTo(x, y + this.segmentWidth);
          context.quadraticCurveTo(x, y + this.segmentWidth - g, x + this.segmentWidth - f - d, y + this.segmentWidth - f);
          context.lineTo(x + this.segmentWidth - f - d, y + this.segmentWidth - f);
      }
      context.fill();

      // draw segment g for 7 segments
      if (this.segmentCount == 7) {
        x = xPos;
        y = (this.digitHeight - this.segmentWidth) / 2.0;
        context.fillStyle = this.getSegmentColor(c, '2345689abdefhnoprty-=');
        context.beginPath();
        context.moveTo(x + s + d, y + s);
        context.lineTo(x + this.segmentWidth + d, y);
        context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
        context.lineTo(x + this.digitWidth - s - d, y + s);
        context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
        context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
        context.fill();
      }

      // draw inner segments for the fourteen- and sixteen-segment-display
      if (this.segmentCount != 7) {
        // draw segment g1
        x = xPos;
        y = (this.digitHeight - this.segmentWidth) / 2.0;
        context.fillStyle = this.getSegmentColor(c, null, '2345689aefhkprsy-+*=', '%');
        context.beginPath();
        context.moveTo(x + s + d, y + s);
        context.lineTo(x + this.segmentWidth + d, y);
        context.lineTo(x + t - d - s, y);
        context.lineTo(x + t - d, y + s);
        context.lineTo(x + t - d - s, y + this.segmentWidth);
        context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
        context.fill();

        // draw segment g2
        x = xPos;
        y = (this.digitHeight - this.segmentWidth) / 2.0;
        context.fillStyle = this.getSegmentColor(c, null, '234689abefghprsy-+*=@', '%');
        context.beginPath();
        context.moveTo(x + t + d, y + s);
        context.lineTo(x + t + d + s, y);
        context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
        context.lineTo(x + this.digitWidth - s - d, y + s);
        context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
        context.lineTo(x + t + d + s, y + this.segmentWidth);
        context.fill();

        // draw segment j
        x = xPos + t - s;
        y = 0;
        context.fillStyle = this.getSegmentColor(c, null, 'bdit+*', '%');
        context.beginPath();
        if (this.segmentCount == 14) {
          context.moveTo(x, y + this.segmentWidth + this.segmentDistance);
          context.lineTo(x + this.segmentWidth, y + this.segmentWidth + this.segmentDistance);
        } else {
          context.moveTo(x, y + this.segmentWidth + d);
          context.lineTo(x + s, y + s + d);
          context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
        }
        context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
        context.lineTo(x + s, y + h + this.segmentWidth + s - d);
        context.lineTo(x, y + h + this.segmentWidth - d);
        context.fill();

        // draw segment m
        x = xPos + t - s;
        y = this.digitHeight;
        context.fillStyle = this.getSegmentColor(c, null, 'bdity+*@', '%');
        context.beginPath();
        if (this.segmentCount == 14) {
          context.moveTo(x, y - this.segmentWidth - this.segmentDistance);
          context.lineTo(x + this.segmentWidth, y - this.segmentWidth - this.segmentDistance);
        } else {
          context.moveTo(x, y - this.segmentWidth - d);
          context.lineTo(x + s, y - s - d);
          context.lineTo(x + this.segmentWidth, y - this.segmentWidth - d);
        }
        context.lineTo(x + this.segmentWidth, y - h - this.segmentWidth + d);
        context.lineTo(x + s, y - h - this.segmentWidth - s + d);
        context.lineTo(x, y - h - this.segmentWidth + d);
        context.fill();

        // draw segment h
        x = xPos + this.segmentWidth;
        y = this.segmentWidth;
        context.fillStyle = this.getSegmentColor(c, null, 'mnx\\*');
        context.beginPath();
        context.moveTo(x + this.segmentDistance, y + this.segmentDistance);
        context.lineTo(x + this.segmentDistance + r, y + this.segmentDistance);
        context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance - r);
        context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance);
        context.lineTo(x + w - this.segmentDistance - r , y + h - this.segmentDistance);
        context.lineTo(x + this.segmentDistance, y + this.segmentDistance + r);
        context.fill();

        // draw segment k
        x = xPos + w + 2.0 * this.segmentWidth;
        y = this.segmentWidth;
        context.fillStyle = this.getSegmentColor(c, null, '0kmvxz/*', '%');
        context.beginPath();
        context.moveTo(x + w - this.segmentDistance, y + this.segmentDistance);
        context.lineTo(x + w - this.segmentDistance, y + this.segmentDistance + r);
        context.lineTo(x + this.segmentDistance + r, y + h - this.segmentDistance);
        context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance);
        context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance - r);
        context.lineTo(x + w - this.segmentDistance - r, y + this.segmentDistance);
        context.fill();

        // draw segment l
        x = xPos + w + 2.0 * this.segmentWidth;
        y = h + 2.0 * this.segmentWidth;
        context.fillStyle = this.getSegmentColor(c, null, '5knqrwx\\*');
        context.beginPath();
        context.moveTo(x + this.segmentDistance, y + this.segmentDistance);
        context.lineTo(x + this.segmentDistance + r, y + this.segmentDistance);
        context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance - r);
        context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance);
        context.lineTo(x + w - this.segmentDistance - r , y + h - this.segmentDistance);
        context.lineTo(x + this.segmentDistance, y + this.segmentDistance + r);
        context.fill();

        // draw segment n
        x = xPos + this.segmentWidth;
        y = h + 2.0 * this.segmentWidth;
        context.fillStyle = this.getSegmentColor(c, null, '0vwxz/*', '%');
        context.beginPath();
        context.moveTo(x + w - this.segmentDistance, y + this.segmentDistance);
        context.lineTo(x + w - this.segmentDistance, y + this.segmentDistance + r);
        context.lineTo(x + this.segmentDistance + r, y + h - this.segmentDistance);
        context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance);
        context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance - r);
        context.lineTo(x + w - this.segmentDistance - r, y + this.segmentDistance);
        context.fill();
      }

      return this.digitDistance + this.digitWidth;

    case '.':
      context.fillStyle = (c == '#') || (c == '.') ? this.colorOn : this.colorOff;
      this.drawPoint(context, xPos, this.digitHeight - this.segmentWidth, this.segmentWidth);
      return this.digitDistance + this.segmentWidth;

    case ':':
      context.fillStyle = (c == '#') || (c == ':') ? this.colorOn : this.colorOff;
			var offset = this.segmentWidth / 2;
      var y = (this.digitHeight - this.segmentWidth) / 2.0 - this.segmentWidth;
      this.drawPoint(context, xPos, y - offset, this.segmentWidth);
      this.drawPoint(context, xPos, y + 2.0 * this.segmentWidth + offset, this.segmentWidth);
      return this.digitDistance + this.segmentWidth;

    default:
      return this.digitDistance;
  }
};

SegmentDisplay.prototype.drawPoint = function(context, x1, y1, size) {
  var x2 = x1 + size;
  var y2 = y1 + size;
  var d  = size / 4.0;

  context.beginPath();
  context.moveTo(x2 - d, y1);
  context.quadraticCurveTo(x2, y1, x2, y1 + d);
  context.lineTo(x2, y2 - d);
  context.quadraticCurveTo(x2, y2, x2 - d, y2);
  context.lineTo(x1 + d, y2);
  context.quadraticCurveTo(x1, y2, x1, y2 - d);
  context.lineTo(x1, y1 + d);
  context.quadraticCurveTo(x1, y1, x1 + d, y1);
  context.fill();
};

SegmentDisplay.prototype.getSegmentColor = function(c, charSet7, charSet14, charSet16) {
  if (c == '#') {
    return this.colorOn;
  } else {
    switch (this.segmentCount) {
      case 7:  return (charSet7.indexOf(c) == -1) ? this.colorOff : this.colorOn;
      case 14: return (charSet14.indexOf(c) == -1) ? this.colorOff : this.colorOn;
      case 16: var pattern = charSet14 + (charSet16 === undefined ? '' : charSet16);
               return (pattern.indexOf(c) == -1) ? this.colorOff : this.colorOn;
      default: return this.colorOff;
    }
  }
};
