<script>
    export let data;
    const { webservices } = data;

    console.log('orig affiliates:', webservices.affiliates);
    console.log('orig hosts:', webservices.hosts);

    // source: https://mokole.com/palette.html 20 colors with default settings otherwise
    const colours30 = [ "#808080", "#7f0000", "#006400", "#808000", "#483d8b", "#008b8b", "#cd853f", "#00008b", "#7f007f", "#8fbc8f", "#b03060", "#ff0000", "#ff8c00", "#00ff00", "#9400d3", "#00ff7f", "#dc143c", "#00ffff", "#00bfff", "#0000ff", "#f08080", "#adff2f", "#1e90ff", "#ffff54", "#90ee90", "#add8e6", "#ff1493", "#7b68ee", "#ee82ee", "#ffe4b5" ];

    function processData(webservices) {
        let instances = 0;
        let current = [];
        let current_status = [];
        let future = [];
        // properties of technologies
        let categories = [];
        let analogues = [];
        let licenses = [];
        // properties of instances
        let statuses = [];
        let affiliates = [];

        let hosts = [];
        let host_data = [];
        let affiliate_data = [];
        //
        // just a trivial reassignment
        //let hosts = webservices.hosts;
        //
        // pull out relevant info in useful chunks.
        for (let key in webservices.technologies) {
            let tech = webservices.technologies[key];
            if (tech.hasOwnProperty('categories') && tech.categories.constructor === Array ) {
                tech.categories.forEach(function(category, index) {
                    if (categories.hasOwnProperty(category)) categories[category]++;
                    else categories[category] = 1;
                });
            }
            if (tech.hasOwnProperty('analogues') && tech.analogues.constructor === Array ) {
                tech.analogues.forEach(function(analogue, index) {
                    if (analogues.hasOwnProperty(analogue)) analogues[analogue]++;
                    else analogues[analogue] = 1;
                });
            }
            if (tech.hasOwnProperty('license')) {
                let license = tech.license;
                if (licenses.hasOwnProperty(license)) licenses[license]++;
                else licenses[license] = 1;
            }

            if (hasInstances(tech)) {
                tech['name'] = key;
                current.push(tech);
                //console.log(tech.name + ': ' + tech.instances.length + ' instances...');
                tech.instances.forEach(function(instance, i) {
                    instances++;
                    if (instance.hasOwnProperty('status')) {
                        let tag = instance.status;
                        if (statuses.hasOwnProperty(tag)) statuses[tag]++;
                        else statuses[tag] = 1;
                    }
                    if (instance.hasOwnProperty('affiliation')) {
                        let tag = instance.affiliation;
                        if (affiliates.hasOwnProperty(tag)) affiliates[tag]++;
                        else affiliates[tag] = 1;
                    }
                    if (instance.hasOwnProperty('host')) {
                        let tag = instance.host;
                        if (hosts.hasOwnProperty(tag)) hosts[tag]++;
                        else hosts[tag] = 1;
                    }
                });
            } else {
                future[key] = tech;
            }

        };
        for (let key in webservices.hosts) {
            //console.log('key: ', key);
            let host = webservices.hosts[key];
            host['name'] = key;
            //console.log('host: ', host);
            if (host.hasOwnProperty('domain') && !(host.hasOwnProperty('status') && host.status == 'retired')) {
                host_data[key] = host;
            }
        }
        console.log('webservices.affiliates: ', webservices.affiliates);
        for (let key in webservices.affiliates) {
            console.log('key: ', key);
            let affiliate = webservices.affiliates[key];
            console.log('affiliate assignment: ', affiliate);
            affiliate_data[key] = affiliate;
           // if (affiliate.hasOwnProperty('name')) {
               // affiliate_data[key] = affiliate;
           // }
        }
        //console.log('categories: ', categories);
        //console.log('analogues: ', analogues);
        //console.log('licenses: ', licenses);
        //console.log('statuses: ', statuses);
        //console.log('affiliates: ', affiliates);
        //console.log('hosts: ', hosts);

        return {
            total_instances: instances,
            active_services: current,
            candidate_services: future,
            tech_tags: {
               categories: categories,
               analogues: analogues,
               licenses: licenses
            },
            instance_tags: {
                statuses: statuses,
                affiliates: affiliates,
                hosts: hosts
            },
            hosts: host_data,
            affiliates: affiliate_data
        };
    }

