text: import {Component} from '../Component';
  import {ComponentPropertiesDlg} from '../Dlg/ComponentPropertiesDlg';
  import {Led} from '../Graphics/Led';
  import {Sanitize} from '../Utility/Sanitize';
  
  /**
   * Component: LED Bar - 2 to 16 LED's in a vertical bar
  
   * @constructor
   */
  export const LEDBar = function() {
      Component.call(this);
  
      this.height = 50;
      this.width = 20;
      this.leds = [];
      this.horz = false;      // Horizontal option
      this.bus = false;       // Bus input?
  
      this.color = "blue";
      this.lastState = [];
  
      this.setSize(4);
  };
  
  LEDBar.prototype = Object.create(Component.prototype);
  LEDBar.prototype.constructor = LEDBar;
  LEDBar.prototype.prefix = "L";
  
  LEDBar.type = "LEDBar";            ///< Name to use in files
  LEDBar.label = "LED Bar";           ///< Label for the palette
  LEDBar.desc = "LED Indicator Bar";       ///< Description for the palette
  LEDBar.img = "ledbar.png";         ///< Image to use for the palette
  LEDBar.description = `<h2>LED Bar</h2><p>The LED Bar component displays from two to 
  sixteen LEDs in a vertical or horizontal bar that are lighted by values on discrete inputs
  or a single bus input. </p>`;
  LEDBar.order = 502;
  LEDBar.help = 'ledbar';
  
  LEDBar.prototype.setSize = function(size) {
      this.size = +size;
      this.ensureIO();
  }
  
  /**
   * Compute the gate result
   * @param state
   */
  LEDBar.prototype.compute = function(state) {
      if(this.bus) {
  	    this.lastState = state[0];
  
  	    if(this.lastState === undefined) {
  		    this.lastState = [];
  	    }
      } else {
  	    this.lastState = state;
      }
  
  };
  
  /**
   * Clone this component object.
   * @returns {LEDBar}
   */
  LEDBar.prototype.clone = function() {
      const copy = new LEDBar();
      copy.size = this.size;
      copy.horz = this.horz;
      copy.bus = this.bus;
      copy.ensureIO();
      copy.copyFrom(this);
      return copy;
  };
  
  /**
   * Load this object from an object converted from JSON
   * @param obj Object from JSON
   */
  LEDBar.prototype.load = function(obj) {
      this.color = Sanitize.sanitize(obj["color"]);
      if(obj["horz"] !== undefined) {
          this.horz = obj['horz'] === true;
      }
      if(obj['bus'] !== undefined) {
          this.bus = obj['bus'] === true;
      }
  	this.setSize(obj["size"]);
      Component.prototype.load.call(this, obj);
  };
  
  
  /**
   * Create a save object suitable for conversion to JSON for export.
   * @returns {*}
   */
  LEDBar.prototype.save = function() {
      const obj = Component.prototype.save.call(this);
      obj.size = this.size;
      obj.color = this.color;
      obj.horz = this.horz;
      obj.bus = this.bus;
      return obj;
  };
  
  /**
   * Ensure the actual number of inputs matches the
   * defined bus size.
   */
  LEDBar.prototype.ensureIO = function() {
      let spacing = 16;
  
      // Input counter
      let i = 0;
  	this.leds = [];
  
  	if(this.ins.length > 0) {
  	    //
  	    // Test if we switched input types
          // If so, disconnect everything and zero the inputs
          //
          if(this.ins[0].bus !== this.bus) {
  	        for(i=0; i<this.ins.length; i++) {
  		        this.ins[i].clear();
  	        }
  
  	        this.ins = [];
          }
      }
  
      if(this.horz) {
          //
          // Horizontal configuration
          //
  	    this.width = this.size * spacing;
  	    if(this.width < 50) {
  		    this.width = 50;
  	    }
  	    this.height = 20;
  
  	    let startX = this.size / 2 * spacing - 8;
  
  	    for(i=0; i<this.size; i++) {
  		    let pinX = startX - i * spacing;
  		    this.leds.push(new Led(pinX, 0, spacing, this.height));
  	    }
  
  	    if(!this.bus) {
  		    for(i=0; i<this.size; i++) {
  			    let pinX = startX - i * spacing;
  			    let pinLen = 24 - this.height/2;
  
  			    let inp = null;
  			    if(i < this.ins.length) {
  				    inp = this.ins[i];
  			    } else {
  				    // Add any new pins
  				    inp = this.addIn(pinX, this.height / 2, pinLen);
  			    }
  
  			    if(inp !== null) {
  			    	inp.x = pinX;
  			    	inp.y = this.height / 2;
  			    	inp.len = pinLen;
  				    inp.orientation = 's';
  				    inp.bus = false;
  			    }
  		    }
          } else {
  		    let inp = null;
  		    if(i < this.ins.length) {
  			    inp = this.ins[i];
  
  			    inp.x = -this.width / 2;
  			    inp.y = 0;
  			    inp.len = 16;
  		    } else {
  			    // Add any new pins
  			    inp = this.addIn(-this.width / 2, 0, 16);
  		    }
  
  		    inp.orientation = 'w';
  		    inp.bus = true;
  		    inp.autoLen();
  	    }
  
      } else {
          //
          // Vertical configuration
          //
  	    this.height = this.size * spacing;
  	    if(this.height < 50) {
  		    this.height = 50;
  	    }
  	    this.width = 20;
  
  	    let startY = this.size / 2 * spacing - 8;
  
  	    for(i=0; i<this.size; i++) {
  		    let pinY = startY - i * spacing;
  		    this.leds.push(new Led(0, pinY, this.width, spacing));
          }
  
  	    if(!this.bus) {
  		    for(i=0; i<this.size; i++) {
  			    let pinY = startY - i * spacing;
  			    let pinLen = 24 - this.width/2;
  
  			    let inp = null;
  			    if(i < this.ins.length) {
  				    inp = this.ins[i];
  
  				    inp.x = -this.width / 2;
  				    inp.y = pinY;
  				    inp.len = pinLen;
  			    } else {
  				    // Add any new pins
  				    inp = this.addIn(-this.width / 2, pinY, pinLen);
  			    }
  
  			    if(inp !== null) {
  				    inp.orientation = 'w';
  				    inp.bus = false;
  			    }
  		    }
          } else {
  		    let inp = null;
  		    if(i < this.ins.length) {
  			    inp = this.ins[i];
  
  			    inp.x = 0;
  			    inp.y = this.height / 2;
  			    inp.len = 16;
  		    } else {
  			    // Add any new pins
  			    inp = this.addIn(0, this.height / 2, 16);
  		    }
  
              inp.orientation = 's';
              inp.bus = true;
              inp.autoLen();
          }
  
      }
  
  	if(!this.bus) {
  	    // Delete pins that have ceased to exist
  	    if(i < this.ins.length) {
  		    for( ; i<this.ins.length; i++) {
  			    this.ins[i].clear();
  		    }
  
  		    this.ins.splice(this.size);
  	    }
      }
  }
  
  
  
  /**
   * Draw component object.
   * @param context Display context
   * @param view View object
   */
  LEDBar.prototype.draw = function(context, view) {
      //
      // Ensure the state is current
      //
      let i=0;
  
      for( ; i<this.lastState.length && i<this.leds.length;  i++) {
          let led = this.lastState[i];
          this.leds[i].color = led === undefined ? 'undefined' : (led ? this.color : 'black');
      }
  
      for( ; i<this.leds.length;  i++) {
          this.leds[i].color = 'undefined';
      }
  
      let background = '#444444';
  
      this.selectStyle(context, view);
  
      this.drawBox(context, background);
  
      for(let i=0; i<this.size;  i++) {
          this.leds[i].draw(context, this.x, this.y, background);
      }
  
      this.drawBox(context, 'none');
      this.drawIO(context, view);
  };
  
  LEDBar.prototype.properties = function(main) {
      const dlg = new ComponentPropertiesDlg(this, main);
  
      // Size
      const sizeId = dlg.uniqueId();
      let html = `<div class="control1 center"><label for="${sizeId}">Size: </label>
  <input class="number" type="text" name="${sizeId}" id="${sizeId}" value="${this.size}"></div>`;
  
      // Color
      const colorId = dlg.uniqueId();
      html += Led.colorSelector(colorId, this.color);
  
      html += '<div class="control center"><div class="choosers">';
  
  	const horzId = dlg.uniqueId();
      html += `
  <label><input type="radio" name="${horzId}" ${!this.horz ? 'checked' : ''} value="0"> Vertical</label>
  <label><input type="radio" name="${horzId}"  ${this.horz ? 'checked' : ''} value="1"> Horizontal</label>`;
  
      html += '<br>';
  
      const busId = dlg.uniqueId();
  	html += `
  <label><input type="radio" name="${busId}"  ${this.bus ? 'checked' : ''} value="1"> Bus Input</label>
  <label><input type="radio" name="${busId}" ${!this.bus ? 'checked' : ''} value="0"> Single Bit Inputs</label>`;
  
  	html += '</div></div>';
  
  	dlg.extra(html, () => {
          const size = parseInt(document.getElementById(sizeId).value);
          if(isNaN(size) || size < 2 || size > 16) {
              return "Size must be an integer from 2 to 16";
          }
          return null;
      }, () => {
          this.color = Sanitize.sanitize(document.getElementById(colorId).value);
  		this.horz = document.querySelector(`input[name=${horzId}]:checked`).value === '1';
  		this.bus = document.querySelector(`input[name=${busId}]:checked`).value === '1';
          this.setSize(parseInt(document.getElementById(sizeId).value));
  	});
  
      dlg.open();
  };
  