/*
 * Menu and navigation
 */
/* Small helpers */
function cell(text) {
    html = ""
    html += '  <div class="rTableCell">';
    html += text;
    html += '  </div>';
    return html
}
/* Convert a list of table items to an HTML DIV table */
function toDIVTable(rows) {
    if (rows.length == 0)
        html = "no results";
    else {
        html = '<div class="rTable">';
        rows.forEach(row => {
            id = row['id'];
            info = row['info'];
            html += '<div class="rTableRow">';
            html += cell('<a href="'+info+'">'+id+'</a>');
            html += cell('<a href="'+row['collection']+'">Collection</a>');
            html += cell('<a href="'+row['fasta']+'">FASTA</a>');
            html += cell('<a href="/api/ebi/sample-'+id+'.xml">EBI/ENA export XML</a>');
            html += '</div>';
        });
        html += '</div>';
    }
    console.log(html);
    document.getElementById("table").innerHTML = html;
}
/* Toggle between adding and removing the "responsive" class to topnav
 * when the user clicks on the icon */
function myFunction() {
    var x = document.getElementById("myTopnav");
    if (x.className === "topnav") {
        x.className += " responsive";
    } else {
        x.className = "topnav";
    }
}
function fetchAPI(apiEndPoint,injectHTML=NULL) {
    fetch(scriptRoot + apiEndPoint)
        .then(response => {
            console.log("* response",response);
            return response.json();
        })
        .then(data => {
            console.log("* data",data);
            if (injectHTML)
                injectHTML(data);
        });
}
// Copy from function above but now output HTML table instead of plain json
function fetchHTMLTable(apiEndPoint) {
    fetch(scriptRoot + apiEndPoint)
        .then(response => {
            return response.json();
        })
        .then(data => {
            console.log(data)
            htmlString="<table>"
            for (var i=0; i<data.length;i++) {
                let url = data[i]["key"];
                continents = ["Q538", "Q48", "Q49", "Q18", "Q15", "Q27611" ];
                node = url.split("/").pop();
                console.log(continents.includes(node));
                if (url.includes("wikidata") && !continents.includes(node)) {
                    url = "http://covid19.genenetwork.org/location?label="+url ;
                }
                let label = data[i]["label"];
                htmlString=htmlString+"<tr><td><a href=\""+url+"\">"+label+"</a></td><td>"+data[i]["count"]+"<td></tr>"
            }
            htmlString=htmlString+"</table>"
            document.getElementById("table").innerHTML = htmlString
        });
}
// changing access for Demo page
function demofetchHTMLTable(apiEndPoint) {
    fetch(scriptRoot + apiEndPoint)
        .then(response => {
            return response.json();
        })
        .then(data => {
            console.log(data);
            htmlString="<h3>Description</h3><p>"+data[0][0]["description"]+"</p>"
            prefix=data[0][1]["prefix"].replace(/</g,"<");
            htmlString+="<h4>Namespace</h4><pre>"+prefix+"</pre>"//prefix to construct correct query @data[0][1]["prefix"]
            htmlString+="<h3>SPARQL query</h3><pre>"+data[0][2]["query"]+"</pre>"
            htmlString+="<h3>SPARQL results table</h3><table>"
            keys=Object.keys(data[1][0])
           // Add keys as table headers
            htmlString+="<tr>"
            for (var j=0; j<keys.length;j++){
                    htmlString+="<td style='font-weight: bold;'>"+keys[j]+"</bold></td>"
                }
            //Go through the results set given the keys and fill the tail of the table
            for (var i=0; i<data[1].length;i++) {
                htmlString+="</tr><tr>"
                for (var j=0; j<keys.length;j++){
                    content = data[1][i][keys[j]];
                    if (content.startsWith("http://")) {
                        content = "<a href=\""+content+"\">"+content+"</a>";
                    }
                    htmlString+="<td>"+content+"</td>"
                }
                htmlString+="</tr>"
            }
            htmlString=htmlString+"</table>"
            //Something like this would be nice, hm
            //htmlString+="Execute this query <a href='http://sparql.genenetwork.org/sparql?query='"+encodeURIComponent(encodeURIComponent(data[0][1]["prefix"]+data[0][2]["query"]))+"'>here</a>"
            document.getElementById("playground").innerHTML = htmlString
        });
}
/* Fetch record info using a 'global search'. Returns for example
[
  {
    "id": "MT326090.1",
    "seq": "http://collections.lugli.arvadosapi.com/c=10eaef75e0b875f81aa1f411c75370cf+126/sequence.fasta"
  },
  {
    "id": "MT326090.1",
    "seq": "http://collections.lugli.arvadosapi.com/c=5a4c815f3e076ad7760a91864c39dd07+126/sequence.fasta"
  }
]
 */