//    console.log(technologies);
    function hasInstances(tech) {
        if (tech.hasOwnProperty('instances') && tech.instances.constructor === Array && tech.instances.length) return true;
        return false;
    }

    function getKeys(ob) {
        let keys = [];
        for (let key in ob) {
            keys.push(key);
            //console.log('pushing key ' + key);
        };
        return keys;
    }

    function toOxfordCommaString(arr) {
        if (arr.length == 1) return arr;
        else {
            var last = arr.pop();
            return arr.join(', ') + ', and ' + last;
        }
    }

    function hostColours(hosts, colours, host_data) {
        let host_array = {};
        let i = 0;

        //console.log('host_data:', host_data);

        hosts.forEach(function(host) {
            //console.log(host);
            if (host_data[host].hasOwnProperty('domain') && host_data[host].hasOwnProperty('affiliation')) {
                host_array[host] = {
                    "colour": colours[i++],
                    "domain": host_data[host].domain,
                    "affiliation": host_data[host].affiliation
                }
            }
        });
        return host_array;
    }

    function affiliateColours(affiliates, colours, affiliate_data) {
        let affiliate_array = {};

        console.log('affiliate_data_full:', affiliate_data);

        for (const affiliate of affiliates) {
            console.log('affiliate:', affiliate);
            if (affiliate_data[affiliate].hasOwnProperty('name') && affiliate_data[affiliate].hasOwnProperty('website')) {
                affiliate_array[affiliate] = {
                    "colour": colours[i++],
                    "name": affiliate_data[affiliate].name,
                    "website": affiliate_data[affiliate].website
                }
            }
        }
        return affiliate_array;
    }


    const results = processData(webservices);
    //console.log('results: ', results);

    //const technologies = webservices.technologies;
    const technologies = results.active_services;
    //console.log(technologies);

    const categories = getKeys(results.tech_tags.categories).sort();
    const analogues = getKeys(results.tech_tags.analogues).sort();
    const licenses = getKeys(results.tech_tags.licenses).sort();
    const statuses = getKeys(results.instance_tags.statuses).sort();
    const affiliates = getKeys(results.instance_tags.affiliates).sort();
    const hosts = getKeys(results.instance_tags.hosts).sort();

    const host_data = results.hosts;
    //console.log('host_data: ', results.hosts);
    const affiliate_data = results.affiliates;
    console.log('affiliate_data: ', results.affiliates);
    const host_colours = hostColours(hosts, colours30, host_data);
    //console.log('host_colours:', host_colours);
    const affiliate_colours = affiliateColours(affiliates, colours30, affiliate_data);
    console.log('affiliate_colours:',affiliate_colours);

    //console.log('categories array: ', results.tech_tags.categories);
    //console.log('categories keys: ', categories);

</script>

