
const parseDuration = function(string) {
    return string.split(':').reverse().slice(0, 4).reduce(function(p, c, i) {
        return p + (parseFloat(c) || 0) * (i == 3 ? 86400 : Math.pow(60, i));
    }, 0);
};

const formatDuration = function(seconds) {
    if (isString(seconds)) {
        seconds = parseFloat(seconds)
    }
    seconds = seconds.toFixed(3)
    var parts = [
        parseInt(seconds / 86400),
        parseInt(seconds % 86400 / 3600),
        parseInt(seconds % 3600 / 60),
        parseInt(seconds % 60)
    ]
    return parts.map(p => { return p.toString().padStart(2, '0')}).join(':')
}

const typeOf = function(value) {
    return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
};
const isUndefined = function(value) {
    return typeOf(value) == 'undefined';
}
const isNumber = function(value) {
    return typeOf(value) == 'number';
};
const isObject = function(value) {
    return typeOf(value) == 'object';
};
const isNull = function(value) {
    return typeOf(value) == 'null';
};
const isString = function(value) {
    return typeOf(value) == 'string';
};
const isEmpty = function(value) {
    var type = typeOf(value)
    if (['arguments', 'array', 'nodelist', 'string'].includes(value)) {
        return value.length == 0
    }
    if (['object', 'storage'].includes(type)) {
        return Object.keys(value).length;
    }
    return false
};
const mod = function(number, by) {
    return (number % by + by) % by;
};

const getObjectById = function(array, id) {
    return array.filter(obj => { return obj.id == id})[0]
}

const debug = function() {
    if (localStorage.debug) {
        console.log.apply(null, arguments)
    }
};

const canPlayMP4 = function() {
    var video = document.createElement('video');
    if (video.canPlayType && video.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace('no', '')) {
        return true
    }
    return false
};

const canPlayWebm = function() {
    var video = document.createElement('video');
    if (video.canPlayType && video.canPlayType('video/webm; codecs="vp8, vorbis"').replace('no', '')) {
        return true
    }
    return false
};

const getFormat = function() {
    //var format = canPlayWebm() ? "webm" : "mp4"
    var format = canPlayMP4() ? "mp4" : "webm"
    return format
}

const safeDocumentName = function(name) {
    ['\\?', '#', '%', '/'].forEach(function(c) {
        var r = new RegExp(c, 'g')
        name = name.replace(r, '_');
    })
    return name;
};

const getVideoInfo = function() {
    console.log("FIXME implement getvideoInfo")
}

const isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);


const getLink = function(fragment) {
    if (document.location.hash.length > 2) {
        return '#' + fragment
    } else {
        return '/m/' + fragment
    }
}

const clickLink = function(event) {
    var a = event.target
    while (a && a.tagName != 'A') {
        a = a.parentElement
    }
    if (!a) {
        return
    }
    var href = a.attributes.href.value
    var prefix = document.location.protocol + '//' + document.location.hostname
    if (href.startsWith(prefix)) {
        href = href.slice(prefix.length)
    }
    if (href.startsWith('/')) {
        event.preventDefault()
        event.stopPropagation()
        var link = href.split('#embed')[0]
        if (document.location.hash.length > 2) {
            if (link.startsWith('/m')) {
                link = link.slice(2)
            }
            document.location.hash = '#' + link.slice(1)
        } else {
            if (link.includes('/download/')) {
                document.location.href = link
                return
            } else if (!link.startsWith('/m')) {
                link = '/m' + link
            }
            history.pushState({}, '', link);
            render()
        }
    }
}

const getUid = (function() {
    var uid = 0;
    return function() {
        return ++uid;
    };
}());


const getVideoURLName = function(id, resolution, part, track, streamId) {
    return id + '/' + resolution + 'p' + part + (track ? '.' + track : '')
        + '.' + pandora.format  + (streamId ? '?' + streamId : '');
};

const getVideoURL = function(id, resolution, part, track, streamId) {
    var uid = getUid(),
        prefix = pandora.site.site.videoprefix
            .replace('{id}', id)
            .replace('{part}', part)
            .replace('{resolution}', resolution)
            .replace('{uid}', uid)
            .replace('{uid42}', uid % 42);
    if (!prefix) {
        prefix = pandoraURL
    }
    return prefix + '/' + getVideoURLName(id, resolution, part, track, streamId);
};

const getSortValue = function(value) {
    var sortValue = value;
    function trim(value) {
        return value.replace(/^\W+(?=\w)/, '');
    }
    if (
        isEmpty(value)
        || isNull(value)
        || isUndefined(value)
    ) {
        sortValue = null;
    } else if (isString(value)) {
        // make lowercase and remove leading non-word characters
        sortValue = trim(value.toLowerCase());
        // move leading articles to the end
        // and remove leading non-word characters
        ['a', 'an', 'the'].forEach(function(article) {
            if (new RegExp('^' + article + ' ').test(sortValue)) {
                sortValue = trim(sortValue.slice(article.length + 1))
                    + ', ' + sortValue.slice(0, article.length);
                return false; // break
            }
        });
        // remove thousand separators and pad numbers
        sortValue = sortValue.replace(/(\d),(?=(\d{3}))/g, '$1')
            .replace(/\d+/g, function(match) {
                return match.padStart(64, '0')
            });
    }
    return sortValue;
};

function sortBy(array, by, map) {
    return array.sort(function(a, b) {
        var aValue, bValue, index = 0, key, ret = 0;
        while (ret == 0 && index < by.length) {
            key = by[index].key;
            aValue = getSortValue(
                map && map[key] ? map[key](a[key], a) : a[key]
            );
            bValue = getSortValue(
                map && map[key] ? map[key](b[key], b) : b[key]
            );
            if ((aValue === null) != (bValue === null)) {
                ret = aValue === null ? 1 : -1;
            } else if (aValue < bValue) {
                ret = by[index].operator == '+' ? -1 : 1;
            } else if (aValue > bValue) {
                ret = by[index].operator == '+' ? 1 : -1;
            } else {
                index++;
            }
        }
        return ret;
    });
}
