const playerManager = context.getPlayerManager();

playerManager.setSupportedMediaCommands(cast.framework.messages.Command.PAUSE |
                                        cast.framework.messages.Command.QUEUE_PREV |
                                        cast.framework.messages.Command.QUEUE_NEXT |
                                        cast.framework.messages.Command.QUEUE_SHUFFLE);

var wakeLock = null;
var requestWakeLock = async () => {
    try {
        if (wakeLock == null) {
            wakeLock = await navigator.wakeLock.request("screen");
        }
    } catch (err) {
        // The wake lock request fails - usually system-related, such as low battery.
        console.log(`${err.name}, ${err.message}`);
    }
};
requestWakeLock();

var audioState = null;
var displayState = null;
var setAudioState = (state) => {
    audioState = state;
    updateApplicationState();
};

var setDisplayState = (state) => {
    displayState = state;
    updateApplicationState();
};

var updateApplicationState = () => {
    context.setApplicationState(displayState != null ? displayState : audioState);
};

var uiMessageListener = null;
var zoneid;
var displaysettings;
context.addCustomMessageListener(ROON_CHANNEL, function(roonEvent) {
    //console.log(roonEvent);
    switch(roonEvent.data.type) {
        case 'GET_DEVICE_CAPABILITIES': {
            var caps = { type: 'DEVICE_CAPABILITIES', requestId: roonEvent.data.requestId,
                capabilities: context.getDeviceCapabilities() };
            console.log('caps: ' + JSON.stringify(caps));
            context.sendCustomMessage(ROON_CHANNEL, roonEvent.senderId, caps);
        }
            break;
        case 'UPDATE_STATE': {
            var newState = roonEvent.data.state;
            //console.log('new state: ' + newState);
            setAudioState(newState);

            var response = { type: 'UPDATE_STATE', requestId: roonEvent.data.requestId,
                result: "SUCCESS" };
            context.sendCustomMessage(ROON_CHANNEL, roonEvent.senderId, response);
        }
            break;
        case 'SET_ACTIVE_DISPLAY_ZONE': {
                zoneid = roonEvent.data.zone_id;
                displaysettings = roonEvent.data.settings;
                var response = { type: 'SET_ACTIVE_DISPLAY_ZONE', requestId: roonEvent.data.requestId, result: "SUCCESS" };
                context.sendCustomMessage(ROON_CHANNEL, roonEvent.senderId, response);
        }
            break;
    }
    if (uiMessageListener != null) uiMessageListener(roonEvent);
});

context.addEventListener(cast.framework.system.EventType.SENDER_DISCONNECTED, function(event) {
    if(context.getSenders().length == 0) {
        console.log('All senders disconnected. Stopping application.');
        context.stop();
    }
});

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.STOP, requestData => {
    if (requestData.customData != undefined && requestData.customData.roon == true) { //request came from Roon, actually process.
        return requestData;
    } else { //request came from some other place (ie: hardware/CEC controls), pass on request to Roon
        context.sendCustomMessage(ROON_CHANNEL, undefined, { type: 'TRANSPORT_CONTROL', control: 'stop' });
    }
});

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.PLAY, requestData => {
    if (requestData.customData != undefined && requestData.customData.roon == true) { //request came from Roon, actually process.
        return requestData;
    } else { //request came from some other place (ie: hardware/CEC controls), pass on request to Roon
        context.sendCustomMessage(ROON_CHANNEL, undefined, { type: 'TRANSPORT_CONTROL', control: 'play' });
    }
});

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.PAUSE, requestData => {
    if (requestData.customData != undefined && requestData.customData.roon == true) { //request came from Roon, actually process.
        return requestData;
    } else { //request came from some other place (ie: hardware/CEC controls), pass on request to Roon
        context.sendCustomMessage(ROON_CHANNEL, undefined, { type: 'TRANSPORT_CONTROL', control: 'pause' });
    }
});

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.QUEUE_UPDATE, requestData => {
    if (requestData.jump != undefined) {
        let control = requestData.jump > 0 ? 'next' : 'previous';
        context.sendCustomMessage(ROON_CHANNEL, undefined, { type : 'TRANSPORT_CONTROL', control: control });
    }
    if (requestData.shuffle != undefined) {
        let control = requestData.shuffle ? 'shuffle_on' : 'shuffle_off';
        context.sendCustomMessage(ROON_CHANNEL, undefined, { type : 'TRANSPORT_CONTROL', control: control });
    }
    if (requestData.repeatMode != undefined) {
        let control = undefined;
        switch (requestData.repeatMode) {
            case cast.framework.messages.RepeatMode.REPEAT_OFF:
                control = 'loop_off';
                break;
            case cast.framework.messages.RepeatMode.REPEAT_ALL_AND_SHUFFLE:
                context.sendCustomMessage(ROON_CHANNEL, undefined, { type : 'TRANSPORT_CONTROL', control: 'shuffle_on' });
            case cast.framework.messages.RepeatMode.REPEAT_ALL:
                control = 'loop_all';
                break;
            case cast.framework.messages.RepeatMode.REPEAT_SINGLE:
                control = 'loop_one';
                break;
        }
        if (control != undefined) context.sendCustomMessage(ROON_CHANNEL, undefined, { type : 'TRANSPORT_CONTROL', control: control });
    }
});

