<template>
<div class="grid-container h-screen">
    <div class="wrapper">
        <div class="grid-header">
            <h1 class="text-center text-4xl font-bold">Batch Color Converter</h1>
            <button @click="batchConvert" type="button">Convert</button>
        </div>
        <div class="grid-main">
            <div class="input-container">
                <textarea v-model="inputBox" class="resize-y w-full h-96 border border-gray-200 shadow rounded py-2 px-4" placeholder="#fff"></textarea>
            </div>
            <div class="output-wrapper">
                <table class="font-ubuntu w-full">
                    <thead>
                        <tr>
                            <th class="p-4">Preview</th>
                            <th class="p-4">Hex(a)</th>
                            <th class="p-4">RGB(a)</th>
                            <th class="p-4">HSL(a)</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(color, idx) in convertedColors" :key="idx" class="border-t border-gray-300">
                            <td v-show="color.error" class="text-center px-2 py-4 bg-red-200 text-red-700 font-bold" colspan="4">Error with {{ color.raw }}</td>
                            <td v-show="!color.error">
                                <div class="block mx-2 my-4" style="height: 25px" :style="{ background: color.hex }"></div>
                            </td>
                            <td v-show="!color.error" class="color-cell cursor-pointer"><div class="text-center px-2 py-4 border border-transparent hover:border-gray-500" v-on:click="updateClipboard(color.hex)">{{ color.hex }}</div></td>
                            <td v-show="!color.error" class="color-cell cursor-pointer"><div class="text-center px-2 py-4 border border-transparent hover:border-gray-500" v-on:click="updateClipboard(color.rgb)">{{ color.rgb }}</div></td>
                            <td v-show="!color.error" class="color-cell cursor-pointer"><div class="text-center px-2 py-4 border border-transparent hover:border-gray-500" v-on:click="updateClipboard(color.hsl)">{{ color.hsl }}</div></td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <div class="grid-footer">
            <p>You can take a look at <a href="https://git.ditoforge.com/brian/batch-color-converter" title="Source code for this page" class="text-blue-400 font-bold hover:text-blue-700 transition">this terrible code over on my git server</a>.</p>
        </div>
    </div>
</div>
</template>

<script>
import { defineComponent, reactive, ref, computed, watch, onBeforeMount, onMounted } from 'vue'
import { Color } from './converters/index.js'

