<template>
  <svg ref="svg" v-bind="svgAttributes" v-html="svgContent" :class="calculatedClasses"></svg>
</template>

<script>

  import { computed, nextTick, onMounted, onUpdated, useTemplateRef } from "vue";

  import Caret from "../iconic/svg/smart/caret";
  import Check from "../iconic/svg/smart/check";
  import CircleCheck from "../iconic/svg/smart/circle-check";
  import Link from "../iconic/svg/smart/link";
  import Lock from "../iconic/svg/smart/lock";
  import Menu from "../iconic/svg/smart/menu";
  import QuestionMark from "../iconic/svg/smart/question-mark.svg"
  import Person from "../iconic/svg/smart/person";
  import Pencil from "../iconic/svg/smart/pencil";
  import Star from "../iconic/svg/smart/star";
  import StarEmpty from "../iconic/svg/smart/star-empty";
  import Warning from "../iconic/svg/smart/warning";
  import X from "../iconic/svg/smart/x";

  const APIS = {};
  const LOADED_APIS = {};

  window._Iconic = {
    smartIconApis: APIS
  };

  let globalIdCounter = 0;

  const iconMap = {
    caret: Caret,
    check: Check,
    'circle-check': CircleCheck,
    link: Link,
    lock: Lock,
    menu: Menu,
    pencil: Pencil,
    person: Person,
    'question-mark': QuestionMark,
    star: Star,
    'star-empty': StarEmpty,
    warning: Warning,
    x: X
  };
  
  export default {
    props: {
      icon: {
        type: String,
        required: true,
        validator: (i) => iconMap[i] !== undefined
      },

      size: {
        type: String,
        default: "lg",
        validator: (s) => ["sm", "md", "lg"].indexOf(s) >= 0
      },

      iconSizeOverride: {
        type: String,
        validator: (s) => ["sm", "md", "lg", null].indexOf(s) >= 0
      },

      displaySizeOverride: {
        type: String,
        validator: (s) => ["sm", "md", "lg", null].indexOf(s) >= 0
      }
    },

    setup(props) {
      const svgElement = useTemplateRef("svg");
      const svgData = computed(() => iconMap[props.icon]);
      const svgAttributes = computed(() => svgData.value.attributes);
      const svgName = computed(() => svgAttributes.value['data-icon']);
      const svgContent = computed(() => {
        let content = String(svgData.value.content);

        for (let idRep of svgData.value.idReplacements) {
          let newId = `__new_id_${globalIdCounter}`;
          globalIdCounter += 1;

          content = content.replace(new RegExp(idRep, "g"), newId);
        }

        return content;
      });

      const calculatedClasses = computed(() => {
        const classes = (svgAttributes.value.class || "").split(" ");

        classes.push(`iconic-${props.size}`);

        if (props.iconSizeOverride) {
          classes.push(`iconic-icon-${props.iconSizeOverride}`);
        }

        if (props.displaySizeOverride) {
          classes.push(`iconic-size-${props.displaySizeOverride}`);
        }

        return classes;
      });

      function ensureSvgApi(name, scripts) {
        if (!name) { return; }
        if (LOADED_APIS[name] !== true) {
          for (let sb of scripts) {
            try {
              new Function(sb)(window);
            } catch (e) {
              console.log(sb);
              console.log(e);
            }
          }
          LOADED_APIS[name] = true;
        }
      }

      function setupSvgApi(name) {
        const apis = APIS;
        if (apis && apis[name]) {
          const iconApi = apis[name](svgElement.value);
          for (let func in iconApi) svgElement.value[func] = iconApi[func]
        } else {
          svgElement.value.update = function() {}
        }
        svgElement.value.update();
      }

      function updateScripts() {
        ensureSvgApi(svgName.value, svgData.value.scriptBlocks);
        setupSvgApi(svgName.value);
      }

      onMounted(() => {
        updateScripts();
      });

      onUpdated(() => {
        updateScripts();
      });

      return {
        svgData,
        svgAttributes,
        svgName,
        svgContent,
        calculatedClasses
      };
    }
  }
  
</script>