// There are a number of checks in here to make this script work both in the IE8 embedded in Desktop HV, AND in 
// "modern" browsers in the context of Browser HV.  See T2116, T2142, and T2174.  Any changes to this script must be 
// checked both contexts.

var headers = []; 
var clonedHeaders = [];
var lastResizeTimer = -1;
var sortTables = [];

// The sort arrow characters
var UP_EMPTY = String.fromCharCode(0x25B3);
var DOWN_EMPTY = String.fromCharCode(0x25BD);
var UP_FILLED = String.fromCharCode(0x25B2);
var DOWN_FILLED = String.fromCharCode(0x25BC);

// console.log won't work in IE8 when no console is present (i.e. in the embedded Internet Explorer in Desktop HV),
// so use "safeLog" for debug prints.
function safeLog(message) {
    if (typeof console !== 'undefined' && typeof console.log !== 'undefined') {
        console.log(message);
    } else {
        // Fallback for browsers without console or when console is not open
        //            alert("IE8 "+message);
    }
}

// AddEventListener availability depends on browser version.
var bAddEventListenerAvailable = false;
if (typeof window.addEventListener === 'function') {
    bAddEventListenerAvailable = true;
}
else {
    bAddEventListenerAvailable = false;
}

// Called after the document contents are loaded.  This is necessary in Browser HV -- otherwise the .sticky stuff hasn't loaded yet.
function onDOMLoaded( e ) {
        
    // Get the headers to be made "sticky"
    headers = document.querySelectorAll('.sticky');  
    for (var i = 0; i < headers.length; i++) {

        var header = headers[i];
        var clone = header.cloneNode(true);

        clone.style.visibility = 'hidden'; 
        clone.style.position = 'fixed';
        clone.style.width = '100%';
        clone.style.top = '0px';
        clone.style.zIndex = '100';
        clone.style.backgroundColor = 'fff';

        headers[i].parentElement.insertBefore(clone, header);
        clonedHeaders.push(clone);
    }
    
    // Get the sortable tables
    sortTables = document.querySelectorAll('table.sortable');
    for (var i = 0; i < sortTables.length; i++) {
        
        var table = sortTables[i];
        var tableHeaders = table.querySelectorAll('th.sort');        
        var numColumns = table.querySelector('tbody').children[0].children.length;
        
        for (var j = 0; j < tableHeaders.length; j++) {
            
            var header = tableHeaders[j];
            
            var headerTable = document.createElement('table');
            
            var titleText = document.createElement('td');
            titleText.className = 'column-title';
            titleText.innerHTML = header.innerHTML;
            header.innerHTML = '';
        
            var triangles = document.createElement('td');
            triangles.className = 'triangles';
            
            var upperTriangle = document.createElement('div');
            upperTriangle.innerText = UP_EMPTY;
            
            var lowerTriangle = document.createElement('div');
            lowerTriangle.innerText = DOWN_EMPTY;
            
            triangles.appendChild(upperTriangle);
            triangles.appendChild(lowerTriangle);
            
            headerTable.appendChild(titleText);
            headerTable.appendChild(triangles);
            
            header.appendChild(headerTable);
            
            header.sortTableIdx = i;
            header.columnIdx = j % numColumns;
            
            // Adding the event listeners this way, but in fact the old style seems to work in Browser HV
            if (bAddEventListenerAvailable) {
                header.addEventListener( "dblclick", onSortDoubleClick ); 
                header.addEventListener( "click", onSortClick ); 
            }
            else {
                header.ondblclick = onSortDoubleClick;            
                header.onclick = onSortClick;
            }            
        }
    }
    
    doResize();   
}

function onScroll() {

    for (var i = 0; i < headers.length; i++) {

        var header = headers[i];
        var clone = clonedHeaders[i];
        var rect = header.getBoundingClientRect();

        clone.style.left = rect.left + 'px';
        
        if (rect.top < 0) {        
            clone.style.zIndex = '100';
            clone.style.visibility = 'visible';
        }
        else {
            clone.style.zIndex = '0';
            clone.style.visibility = 'hidden';
        }
    }
}

