console.info(`%c TEMPOMETER-CARD \n%c      v1.4-beta.1`, 'color: orange; font-weight: bold; background: black', 'color: white; font-weight: bold; background: dimgray');
class TempometerGaugeCard extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }
  setConfig(config) {
    if (!config.entity) {
      throw new Error('Please define an entity');
    }
	if (config.max == null) {
		throw new Error('Please define the max config option');
	}
	if (config.min == null) {
		throw new Error('Please define the min config option');
	}

    const root = this.shadowRoot;
    if (root.lastChild) root.removeChild(root.lastChild);

    const cardConfig = Object.assign({}, config);
    if (!cardConfig.scale) cardConfig.scale = "50px";

    if (config.horizontal) {
      cardConfig.scale = "40px";
    }
    
    const entityParts = this._splitEntityAndAttribute(cardConfig.entity);
    cardConfig.entity = entityParts.entity;
    if (entityParts.attribute) cardConfig.attribute = entityParts.attribute;

    if (cardConfig.entity_min !== undefined) {
      const entityMinParts = this._splitEntityAndAttribute(cardConfig.entity_min);
      cardConfig.entity_min = entityMinParts.entity;
      if (entityMinParts.attribute) cardConfig.minAttribute = entityMinParts.attribute;
    }

    if (cardConfig.entity_max !== undefined) {
      const entityMaxParts = this._splitEntityAndAttribute(cardConfig.entity_max);
      cardConfig.entity_max = entityMaxParts.entity;
      if (entityMaxParts.attribute) cardConfig.maxAttribute = entityMaxParts.attribute;
    }
    
    if (config.icon_color !== undefined) {
        var icon_color = config.icon_color;
    } else {
        var icon_color = "var(--paper-item-icon-color)";
    }
	    
    let card_style = cardConfig.card_style;
    const card = document.createElement('ha-card');
    const content = document.createElement('div');
    const style = document.createElement('style');

    style.textContent = `
      ha-card {
        --base-unit: ${cardConfig.scale};
        height: calc(var(--base-unit)*3.5);
        position: relative;
      }
      .container{
        width: calc(var(--base-unit) * 4);
        height: calc(var(--base-unit) * 2.44);
        position: absolute;
        top: calc(var(--base-unit)*2.1);
        left: 50%;
        overflow: hidden;
        text-align: center;
        transform: translate(-50%, -50%);
      }
      .gauge-a{
        z-index: 1;
        position: absolute;
        background-color: var(--secondary-background-color);
        width: calc(var(--base-unit) * 4);
        height: calc(var(--base-unit) * 2);
        top: 0%;
        border-radius:calc(var(--base-unit) * 2.5) calc(var(--base-unit) * 2.5) 0px 0px ;
      }
      .gauge-b{
        z-index: 3;
        position: absolute;
        background-color: var(--card-background-color);
        width: calc(var(--base-unit) * 3.6);
        height: calc(var(--base-unit) * 2);
        top: calc(var(--base-unit) * 0.2);
        margin-left: calc(var(--base-unit) * 0.2);
        margin-right: auto;
        border-radius: calc(var(--base-unit) * 3.6) calc(var(--base-unit) * 3.6) 0px 0px ;
      }
      .gauge-c{
        z-index: 2;
        position: absolute;
        background-color: var(--label-badge-yellow);
        width: calc(var(--base-unit) * 4);
        height: calc(var(--base-unit) * 2);
        top: calc(var(--base-unit) * 2);
        margin-left: auto;
        margin-right: auto;
        border-radius: 0px 0px calc(var(--base-unit) * 2) calc(var(--base-unit) * 2) ;
        transform-origin: center top;
        transition: all 1.3s ease-in-out;
      }
      .gauge-data{
        z-index: 4;
        color: var(--primary-text-color);
        line-height: calc(var(--base-unit) * 0.3);
        position: absolute;
        width: calc(var(--base-unit) * 4);
        height: calc(var(--base-unit) * 2.1);
        top: calc(var(--base-unit) * 1.25);
        margin-left: auto;
        margin-right: auto;
        transition: all 1s ease-out;
      }
      .gauge-data #percent{
        font-size: calc(var(--base-unit) * 0.55);
      }
      .gauge-data #title{
        padding-top: calc(var(--base-unit) * 0.15);
        font-size: calc(var(--base-unit) * 0.30);
      }
      .gauge-icons{
            width: calc(var(--base-unit) * 4);
            height: calc(var(--base-unit) * 2.5);
            text-align: center;
            margin: 0 auto;
            padding-top: calc(var(--base-unit)*0.15);
        }
      .icon1{
            width: 18px;
            height: 18px;
            color: ${icon_color};
            float: left;
            padding-top: 3em;
        }
      .icon2{
            width: 18px;
            height: 18px;
            color: ${icon_color};
            padding-top: .5em;
            padding-right: 9px;
        }
      .icon3{
            width: 18px;
            height: 18px;
            color: ${icon_color};
            float: right;
            padding-top: 3em;
        }
      .gauge-footer{
            position: absolute;
            width: calc(var(--base-unit) *4);
            height: calc(var(--base-unit) *.75);
            top: calc(var(--base-unit) *2);
            z-index: 4;
            font-size: calc(var(--base-unit) * 0.30);
            font-weight: 400;
            padding-top: .25em;
            background: var(--card-background-color);
        }
      .gauge-footer .minval{
            float: left;
            color: #797575;
            padding-left: .5em;
        }
      .gauge-footer .maxval{
            float: right;
            color: #797575;
            padding-right: .25em;
        }
      .gauge-c hr {
            visibility: hidden;
        }
      .gauge-d{
        z-index: 100;
        position: absolute;
        width: calc(var(--base-unit) * 4);
        height: 0;
        top: calc(var(--base-unit) * 2);
        margin-left: auto;
        margin-right: auto;
        border-radius: 0px 0px calc(var(--base-unit) * 2) calc(var(--base-unit) * 2) ;
        transform-origin: center top;
        transition: all 1.3s ease-in-out;
        transform: rotate(45deg);
      }
      .gauge-e{
        z-index: 101;
        position: absolute;
        width: calc(var(--base-unit) * 4);
        height: 0;
        top: calc(var(--base-unit) * 2);
        margin-left: auto;
        margin-right: auto;
        border-radius: 0px 0px calc(var(--base-unit) * 2) calc(var(--base-unit) * 2) ;
        transform-origin: center top;
        transition: all 1.3s ease-in-out;
        transform: rotate(125deg);
      }
    `;
    content.innerHTML = `
    <div id="gauge-icons" class="gauge-icons" style="display: none;">
        <ha-icon class="icon1" icon="${cardConfig.icon1}"></ha-icon>
        <ha-icon class="icon2" icon="${cardConfig.icon2}"></ha-icon>
        <ha-icon class="icon3" icon="${cardConfig.icon3}"></ha-icon>
    </div>
    <div id="gauge-icons-baro" class="gauge-icons">
        <ha-icon class="icon1" icon=mdi:weather-pouring></ha-icon>
        <ha-icon class="icon2" icon=mdi:weather-partly-cloudy></ha-icon>
        <ha-icon class="icon3" icon=mdi:weather-sunny></ha-icon>
    </div>
    <div id="gauge-icons-thermo" class="gauge-icons" style="display: none;">
        <ha-icon class="icon1" icon=mdi:thermometer-low></ha-icon>
        <ha-icon class="icon2" icon=mdi:thermometer></ha-icon>
        <ha-icon class="icon3" icon=mdi:thermometer-high></ha-icon>
    </div>
    <div id="gauge-icons-water" class="gauge-icons" style="display: none;">
        <ha-icon class="icon1" icon=mdi:water-off></ha-icon>
        <ha-icon class="icon2" icon=mdi:water-percent></ha-icon>
        <ha-icon class="icon3" icon=mdi:water></ha-icon>
    </div>
    <div class="container">
        <div class="gauge-a">
        </div>
        <div class="gauge-b"></div>
        <div class="gauge-c" id="gauge"></div>
        <div class="gauge-d" id="recentMin">
            <svg id="svg_min" style="margin-right: 90%; width: 18px;height: 18px; margin-top: -6px; padding-bottom: 10px" viewBox="0 0 24 24">
                <title id="svg_min_title"></title>
                <path fill="blue" d="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z" />
	    </svg>
        </div>
        <div class="gauge-e" id="recentMax">
            <svg id="svg_max" style="margin-right: 90%; width: 18px;height: 18px; margin-top: -12px; padding-bottom:10px;" viewBox="0 0 24 24">
                <title id="svg_max_title"></title>
                <path fill="red" d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" />
            </svg>
        </div>
        <div class="gauge-data">
            <div id="percent"></div>
            <div id="title"></div>
        </div>
        <div class="gauge-footer">
            <span id="minval" class="minval"></span>
            <span id="maxval" class="maxval"></span>
        </div>
      </div>
    `;
    card.appendChild(content);
    card.appendChild(style);
    card.addEventListener('click', event => {
      this._fire('hass-more-info', { entityId: cardConfig.entity });
    });
    root.appendChild(card);
    this._config = cardConfig;
	
	if (card_style == "thermometer") {
		root.getElementById("gauge-icons-baro").style.display = 'none';
		root.getElementById("gauge-icons-water").style.display = 'none';
		root.getElementById("gauge-icons-thermo").style.display = 'block';
		root.getElementById("gauge-icons").style.display = 'none';
	} else if (card_style == "humidity") {
		root.getElementById("gauge-icons-baro").style.display = 'none';
		root.getElementById("gauge-icons-water").style.display = 'block';
		root.getElementById("gauge-icons-thermo").style.display = 'none';
		root.getElementById("gauge-icons").style.display = 'none';
	} else if (card_style == "custom") {
	    root.getElementById("gauge-icons-baro").style.display = 'none';
		root.getElementById("gauge-icons-water").style.display = 'none';
		root.getElementById("gauge-icons-thermo").style.display = 'none';
		root.getElementById("gauge-icons").style.display = 'block';
	}
  }

  _splitEntityAndAttribute(entity) {
      let parts = entity.split('.');
      if (parts.length < 3) {
          return { entity: entity };
      }

      return { attribute: parts.pop(), entity: parts.join('.') };
  }

  _fire(type, detail, options) {
    const node = this.shadowRoot;
    options = options || {};
    detail = (detail === null || detail === undefined) ? {} : detail;
    const event = new Event(type, {
      bubbles: options.bubbles === undefined ? true : options.bubbles,
      cancelable: Boolean(options.cancelable),
      composed: options.composed === undefined ? true : options.composed
    });
    event.detail = detail;
    node.dispatchEvent(event);
    return event;
  }

  _translateTurn(value, config) {
    return 5 * (value - config.min) / (config.max - config.min);
  }

  _computeSeverity(stateValue, sections) {
    let numberValue = Number(stateValue);
    const severityMap = {
      red: "var(--label-badge-red)",
      green: "var(--label-badge-green)",
      yellow: "var(--label-badge-yellow)",
      normal: "var(--label-badge-blue)",
    };
    if (!sections) return severityMap["normal"];
    let sortable = [];
    for (let severity in sections) {
      sortable.push([severity, sections[severity]]);
    }
    sortable.sort((a, b) => { return a[1] - b[1] });
    if (numberValue >= sortable[0][1] && numberValue < sortable[1][1]) {
      return severityMap[sortable[0][0]];
    }
    if (numberValue >= sortable[1][1] && numberValue < sortable[2][1]) {
      return severityMap[sortable[1][0]];
    }
    if (sortable.length === 4) {
      if (numberValue >= sortable[2][1] && numberValue < sortable[3][1]) {
        return severityMap[sortable[2][0]];
      }
      if (numberValue > sortable[3][1]) {
        return severityMap["normal"]
      }
    } else {
      if (numberValue >= sortable[2][1]) {
        return severityMap[sortable[2][0]];
      }
    }
    return severityMap["normal"];
  }

  _getEntityStateValue(entity, attribute) {
    if (!attribute) {
      return entity.state;
    }

    return entity.attributes[attribute];
  }

  set hass(hass) {
    const root = this.shadowRoot;
    const config = this._config;
    var entityState = this._getEntityStateValue(hass.states[config.entity], config.attribute);
    var maxEntityState = null;
    var minEntityState = null;
    if (config.entity_max !== undefined) {
        maxEntityState = this._getEntityStateValue(hass.states[config.entity_max], config.maxAttribute);
    } else {
        root.getElementById("recentMax").style.display = 'none';
    }
    if (config.entity_min !== undefined) {
        minEntityState = this._getEntityStateValue(hass.states[config.entity_min], config.minAttribute);
    } else {
        root.getElementById("recentMin").style.display = 'none';
    }

    let measurement = "";
    if (config.measurement == null) {
      if (hass.states[config.entity].attributes.unit_of_measurement === undefined) {
        measurement = '';
      } else {
        measurement = hass.states[config.entity].attributes.unit_of_measurement;
      }
    } else {
      measurement = config.measurement;
    }

	root.getElementById("minval").innerHTML = config.min;
	root.getElementById("maxval").innerHTML = config.max;
    
  // Set decimal precision
  if (config.decimals !== undefined) {
      // Only allow positive numbers
      if (config.decimals >= 0) {
        entityState = Math.round(parseFloat(entityState) * (10 ** config.decimals)) / (10 ** config.decimals)   // Round (https://stackoverflow.com/a/11832950)
        entityState = entityState.toFixed(config.decimals)  // Add trailing zeroes if applicable        
      }
  }

	if (entityState !== this._entityState) {
      root.getElementById("percent").textContent = `${entityState} ${measurement}`;
      root.getElementById("title").textContent = config.title;
      const turn = this._translateTurn(entityState, config) / 10;
      root.getElementById("gauge").style.transform = `rotate(${turn}turn)`;
      root.getElementById("gauge").style.backgroundColor = this._computeSeverity(entityState, config.severity);
      this._entityState = entityState;
    }
	if (config.entity_max !== null) {
	    if (maxEntityState !== this._maxEntityState) {
		    this._maxEntityState = maxEntityState;
		    const turn3 = this._translateTurn(maxEntityState, config) /10;  
		    root.getElementById("recentMax").style.transform = `rotate(${turn3}turn)`;
		    root.getElementById("svg_max_title").innerHTML = maxEntityState;
	    }
	}
	if (config.entity_min !== null) {
	    if (minEntityState !== this._minEntityState) {
		    this._minEntityState = minEntityState;
		    const turn2 = this._translateTurn(minEntityState, config) /10;
            root.getElementById("recentMin").style.transform = `rotate(${turn2}turn)`;
		    root.getElementById("svg_min_title").innerHTML = minEntityState;
	    } 
	}
    root.lastChild.hass = hass;
  }

  getCardSize() {
    return 1;
  }
}

customElements.define('tempometer-gauge-card', TempometerGaugeCard);