playerManager.addEventListener(cast.framework.events.EventType.TIME_UPDATE, event => {
    context.sendCustomMessage(ROON_CHANNEL, undefined, event);
});

var suppressMediaFinishedEvents = false;
playerManager.addEventListener(cast.framework.events.EventType.MEDIA_FINISHED, function(event) {
    console.log('Media finished: ' + JSON.stringify(event));
    let mediaInfo = playerManager.getMediaInformation();
    if (suppressMediaFinishedEvents) {
        console.log('ignoring media finished event for fake idle file'); //we knew this URL wouldn't load
    } else {
        context.sendCustomMessage(ROON_CHANNEL, undefined, event);
    }
});

var getUrlBase = function() {
    var fullurl = document.currentScript.src;
    var lastSlashIndex = fullurl.lastIndexOf("/");
    var urlbase = lastSlashIndex != -1 ? fullurl.substring(0, lastSlashIndex + 1) : "";

    return urlbase;
}
var urlbase = getUrlBase();

// if the display portion is showing information for a zone but the player is idle, attempt to play
// a bogus URL to look active. This should be enough to prevent sleep/screensaver mode.
var keepAliveRequested;
var keepAlive = () => {
    if (typeof keepAliveRequested === 'function' && keepAliveRequested()) {
        console.log('keepAlive called and keepAliveRequested');
        preventSleep();
    }
    setTimeout(keepAlive, 60000);
}

var lastPreventSleep = Date.now();
var preventSleep = () => {
    let playerState = playerManager.getPlayerState();
    if (playerState !== cast.framework.messages.PlayerState.IDLE) {
        //console.log('playerState !== IDLE, skipping.')
        return;
    }

    let now = Date.now();
    if (lastPreventSleep != null && now - lastPreventSleep < 60000) {
        //console.log('recently prevented sleep. skipping.');
        return;
    }

    let mediaInfo = new cast.framework.messages.MediaInformation();
    mediaInfo.contentId = urlbase + 'idle.flac';
    mediaInfo.contentType = 'audio/flac;'

    let requestData = new cast.framework.messages.LoadRequestData();
    requestData.media = mediaInfo;
    requestData.autoplay = true;

    suppressMediaFinishedEvents = true;
    lastPreventSleep = now;
    playerManager.load(requestData).then(() => {
        console.log('successfully loaded fake idle file. This isn\'t supposed to happen');
    }, (error) => {
        //this is expected.
    }).finally(() => {
        console.log('finished idle flac load request. returning to normal operation.');
        suppressMediaFinishedEvents = false;
    });
};

var caps = context.getDeviceCapabilities();
if (caps["display_supported"] == true) {
    var displayScriptUrl = urlbase + "display_ui.js";
    var displayHtmlUrl = urlbase + "display_ui.html";
    $("#uiParent").load(displayHtmlUrl, (responseText, textStatus, jqXHR) => {
        $.getScript(displayScriptUrl)
            .done(function(script, textStatus) {
                var request = { type: 'GET_MOO_DATA' }
                context.sendCustomMessage(ROON_CHANNEL, undefined, request);
                setTimeout(keepAlive, 60000);
            });
    });
} else {
    $("#splash").remove();
}
