<template>
<div class="picker">
    <div class="images">
        <!--suppress HtmlUnknownTarget -->
        <img v-for="file in files" :alt="file.name" :src="dataURLs[file.name]" @click="confirmDelete(file)"/>
    </div>
    <input class="browse" type="file" accept="image/*" multiple @change="loadImages($event)">
</div>
</template>

<script lang="ts">
import {Component, Vue, Watch} from "vue-property-decorator";

@Component
export default class Picker extends Vue {
    private files: File[] = [];
    private dataURLs: { [key: string]: string } = {};
    private bitmaps: { [key: string]: ImageBitmap } = {};

    private loadImages(event: Event) {
        Object.values(this.dataURLs).forEach((url) => {
            URL.revokeObjectURL(url);
        });
        this.dataURLs = {};

        this.files = Array.from((event.target as HTMLInputElement).files || []);
        this.files.forEach((file: File) => {
            this.dataURLs[file.name] = URL.createObjectURL(file);
        });

        const bitmapPromises: Promise<[string, ImageBitmap]>[] =
          Object.entries(this.dataURLs).map(([filename, url]) => {
              return new Promise((resolve) => {
                  const image = new Image();
                  image.onload = () => {
                      createImageBitmap(image).then((bitmap) => {
                          resolve([filename, bitmap]);
                      });
                  };
                  image.src = url;
              });
          });

        Promise.all(bitmapPromises).then((bitmaps) => {
            this.bitmaps = {};
            bitmaps.forEach(([filename, bitmap]) => {
                this.bitmaps[filename] = bitmap;
            });
            this.$emit("images", Object.values(this.bitmaps));
        });
    }

    private confirmDelete(file: File) {
        if (window.confirm(`Remove ${file.name}?`)) {
            this.files.splice(this.files.indexOf(file), 1);
            URL.revokeObjectURL(this.dataURLs[file.name]);
            delete this.dataURLs[file.name];
            delete this.bitmaps[file.name];

            this.$emit("images", Object.values(this.bitmaps));
        }
    }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.picker {
    border: 1px solid black;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.images {
    min-height: 120px;
    display: flex;
    overflow-x: scroll;
}

.images img {
    height: 120px;
    margin: .5rem;
    cursor: pointer;
}

.browse {
    min-width: 16em;
    margin: 2em;
}
</style>