<div class="webservices">
    <h1>Web Services</h1>

    <div class="summary">
        <ul>
            <li>Total number of services: {results.total_instances}</li>
        </ul>
    </div>
    <div class="filters">
        <div class="tag-list tech">
            <div class="tags tech categories">Categories: {#each categories as category}<span class="tag category">{category}</span> {/each}</div>
            <!--<div class="tags tech analogues">{#each analogues as analogue}<span class="tag analogue">{analogue}</span> {/each}</div>-->
            <div class="tags tech licenses">Licenses: {#each licenses as license}<span class="tag license">{license}</span> {/each}</div>
        </div>
        <div class="tag-list instance">
            <div class="tags instance statuses">Statuses: {#each statuses as status}<span class="tag status">{status}</span> {/each}</div>            <div class="tags instance affiliates">Affiliates: {#each affiliates as affiliate}<span class="tag affilate">{affiliate}</span> {/each}</div>
            <div class="tags instance hosts">Hosts: {#each hosts as host}<span class="tag host">{host}</span> {/each}</div>
        </div>
    </div>
    <div class="tiles">
        {#each technologies as technology}
        <div class="tile technology">
            <h2><a href="{technology.website}">{technology.name}</a></h2>
            {#if (technology.license)}<p class="license" title="The libre license for this project is {technology.license}">License: <span class="value">{technology.license}</span></p>{/if}
            {#if (technology.analogues)}<p class="analogues">Alternative to <span class="value">{toOxfordCommaString(technology.analogues)}</span></p>{/if}
            <p class="description">{technology.description}</p>
            {#if hasInstances(technology)}
            <div class="instances">
                <ul class="instances">
                    {#each technology.instances as instance}
                    <li><a href="https://{instance.domain}"><span style="{affiliate_colours[instance.affiliate]}.colour"></span></a> <span class="affiliation {instance.affiliation}">{instance.affiliation}</span></li>
                    {/each}
                </ul>
            </div>
            {:else}
            <div class="instances cell">
                <ul class="instances">
                    <li>Nothing here yet...</li>
                </ul>
            </div>
            {/if}
        </div>
        {/each}
    </div>
</div>

<style>
    .webservices {
        display: grid;
        width: 96%;
        margin: 0 auto 3em auto;
        padding: 0;
    }
    .summary {
    }
    .filters {
        /*background-color: #f1ff94;
        padding: 0.5em;
        border: 3px solid #cbea77;
        margin: 1em 0;*/
        margin-bottom: 1em;
    }
    .filters .tags {
        /*padding: 0.5em;*/
        margin: 1em 0;
        display: block;
    }
    .tag-list {
        white-space: normal;
        word-break: normal;
        display: inline;
    }
    .tag {
        font-size: 80%;
        color: #777;
        margin-right: 0.5em;
        line-height: 2;
        background-color: #a369a2;
        color: #fff;
        padding: 4px 8px;
        border-radius: 10px;
        white-space: nowrap;
        word-break: keep-all;
    }
    .tag:after { content: "\00a0"; }
    .tiles {
        display: grid;
        grid-gap: 15px;
        grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    }
    /* flip card stuff: https://www.w3schools.com/howto/howto_css_flip_card.asp */
    .tile {
        height: 400px;
        min-width: 250px;
        max-width: 400px;
        overflow: hidden;
        box-sizing: border-box;
        box-shadow: 5px 5px 3px #71ba71;
        border: solid 3px #1e6831;
        text-overflow: ellipsis;
        overflow: hidden;
        position: relative;
    }
    .tile h2 {
        background-color: #999;
        text-align: center;
        padding: 0.5em;
        margin: 0;
    }
    .tile h2 a { color: #e6c4fc; }
    .tile h2 a:visited { color: #ced0ff; }
    .tile h2 a:hover { color: #fff; }
    .tile .description {
        height: 200px;
        text-overflow: ellipsis;
        overflow: hidden;
    }
    .tile p {
        padding: 0 1em 0.2em 1em;
        font-size: 80%;
        color: #555;
    }
    .tile .instances {
        background-color: #c2e6c2;
        position: absolute;
        bottom: 0;
        height: 3em;
        width: 100%;
    }
    .tile .instances ul {
        margin-bottom: 0px;
    }
    .webservices li { list-style-type: none; }
    .value { font-weight: bold; color: #000; }
    .triangle {
        --side-size: 20px;
        border-left: var(--side-size) solid transparent;
        border-right: var(--side-size) solid transparent;
        border-bottom: calc(2 * var(--side-size) * 0.866) solid green;
        border-top: var(--side-size) solid transparent;
        display: inline-block;
    }
    .circle {
        height: 20px;
        width: 50px;
        background-color: #555;
        border-radius: 50%;
    }
    .square {
        height: 20px;
        width: 50px;
    }
</style>
