// - return the empty string if type is a type that the user agent knows it cannot render or is the type "application/octet-stream"
// - return "probably" if the user agent is confident that the type represents a media resource that it can render if used in with this audio or video element
// - return "maybe" otherwise. Implementers are encouraged to return "maybe" unless the type can be confidently established as being supported or not
// Generally, a user agent should never return "probably" for a type that allows the codecs parameter if that parameter is not present.
// When the length of the media resource changes to a known value (e.g. from being unknown to known, or from a previously established length to a new
// length) the user agent must queue a media element task given the media element to fire an event named durationchange at the media element. (The event
// is not fired when the duration is reset as part of loading a new media resource.) If the duration is changed such that the current playback position
// ends up being greater than the time of the end of the media resource, then the user agent must also seek to the time of the end of the media resource.
if(!isnan(duration)){
// FIXME: Handle seeking to the end of the media resource when needed.
// 8. Return. The element won't attempt to load another resource until this algorithm is triggered again.
return{};
}
// -> Otherwise (mode is children)
caseSelectMode::Children:
// FIXME: 1. ⌛ Let pointer be a position defined by two adjacent nodes in the media element's child list, treating the start of the list (before the
// first child in the list, if any) and end of the list (after the last child in the list, if any) as nodes in their own right. One node is
// the node before pointer, and the other node is the node after pointer. Initially, let pointer be the position between the candidate node
// and the next node, if there are any, or the end of the list, if it is the last node.
//
// As nodes are inserted and removed into the media element, pointer must be updated as follows:
//
// If a new node is inserted between the two nodes that define pointer
// Let pointer be the point between the node before pointer and the new node. In other words, insertions at pointer go after pointer.
// If the node before pointer is removed
// Let pointer be the point between the node after pointer and the node before the node after pointer. In other words, pointer doesn't
// move relative to the remaining nodes.
// If the node after pointer is removed
// Let pointer be the point between the node before pointer and the node after the node before pointer. Just as with the previous case,
// pointer doesn't move relative to the remaining nodes.
// Other changes don't affect pointer.
// FIXME: 2. ⌛ Process candidate: If candidate does not have a src attribute, or if its src attribute's value is the empty string, then end the
// synchronous section, and jump down to the failed with elements step below.
// FIXME: 3. ⌛ Let urlString and urlRecord be the resulting URL string and the resulting URL record, respectively, that would have resulted from parsing
// the URL specified by candidate's src attribute's value relative to the candidate's node document when the src attribute was last changed.
// FIXME: 4. ⌛ If urlString was not obtained successfully, then end the synchronous section, and jump down to the failed with elements step below.
// FIXME: 5. ⌛ If candidate has a type attribute whose value, when parsed as a MIME type (including any codecs described by the codecs parameter, for
// types that define that parameter), represents a type that the user agent knows it cannot render, then end the synchronous section, and
// jump down to the failed with elements step below.
// FIXME: 6. ⌛ Set the currentSrc attribute to urlString.
// FIXME: 7. End the synchronous section, continuing the remaining steps in parallel.
// FIXME: 8. Run the resource fetch algorithm with urlRecord. If that algorithm returns without aborting this one, then the load failed.
// FIXME: 9. Failed with elements: Queue a media element task given the media element to fire an event named error at candidate.
// FIXME: 10. Await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorithm says the
// synchronous section has ended. (Steps in synchronous sections are marked with ⌛.)
// FIXME: 11. ⌛ Forget the media element's media-resource-specific tracks.
// FIXME: 12. ⌛ Find next candidate: Let candidate be null.
// FIXME: 13. ⌛ Search loop: If the node after pointer is the end of the list, then jump to the waiting step below.
// FIXME: 14. ⌛ If the node after pointer is a source element, let candidate be that element.
// FIXME: 15. ⌛ Advance pointer so that the node before pointer is now the node that was after pointer, and the node after pointer is the node after
// the node that used to be after pointer, if any.
// FIXME: 16. ⌛ If candidate is null, jump back to the search loop step. Otherwise, jump back to the process candidate step.
// FIXME: 17. ⌛ Waiting: Set the element's networkState attribute to the NETWORK_NO_SOURCE value.
// FIXME: 18. ⌛ Set the element's show poster flag to true.
// FIXME: 19. ⌛ Queue a media element task given the media element to set the element's delaying-the-load-event flag to false. This stops delaying the
// load event.
// FIXME: 20. End the synchronous section, continuing the remaining steps in parallel.
// FIXME: 21. Wait until the node after pointer is a node other than the end of the list. (This step might wait forever.)
// FIXME: 22. Await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorithm says the
// synchronous section has ended. (Steps in synchronous sections are marked with ⌛.)
// FIXME: 23. ⌛ Set the element's delaying-the-load-event flag back to true (this delays the load event again, in case it hasn't been fired yet).
// FIXME: 24. ⌛ Set the networkState back to NETWORK_LOADING.
// FIXME: 25. ⌛ Jump back to the find next candidate step above.
// 1. If the algorithm was invoked with media provider object or a URL record whose blob URL entry is a blob URL entry whose object is a media provider
// object, then let mode be local. Otherwise let mode be remote.
// FIXME: Detect media provider object / blob URLs with a media provider object.
automode=FetchMode::Remote;
// FIXME: 2. If mode is remote, then let the current media resource be the resource given by the URL record passed to this algorithm; otherwise, let the
// current media resource be the resource given by the media provider object. Either way, the current media resource is now the element's media
// resource.
// FIXME: 3. Remove all media-resource-specific text tracks from the media element's list of pending text tracks, if any.
// 4. Run the appropriate steps from the following list:
switch(mode){
// -> If mode is remote
caseFetchMode::Remote:{
// FIXME: 1. Optionally, run the following substeps. This is the expected behavior if the user agent intends to not attempt to fetch the resource until
// the user requests it explicitly (e.g. as a way to implement the preload attribute's none keyword).
// 1. Set the networkState to NETWORK_IDLE.
// 2. Queue a media element task given the media element to fire an event named suspend at the element.
// 3. Queue a media element task given the media element to set the element's delaying-the-load-event flag to false. This stops delaying
// the load event.
// 4. Wait for the task to be run.
// 5. Wait for an implementation-defined event (e.g., the user requesting that the media element begin playback).
// 6. Set the element's delaying-the-load-event flag back to true (this delays the load event again, in case it hasn't been fired yet).
// 7. Set the networkState to NETWORK_LOADING.
// 2. Let destination be "audio" if the media element is an audio element, or "video" otherwise.
// FIXME: 1. Create an AudioTrack object to represent the audio track.
// FIXME: 2. Update the media element's audioTracks attribute's AudioTrackList object with the new AudioTrack object.
// FIXME: 3. Let enable be unknown.
// FIXME: 4. If either the media resource or the URL of the current media resource indicate a particular set of audio tracks to enable, or if
// the user agent has information that would facilitate the selection of specific audio tracks to improve the user's experience, then:
// if this audio track is one of the ones to enable, then set enable to true, otherwise, set enable to false.
// FIXME: 5. If enable is still unknown, then, if the media element does not yet have an enabled audio track, then set enable to true, otherwise,
// set enable to false.
// FIXME: 6. If enable is true, then enable this audio track, otherwise, do not enable this audio track.
// FIXME: 7. Fire an event named addtrack at this AudioTrackList object, using TrackEvent, with the track attribute initialized to the new AudioTrack object.
}
// -> If the media resource is found to have a video track
// -> Once enough of the media data has been fetched to determine the duration of the media resource, its dimensions, and other metadata
if(video_track!=nullptr){
// FIXME: 1. Establish the media timeline for the purposes of the current playback position and the earliest possible position, based on the media data.
// FIXME: 2. Update the timeline offset to the date and time that corresponds to the zero time in the media timeline established in the previous step,
// if any. If no explicit time and date is given by the media resource, the timeline offset must be set to Not-a-Number (NaN).
// FIXME: 3. Set the current playback position and the official playback position to the earliest possible position.
// FIXME: 6. Set the readyState attribute to HAVE_METADATA.
// FIXME: 7. Let jumped be false.
// FIXME: 8. If the media element's default playback start position is greater than zero, then seek to that time, and let jumped be true.
// FIXME: 9. Let the media element's default playback start position be zero.
// FIXME: 10. Let the initial playback position be zero.
// FIXME: 11. If either the media resource or the URL of the current media resource indicate a particular start time, then set the initial playback
// position to that time and, if jumped is still false, seek to that time.
// FIXME: 12. If there is no enabled audio track, then enable an audio track. This will cause a change event to be fired.
// 13. If there is no selected video track, then select a video track. This will cause a change event to be fired.
if(m_video_tracks->selected_index()==-1)
video_track->set_selected(true);
// FIXME: Once the readyState attribute reaches HAVE_CURRENT_DATA, after the loadeddata event has been fired, set the element's delaying-the-load-event
// flag to false. This stops delaying the load event.
}
// -> Once the entire media resource has been fetched (but potentially before any of it has been decoded)
if(video_track!=nullptr){
// Fire an event named progress at the media element.