export default defineComponent({
  emits: [],

  props: {},

  components: {},

  setup(props, { attrs, slots, emit, expose }) {
    let defaultInputs = [
      "ccc",
      "#db2777aa",
      "rgb(64, 240, 18)",
      "hsla(240, 86.9%, 50.7%, 0.8)",
    ]
    let inputBox = ref("ccc\n#4f46e5\n#db2777aa\n")

    let convertedColors = ref([])

    let showStatusMessage = ref(false)
    let showErrorMessage = ref(false)

    //const hexRegex = /^\#?[a-fA-F0-9]{3,6}$/i
    //const hexRegex = /^(?=(\#?)[a-fA-F0-9]$)(?:.{3}|.{6})$/i
    const hexRegex = /^(\#?[a-fA-F0-9]{3}|\#?[a-fA-F0-9]{6})$/i
    //const hexaRegex = /^(\#?)[a-fA-F0-9]{4,8}$/i
    //const hexaRegex = /^(?=\#?[a-fA-F0-9]$)(?:.{4}|.{8})$/i
    const hexaRegex = /^(\#?[a-fA-F0-9]{4}|\#?[a-fA-F0-9]{8})$/i
    const rgbRegex = /^rgb\(\s*\d{1,3}\s*,?\s*\d{1,3}\s*,?\s*\d{1,3}\s*\)$/i
    //const rgbaRegex = /^rgba\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*(0(\.[0-9])?|1(\.0)?)\s*\)/i
    const rgbaRegex = /^rgb(a?)\(\s*\d{1,3}\s*,?\s*\d{1,3}\s*,?\s*\d{1,3}\s*(,|\/)*\s*((0(\.[0-9]{1,3}))?|(1(\.0{1,3}))?|([1-9][0-9]?|100))\s*\)$/i
    const hslRegex = /^hsl\(\s*\d{1,3}\s*,?\s*\d{1,3}(\.[0-9])?%\s*,?\s*\d{1,3}(\.[0-9])?%\s*\)\s*$/i
    //const hslaRegex = /^hsla\(\s*\d{1,3}\s*,*\s*\d{1,3}(\.[0-9])?%\s*,*\s*\d{1,3}(\.[0-9])?%\s*(,|\/)*\s*((0(\.[0-9]{1,3}))?|(1(\.0{1,3}))?)\s*\)/i
    const hslaRegex = /^hsl(a?)\(\s*\d{1,3}\s*,?\s*\d{1,3}(\.[0-9])?%\s*,?\s*\d{1,3}(\.[0-9])?%\s*(,|\/)*\s*((0(\.[0-9]{1,3}))?|(1(\.0{1,3}))?|([1-9][0-9]?|100))\s*\)\s*$/i

    // computed properties
    /*let compVariable = computed(() => {
      //return 'foo'
    })*/

    // watchers
    /*watch(inputBox, (newValue, oldValue) => {
      //
    })*/

    // lifecycle hooks
    onBeforeMount(() => {
      inputBox.value = defaultInputs.join("\n")
    })

    onMounted(() => {
      batchConvert()
    })

    // methods
    function batchConvert() {
      convertedColors.value = []

      // first attempt to split by new-line characters
      let inputArray = inputBox.value.split('\n')
      let count = inputArray.length

      for (let i = 0; i < count; i++) {
        // check for empty line, non hex(a)/rgb(a)/hsl(a) string
        let inputLine = inputArray[i].toLowerCase().trim()
        if (inputLine.length === 0) {
          continue
        }

        let converted = {
          error: false,
          raw: inputLine,
          hex: "",
          rgb: "",
          hsl: "",
        }

        let rgb = { red: null, green: null, blue: null, alpha: null }
        let hsl = { hue: null, saturation: null, lightness: null, alpha: null }

        if (hexRegex.test(inputLine)) {
          let hexString = inputLine

          // doing this just to add pound symbol for the table output
          // if it doesn't already exist and to allow the use of
          // the hex value without leading pound symbol
          // for conversion to other formats.
          hexString = hexString.replace('#', '')

          rgb = Color.hexToRgb(hexString)
          hsl = Color.rgbToHsl(rgb.red, rgb.green, rgb.blue)

          converted.hex = "#" + hexString
          converted.rgb = "rgb(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ")"
          converted.hsl = "hsl(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%)"
        } else if (hexaRegex.test(inputLine)) {
          let hexString = inputLine
          hexString = hexString.replace('#', '')

          rgb = Color.hexaToRgba(hexString)
          hsl = Color.rgbaToHsla(rgb.red, rgb.green, rgb.blue, rgb.alpha)

          converted.hex = "#" + hexString
          converted.rgb = "rgba(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ", " + rgb.alpha + ")"
          converted.hsl = "hsla(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%, " + hsl.alpha + ")"
        }

        if (rgbRegex.test(inputLine)) {
          // extract the values for red, green, blue.
          let rgbStrArray = inputLine.split(',')
          if (rgbStrArray.length !== 3) {
            rgbStrArray = inputLine.split(' ')
          }
          let red = Number.parseInt(rgbStrArray[0].replace('rgb(', '').trim())
          let green = Number.parseInt(rgbStrArray[1].trim())
          let blue = Number.parseInt(rgbStrArray[2].replace(')', '').trim())

          hsl = Color.rgbToHsl(red, green, blue)

          converted.hex = "#" + Color.rgbToHex(red, green, blue)
          converted.rgb = "rgb(" + red + ", " + green + ", " + blue + ")"
          converted.hsl = converted.hsl = "hsl(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%)"
        } else if (rgbaRegex.test(inputLine)) {
          // extract the values for red, green, blue, alpha.
          let alphaIndex = 3
          let rgbaStrArray = inputLine.split(',')
          if (rgbaStrArray.length !== 4) {
            alphaIndex = 4
            rgbaStrArray = inputLine.split(' ')
          }
          let red = Number.parseInt(rgbaStrArray[0].replace('rgb(', '').replace('rgba(', '').trim())
          let green = Number.parseInt(rgbaStrArray[1].trim())
          let blue = Number.parseInt(rgbaStrArray[2].trim())
          let alpha = rgbaStrArray[alphaIndex].replace(')', '').trim()
          if (alpha > 1) { alpha /= 100 }

          hsl = Color.rgbToHsl(red, green, blue)

          converted.hex = "#" + Color.rgbaToHexa(red, green, blue, alpha)
          converted.rgb = "rgba(" + red + ", " + green + ", " + blue + ", " + alpha + ")"
          converted.hsl = "hsla(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%, " + alpha + ")"
        }

        if (hslRegex.test(inputLine)) {
          // extract the values for hue, saturation, lightness.
          let hslStrArray = inputLine.split(',')
          if (hslStrArray.length !== 3) {
            hslStrArray = inputLine.split(' ')
          }
          let hue = hslStrArray[0].replace('hsl(', '').trim()
          let saturation = hslStrArray[1].replace('%', '').trim()
          let lightness = hslStrArray[2].replace('%', '').replace(')', '').trim()

          rgb = Color.hslToRgb(hue, saturation, lightness)

          converted.hex = "#" + Color.hslToHex(hue, saturation, lightness)
          converted.rgb = "rgb(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ")"
          converted.hsl = "hsl(" + hue + ", " + saturation + "%, " + lightness + "%)"
        } else if (hslaRegex.test(inputLine)) {
          // extract the values for hue, saturation, lightness, alpha.
          let alphaIndex = 3
          let hslaStrArray = inputLine.split(',')
          if (hslaStrArray.length !== 4) {
            alphaIndex = 4
            hslaStrArray = inputLine.split(' ')
          }
          let hue = hslaStrArray[0].replace('hsl(', '').replace('hsla(', '').trim()
          let saturation = hslaStrArray[1].replace('%', '').trim()
          let lightness = hslaStrArray[2].replace('%', '').trim()
          let alpha = hslaStrArray[alphaIndex].replace(')', '').trim()
          if (alpha > 1) { alpha /= 100 }

          rgb = Color.hslaToRgba(hue, saturation, lightness, alpha)

          converted.hex = "#" + Color.hslaToHexa(hue, saturation, lightness, alpha)
          converted.rgb = "rgb(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ", " + alpha + ")"
          converted.hsl = "hsla(" + hue + ", " + saturation + "%, " + lightness + "%, " + alpha + ")"
        }

        convertedColors.value.push(converted)
      }
    }

    function updateClipboard (text) {
      clipboard.writeText(text).then(() => {
        showErrorMessage = false
        showStatusMessage = true
        setTimeout(() => {
          showStatusMessage = false
        }, 1000)
      })
      .catch(() => {
        showStatusMessage = false
        showErrorMessage = true
        setTimeout(() => {
          showErrorMessage = false
        }, 1000)
      })
    }

    return {
      inputBox,
      convertedColors,
      showStatusMessage,
      showErrorMessage,
      batchConvert,
      updateClipboard,
    }
  },
})
</script>

<style>
@import './assets/base.css'

</style>