let searchGlobal = (toHTML) => {
    let m =  document.getElementById('search-input').value;
    fetchAPI(scriptRoot + "/api/search?s=" + encodeURIComponent(m), toHTML);
}
// Same as above, but generates div table
let searchGlobaltoDIVTable = () => {
    searchGlobal(toDIVTable);
}
let searchSeq = () => {
  let m =  document.getElementById('search-input').value;
  fetchAPI(scriptRoot + "/api/getDetailsForSeq?seq=" + encodeURIComponent(m));
}
// Get count from Arvados
let fetchCount = () => {
  fetchAPI("/api/getCount");
}
// Get count from Virtuoso
let fetchCountDB = () => {
  fetchAPI("/api/getCountDB");
}
//////  old API functions, some might no be used //
let fetchSEQCountByTech = () => {
  fetchHTMLTable("/api/getSEQCountbytech");
}
let fetchAllaccessions = () => {
  fetchHTMLTable("/api/getAllaccessions");
};
let fetchMap = () => {
    fetchAPI("/api/getCountByGPS");
    updateMapMarkers();
};
let fetchSEQByLocation = () => {
  console.log("Missing - set parameter for request, retrieve data")
};
let fetchSEQCountbyContinent = () => {
  fetchHTMLTable("/api/getSEQCountbyContinent");
}
/////////////////////////////////// End "old" function
////****** SPARQL playground functions ***************////
let demoFetchSEQCountBySpecimen = (toHTML) => {
  //fetchHTMLTable("/api/getSEQCountbySpecimenSource");
  demofetchHTMLTable("/api/demoGetSEQCountbySpecimenSource")
}
let demoFetchSEQCountByLocation = () => {
  //fetchHTMLTable("/api/getSEQCountbyLocation");
  demofetchHTMLTable("/api/demoGetSEQCountbyLocation")
}
//Get authors and there country/contitent where they come from
let demoGetAuthors = () => {
    demofetchHTMLTable("/api/demoGetAuthors")
}
// Fetch all institutes/originating labs and their associeted publications
let demoFetchInstitutesPublications = () => {
    demofetchHTMLTable("/api/demoInstitutesPublications")
}
// Fetch sequence technology used by continent
let demoGetSEQCountbytechContinent = () => {
    demofetchHTMLTable("/api/demoGetSEQCountbytechContinent")
}
let demoGetSEQCountbytech = () => {
    demofetchHTMLTable("/api/demoGetSEQCountbytech")
}
let demoGetSequencePerDate = () => {
    demofetchHTMLTable('/api/demoGetSequencePerDate')
}
let demoGetLocationGps = () => {
    demofetchHTMLTable("/api/demoGetLocationGps")
}
let demoGetNYsamples = () => {
    demofetchHTMLTable("/api/demoGetNYsamples")
}
let demoGetSouthAmericaSeq = () => {
    demofetchHTMLTable("/api/demoGetSouthAmericaSeq")
}
let demoGetSeqByAgeGender = () => {
    demofetchHTMLTable("/api/demoGetSeqByAgeGender")
}
let demoGetSeqIllumina = () => {
    demofetchHTMLTable("/api/demoGetSeqIllumina")
}
let demoGetSeqWithStrain = () => {
    demofetchHTMLTable("/api/demoGetSeqWithStrain")
}
let demoGetContinentSpecimentSeqCount = () => {
    demofetchHTMLTable("/api/demoGetContinentSpecimentSeqCount")
}
let demoGetSampleSchema= () => {
    demofetchHTMLTable("/api/demoGetSampleSchema")
}
////****** SPARQL playground functions ***************////
/*
 * Make sure that only one of the manual metadata entry and metadata upload
 * form components is *actually* a child of the form element in the DOM.
 *
 * Because both make use of the "required" attribute, we can't get away with
 * just hiding the one we don't want the user to fill in. The hidden part will
 * still have possibly empty required fields and (some) browsers will
 * blocksubmission because of it. Moreover, the data (including file uploads)
 * from the hidden elements will still be sent to the server, which the user
 * may not expect.
 */