// Update the clone with current "real" widths
function cloneWidths(clone, original) {
      
     // Necessary to add "px" for Browser HV to work. IE8 in Desktop HV seems to work without px.
    clone.style.width = original.clientWidth + 'px';     
    for (var i = 0; i < original.children.length; i++) {
        cloneWidths(clone.children[i], original.children[i]);
    }
}

function doResize() {
     for (var i = 0; i < headers.length; i++) {
        cloneWidths(clonedHeaders[i], headers[i]);
    }
}

function onResize() {
    clearTimeout(lastResizeTimer);
    lastResizeTimer = setTimeout(doResize, 150);
}

// This only seems to work in Desktop HV (IE8), not in Browser HV.
function onSortDoubleClick(event) {
    event = event || window.event;
    event.preventDefault();
    onSortClick(event);
}

function onSortClick(event) {
    
    event = event || window.event;
    target = event.target || event.srcElement;
    
    while (target.tagName != 'TH') {
        target = target.parentElement;
    }
    
    var reverse = target.querySelector('.triangles').children[0].innerText == UP_FILLED;
    
    var table = sortTables[target.sortTableIdx];
    var tableBody = table.querySelector('tbody');   
    var oldRows = table.querySelectorAll('tbody tr');
    
    var rows = [];
    for (var i = 0; i < oldRows.length; i++) {
        rows.push(oldRows[i].cloneNode(true));
    }
    
    var useSortVal = rows[0].children[target.columnIdx].getAttribute("data-sortval") != undefined;
    
    rows.sort(function(a, b) {
        
        var cellA = a.children[target.columnIdx];
        var cellB = b.children[target.columnIdx];
        
        // T2336
        var cellABlank = cellA.innerText == "";
        var cellBBlank = cellB.innerText == "";
        
        if (cellABlank && cellBBlank) {
            return 0;
        }
        else if (cellABlank) {
            return 1;
        }
        else if (cellBBlank) {
            return -1;
        }
        
        var cmp;
        if (useSortVal) {
            cmp = cellA.getAttribute("data-sortval") - cellB.getAttribute("data-sortval");
        }
        else {
            var str1 = cellA.innerText;
            var str2 = cellB.innerText;
        
            cmp = str1.localeCompare(str2);
        }
        
        if (reverse) {
            cmp = -cmp;
        }
        
        return cmp;
        
    });
    
    for (var i = 0; i < oldRows.length; i++) {
        
        tableBody.replaceChild(rows[i], oldRows[i]);
        
        if (i % 2 == 0) {
            rows[i].className = 'even';
        }
        else {
            rows[i].className = 'odd';
        }
    }
    
    var tableHeaders = table.querySelectorAll('th.sort');
    
    for (var i = 0; i < tableHeaders.length; i++) {
        
        var header = tableHeaders[i];
        var triangles = header.querySelector('.triangles');
        
        if (header.columnIdx != target.columnIdx) {
            triangles.children[0].innerText = UP_EMPTY;
            triangles.children[1].innerText = DOWN_EMPTY;
        }
        else if (reverse) {
            triangles.children[0].innerText = UP_EMPTY;
            triangles.children[1].innerText = DOWN_FILLED;
        }
        else {
            triangles.children[0].innerText = UP_FILLED;
            triangles.children[1].innerText = DOWN_EMPTY;
        }
    }    
}

// Set the listeners, in either the new or old style.
if (bAddEventListenerAvailable) {
    window.addEventListener( "DOMContentLoaded", onDOMLoaded ); 
    window.addEventListener( "scroll", onScroll ); 
    window.addEventListener( "resize", onResize ); 
}
else {
    window.onload = onDOMLoaded;
    window.onscroll = onScroll;
    window.onresize = onResize;
}