function setUploadMode() {
  // Make the upload form the one in use.
  uploadFormSpot.appendChild(uploadForm)
  // Remove the upload form from the DOM so its required-ness does not block submission.
  fillFormSpot.removeChild(fillForm)
}
function setFillMode() {
  // Make the fillable form the one in use
  uploadFormSpot.removeChild(uploadForm)
  // Remove the fillable form from the DOM so its required-ness does not block submission.
  fillFormSpot.appendChild(fillForm)
}
function setMode() {
  // Pick mode based on radio
  if (document.getElementById('metadata_upload').checked) {
    setUploadMode()
 } else {
    setFillMode()
 }
}
/*
 * Machinery for variable-length lists of input items.
 */
// Start in mode appropriate to selected form item.
// It is important that we run this code when the page starts! The browser may
// have set the radio button to whatever the state was on last page load,
// instead of the default state, without raising an event, and we have to
// handle that.
/**
 * Add another form field to the group this button is part of.
 */
function addField(e) {
  // Find our parent field-group div
  let fieldGroup = this.parentElement
  // Get its keypath
  let keypath = fieldGroup.dataset.keypath
  // Find its last field child
  let existingFields = fieldGroup.getElementsByClassName('field')
  let templateField = existingFields[existingFields.length - 1]
  // Get its number
  let fieldNumber = templateField.dataset.number
  // Duplicate it
  let newField = templateField.cloneNode(true)
  // Increment the number and use the keypath and number to set IDs and cross
  // references.
  // TODO: Heavily dependent on the form field HTML. Maybe we want custom
  // elements for the labeled controls that know how to be list items?
  fieldNumber++
  newField.dataset.number = fieldNumber
  let newID = keypath + '[' + fieldNumber + ']'
  let newControl = newField.getElementsByClassName('control')[0]
  newControl.id = newID
  newControl.setAttribute('name', newID)
  let newLabel = newField.getElementsByTagName('label')[0]
  newLabel.setAttribute('for', newID)
  // Find the minus button
  let minusButton = fieldGroup.getElementsByClassName('remove-field')[0]
  // Put new field as a child before the minus button
  fieldGroup.insertBefore(newField, minusButton)
  // Enable the minus button
  minusButton.classList.remove('invisible')
}
/**
 * Remove the last form field from the group button is part of.
 */
function removeField(e) {
  // Find our parent field-group div
  let fieldGroup = this.parentElement
  // Find its field children
  let existingFields = fieldGroup.getElementsByClassName('field')
  if (existingFields.length > 1) {
    // There is a last field we can safely remove.
    let lastField = existingFields[existingFields.length - 1]
    fieldGroup.removeChild(lastField)
  }
  if (existingFields.length <= 1) {
    // Collection auto-updates. Now there's only one element. Don't let the
    // user remove it. If they don't want it, they can leave it empty.
    this.classList.add('invisible')
  }
}
// Change the submit button after hitting
function on_submit_button() {
    var f = document.getElementsByTagName('form')[0];
    if(f.checkValidity()) {
        var elem = document.getElementById("submit");
        elem.value = "Submitting...";
        elem.disabled = true;
        f.submit();
    } else {
        alert(document.getElementById('example').validationMessage);
        return false;
    }
}