OMO Issues
----------

Long Term Goals
---------------

[ ]Look into missing button graphics on Windows.

[ ]Consider setting the track length if the entered fade time is 0.

[ ]Add per-codec handler gain settings. The main player should multiply the gain
   by the per-codec handler value.

   [ ]We should provide suitable default values for each codec handler.

   [ ]We should consider other per-codec handler settings.

[ ]Album Artist tags should be in Artist list when available.

[ ]Add support for SID music format. We should be able to utilize libresid
   (libresid-builder-dev in Ubuntu) and libsidplay2 (libsidplay2-dev in Ubuntu)
   as dependencies. Alternatively, we can include the source for both of these
   libraries.

[ ]Add support files for users to deploy their own OMO infrastructure.

   [ ]Need SQL command to generate compatible database.

   [ ]Need PHP scripts and template configuration script to minimize the amount
      of work needed to do a deployment.

[ ]GME codec handler position slider is longer than song length when resuming
   previous state on program load.

[ ]GME fade doesn't work sometimes after seek.

[ ]Investigate crash when track is finished playing and we move to the next
   track. OMO consistently crashes when a track finishes while
   listening to the '[ Movements ]' album.

[ ]Add a favorites system. We should be able to set favorite artists, albums,
   and songs and have a way to present those to the user.

[ ]Allow editing album tags. This will automatically apply the edited tags to
   each track in the album. Track-specific tags should not be shown in the
   dialog.

[ ]Consider adding a codec handler method for retrieving audio data. This method
   should be able to fill a buffer and express how many samples it generated and
   whether the end of the stream has been reached. This method could be used
   internally where we utilize engines that are connected to the audio device
   through Allegro to simplify the code base. As a bonus, we could add an option
   to convert supported codecs to WAV for burning to CD with another program.

[ ]We need to modularize the UI so we can enable developing multiple UI
   systems. The current Allegro-based UI is the main UI, but I'd also like
   provide a curses UI. Other UIs could also be developed, such as native
   Android or MacOS UIs. The library and playback engines are self-contained,
   so we should be able to easily add new UI systems.

   Ultimately, we should have a separate UI folder for each UI system. There
   should be a standard API for initializing and utilizing a UI system.
   Multiple UI systems should be able to coexist and be selected by the user at
   run time.

[ ]Implement portable mode. In portable mode, the library databases and app
   settings are stored alongside the executable. The idea is to allow a user to
   copy their music collection to a thumb drive and use it on multiple machines
   without having to generate library databases for each machine.

[ ]Look into adding a lyrics window.

[ ]Investigate why certain files that have been split aren't playing (DUMBA5).

   [ ]For some reason setting the start order doesn't work for PSM files. This
      will have to be fixed in DUMB.

[ ]Add album art view. I'm not sure what the best way to handle this is yet. We
   might want to add a separate view type that has 3 panes. Alternately, we
   could just add an option to show album art in the album list in the 2nd
   pane.

   We will probably want to make the album art icons the size of two lines of
   text or maybe just pick a standard size or allow the user to decide how big
   they want it. If we make it user configurable, the default should be the
   size of two lines of text.

[ ]Allow accessing a library remotely. The user should be able to sync a
   library over a LAN or WAN. The music files will remain on the remote device,
   while the local device will download songs from the remote device as needed.

   A synching mechanism should be provided so that the user can get some songs
   on their local device before going offline.

   An instance of OMO will need to be running on the remote device for this to
   work.

[ ]Implement a system for a user to rate or otherwise mark tracks they like or
   dislike.

[ ]Look into file selector that can select folders and files. Maybe we should
   provide our own file browser as an option.

[ ]Implement context menus.

[ ]Implement shortcut engine and map as many useful features as possible.

   [ ]Shortcuts should be user-definable with sensible defaults for the most
      used functions.

   [ ]Look into how to detect shortcuts when OMO's window is not in focus. We
      will probably need to use OS-specific functions for various platforms to
      make this work.

[ ]Add manual.

[ ]Allow multiple items to be selected in the list boxes. We need to add
   another argument to the list box callbacks to check whether an item is
   selected. We also need a way to check whether the list box is single-select
   or multi-select.

[ ]Add support for Amiga XPK compressed files.


v0.5.4
------

[ ]Crash when switching between library and basic view on occasion.

[X]Queue list multi-select is corrupted when switching between library and
   basic views. Probably need to reset a variable or clear an array.

[X]Window has black area at the bottom the size of the menu when switching
   between basic and library views.

   [X]This is the result of a bug in Allegro that was adding extra height to
      the display if a menu is attached. A pull request has been sent so
      hopefully they will accept it or at least offer another fix.

[X]After tagging a song while Unknown Artist/Album is selected, the song list
   shows all songs, but the selection still shows Unknown. We should probably
   revert to All Artists/Albums any time we regenerate the lists to prevent this
   from happening.

[X]Fix list box not scrolling when current song is not visible after previous
   song ends.

[X]Fix scroll bar not going all the way down sometimes.

[X]Adding disambiguation to Star Wars NES didn't regenerate library lists.
   Probably need to check if disambiguation changed during edit and use that as
   another trigger for regenerating library lists.

[X]Obfuscate URLs to work around Mod Security rules.

[X]T3Net has some potential race conditions where different threads might be
   trying to access the same resources. I think this might be what's causing
   the random crashing.

   [X]Added mutex locking to all t3net_get_data() calls.

[X]Scrutinize tags cloud sync. Tags that don't successfully submit are
   supposed to try again later. I keep seeing signs that some tags never get
   submitted properly and thus retry forever.

   [X]Tags were failing to submit due to Apache Mod Security on the host. A
      workaround has been implemented.

[X]Viewing "All Artists->Album" with no disambiduation shows blank song list.

[X]Songs that don't have disambiguation data get listed in all albums with that
   have the same name. Nondisambiguated songs should be listed together and
   excluded from disambiguated album song lists.

[X]Investigate library cache never loading on MacOS machine.

[X]Remove libarchive dependency and use Allegro's built-in PhysFS support for
   opening ZIP files.

[X]Add Opus codec handler.

[X]Make cloud sync URLs user configurable.

[X]See if we can fix playback of looping songs not ending correctly after
   resuming on load before the library is finished loading. We might need to
   srore each queued track's loop info.

[X]Check boxes in filter dialog do not work. Formats cannot be toggled off.

[X]Add option to disable cloud syncing. We should still flag unsynced tags so
   all modified tags will be synced once syncing is re-enabled.

[X]Can't delete two playlist entries back to back. I think the multi-select code
   may have broken this functionality a bit.

[X]Add disambiguation tag for albums with the same name.

[X]Look into crash that happens when doing Shuffle All on entire library.

[X]Fix missing support for dark mode on MacOS.

[X]Fix queue total time adding length of track immediately after editing. The
   old length should be subtracted before we add the new length if the length
   was edited.

[X]Crash when artist name is too long.

[X]Look into crash when creating a small queue while scrolled down far in a
   larger queue. I tried loading up a queue of about 50 songs while a 52000+
   queue was open and it crashed two different times. Once, it waited until I
   clicked the scroll bar to crash.

[X]See if we can start FluidSynth automatically when we need it instead of
   requiring the user to start it manually.

   [X]This method worked successfully in Instant Instruments. We'll use that
      implementation or a variation of it.

[X]Look into queue list showing "Unknown" for title when the artist is unknown.
   We should be able to show the correct title whether or not we know who the
   artist is.

[X]When Detected Length tag is updated after a track ends unexpectedly early,
   the time displayed in the queue needs to be updated.


v0.5.3
------

[X]Fix T3Net buffer overrun issue with tags larger than 256 bytes.

[X]Fix double-clicking on song while the player is paused not setting the
   proper state. We should play the double-clicked song.

[X]Fix search filter adding "special" entries such as "Unknown Artist" as
   matches for search text.


v0.5.2
------

[X]Error out of omo_submit_track_tags() if track fails to load.

[X]Apply filter text when library lists reloaded.

   [X]We probably need to apply any filters when the library thread finishes.

   [X]We also need to check when the user changes a selection in the library
      and reapply all the filters.

[X]Fix size of search filter edit boxes.

[X]Remove debugging information before finalizing release.

[X]Move cursor in edit box on first click.


v0.5.1
------

[X]Look into crash bug when opening invalid Ogg Vorbis audio file.


v0.5
----

[X]Remember track position as well as queue position.

[X]Don't count articles such as "the" and "and" as part of strings during
   sorting.

[X]Allow codec handler to be specified for each file. OMO will always default
   to using the first available codec handler that supports the file's type.
   Some file types are supported by multiple codec handlers. We want to be able
   to specify the desired codec handler in case the file works better with a
   specific one.

   [X]We need to add identifiers to all codec handlers to support this
      addition.

[X]Figure out a way to display track length in library and queue.

[X]Use Album Artist tag when appropriate.

   [X]See if we can list the album artist and artist in the artist list.

   [X]When sorting by artist, we should prioritize using the album artist if
      the album artist tag exists.

[X]Figure out why the first press of the 'T' key doesn't bring up the tags
   editor.

   [X]This seems to be a problem, but it is really the interface being a little
      unintuitive. The 'T' key activates the tags editor for the currently
      selected library or queue item. If no valid item is selected, it won't
      bring up the tags dialog.

[X]Allow disabling individual codec handlers at run time. We should keep a list
   of all enabled codec handlers in the config file. All codec handlers should
   be registered even if some are disabled. When searching for a codec handler,
   we should not return a disabled codec handler.

[X]Improve icon so it works better on dark backgrounds.

[X]Add Help menu.

[X]Add about box.

[X]Fix Debian category.

   [X]The Debian category is correct, but we need to ensure the desktop file
      also has the correct category. We may have to add another variable to the
      build script for the desktop category if it differs from the control
      category.

[X]Add option to locate a song in the library.

[X]Fix song list not working when selecting an artist+album combo. Many times
   it will generate an empty list.

[X]See if we can show albums that an artist contributed to that contain other
   artists as well. Many albums contain songs from various artists and it would
   be nice to have those albums listed under every artist that contributed to
   it.

[X]Automatically generate an anonymous tagger key on startup if there isn't one
   configured. We need to look at the PHP tagger key generation code to ensure
   we get unique keys for every user.

   Generating a unique anonymous tagger key for each user might seem wasteful,
   but it will make maintaining the database easier. If any users abuse the
   tagging function, we'll be able to wipe the bad tags out with less effort.

[X]Finalize default theme.

   [X]Remove rounded border around outer edge of program window.

   [X]Make edit boxes have outlines. We might do this by doing two render
      passes like we do with list boxes.

   [X]Consider making the default font size larger.

[X]Fix text for 0 items in library.

[X]Look into Linux crash when song ends or changes while library is loaded.

[X]Look into MPG123 crash when song ends.

[X]Clicking Shuffle All doesn't reset the queue list scroll position.

[X]Reset scroll position when editing search filter.

[X]DUMBA5 codec handler allows music to play past the end if you seek to the
   very end of the track.

[X]Fix GUI issues.

   [X]Right-click should not be interchangeable with left-click.

[X]Fix crash when library setup completes while library is not being shown.

[X]Look into accessing GUI elements in omo_tags_dialog_logic() to ensure we
   aren't attempting to access them when they might not be valid pointers. We
   need to see what the logic there is supposed to do and possibly store some
   extra data when opening the dialog.

[X]Don't show queue position and current song length if playback is stopped.

[X]See if we can stop the queue thread from tallying up time when the time is
   already figured out from the library.

[X]See if we can prevent keyboard focus from going to any element unless we
   specifically click on it or use Tab to select it.

[X]Don't put duplicate songs in the song list.

[X]Add support for loading and saving playlists. We should try to support M3U
   and PLS.

   [X]Allow saving the current queue as a playlist.

   [X]Don't add unsupported file types to queue.

   [X]Don't change sorting of queue items added from playlist. They should
      appear in the same order as they are in the playlist.

   [X]We need a way to store OMO-style filenames in a playlist file. When
      loading a playlist, we need to decode the filename into a base filename,
      sub filename, and track.

   [X]See about adding M3U support.

[X]Fix button rendering when it has focus. It should look the same as when it
   has mouse focus.

[X]Update plist for new format support.

[X]Check Artist->Unknown Album code path. When I selected an artist and
   Unknown Album, no songs were listed even though there were several songs
   with no album specified.

[X]Fix View menu on Mac. Currently, clicking an item in the View menu doesn't
   generate a MENU_CLICK event. This might be something that needs to be fixed
   in Allegro. If so, we can fix it there or work around the issue by naming
   our view menu something else.

   [X]I've implemented a workaround in Allegro to deal with this issue. The
      patch has been submitted to the Allegro devs for review.

[X]See about fixing scroll bar rendering. Currently we usually get a small gap
   at the bottom when we are scrolled all the way down.

[X]Make bezel size a theme option.

[X]Figure out why the song list updates don't work when okaying edited tags
   while the library lists are regenerating.

[X]Fix crash when pressing Tab or Enter while library is loading.

[X]Don't start playing queue if it is stopped and we delete an item.

[X]Add search field above each library section.

   [X]We'll probably need to make 'real' lists which contain pointers to the
      main lists. The real lists will be generated as the user types in the
      search box. I think we'll be able to make it work like Live Studio
      Sessions without too much trouble.

   [X]The filtered lists should still show All and Unknown entries at the top.

   [X]Typing in the search field should probably reset the state of the list
      box. The filter might eliminate the selected item from the list, which
      would just lead to confusion for the user.

   [X]Disable search filter edit boxes when library is not loaded.

   [X]When typing in the search box, don't regenerate any lists. Currently, the
      first matching item in the list is selected and the proceeding lists are
      generated based on that selection. The matching item should not really be
      selected until the user hits Enter or Tab.

   [X]Pressing Enter or Tab in the search field should fully select the first
      matching item in the list that is being searched.

   [X]Figure out why we are regenerating the album list when an album is
      selected. The regenerated list includes all albums from the currently
      selected artist, not just the ones that match the current search filter.
      Not sure if the album list is being regenerated for a reason or if it is
      just some bad or left over logic that can safely be removed.

      [X]We are currently generating the album list during song list generation
         so we can use the user's selected artist to generate the album list.
         We need to be able to generate the album list separately. We should
         look at all the places we call omo_get_library_song_list() and see if
         we need to make a separate call to omo_get_library_album_list(). Then
         we can eliminate the calls to omo_get_library_album_list() that are
         within omo_get_library_song_list().

[X]Update README.

v0.4
----

[X]Streamline library loading.

   [X]We should be able to use the database without waiting for lists to
      generate.

   [X]List generation should be done in a separate thread so we can still
      interact with the UI.

[X]Need to NULLify tags that are cleared so we don't get blank entries in the
   library UI.

[X]Implement tags submission and retrieval.

   [X]Add script to generate tagger key.

   [X]Add dialog for creating a tagger key.

      [X]Dialog will ask for a display name.

   [X]Require existing key to submit tags.

      [X]Add a tagger database so we can check for the existence of the tagger
         before accepting tags.

   [X]Add functions for submitting and retrieving tags to the UI.

      [X]Tag submission should be able to automatically run through your entire
         library and submit only tags that aren't included in a track's
         metadata. We also need to mark submitted tags so we don't end up
         constantly resubmitting tags that are already in the database.

      [X]When retrieving tags, we need a way to prevent overwriting the user's
         own tags if they differ from the ones being downloaded. We should
         probably present a dialog which asks if the user wants to accept the
         tags in this case.

      [X]When submitting tags, we should check the library database to
         determine if a track has any tags set by the user. When editing tags
         with the Edit Tags dialog, we should set a flag in the database to
         mark that the user has input some of their own tags.

         [X]We might be able to use the Submitted flag for this. Instead of
            deleting the Submitted key from the database, we can set it to
            false when the user makes an edit. The cloud code can then check to
            see that the Submitted key exists and that it is set to false
            before actually submitting the tag. If the tag submission succeeds,
            the Submitted key can be set to true.

[X]Need a way to clear tags in the database. A tagger should be able to delete
   tags they have submitted. Tags that have been cleared should be able to be
   set to NULL in the database.

   [X]If all tags are NULL, we should delete the track's database entry.

      [X]We can probably just count the fields as we are building the query. If
         the count is not greater than the number of mandatory fields, we know
         the entry can be deleted.

[X]Fix split tracks not appearing in library.

[X]Submit split track data if it exists.

   [X]When submitting tags, we should be able to reference the base file of
      split tracks and submit tags for the base track. The library won't
      contain an entry for the base track once it has been split.

[X]Look into why RSNs are being rescanned during library scan instead of using
   the data cached in file_database.

[X]Add a function to detect a top level folder modified time. This function
   should scan all subfolders and use the newest time.

[X]If a song ends before it reaches its reported length, set an internal length
   tag. This length tag should also be submitted.

[X]Add library mutex and lock it when we are performing certain operations on
   the library database. Specifically, we need to ensure no data is written to
   the database while a separate thread is attempting to read from it. The
   library list code running in a separate thread might be reading data from
   the database while the database is being altered. This could cause a crash.

[X]Move all thread operations to a single place in the code. Instead of
   creating/destroying threads in various places in the code, we should set a
   flag. We might make a separate "thread logic" module which handles this.

[X]Retrieve tags when opening tags editor or split track dialog.

[X]Retrieve tags from the cloud as part of the library scanning process.

[X]Don't load library cache if we don't have library database files.

[X]Ensure library folders are valid. If we hit on a file instead of a folder,
   we should remove the path tail and see if we are at a valid folder.

[X]Don't save library cache if library scan cancelled. We don't want an
   incomplete library to be loaded on next startup.

[X]Fix initial archive scanning. The archive entry data is being saved
   incorrectly in the file database on initial scan. This is making it
   impossible to add archived files to the library.

[X]Add library profiles. A library profile will contain library settings
   specific to that profile. For instance, you can have the default profile
   contain all of your music and have a separate profile for just MODs or
   game music.

[X]Save library cache when library finishes loading.

[X]Add file type ignore list configuration option. The codec handler registry
   should take this list into account when looking for a codec handler and
   should return NULL if we are looking for a codec handler for a type that is
   on the ignore list.

[X]Audit PHP code to check for vulnerabilities.

[X]Review menu code to ensure we are enabling/disabling menu items under the
   correct circumstances.

   [X]All menu items should be disabled when a popup dialog is being displayed.
      We should create a base update proc that every menu item uses. Every menu
      update proc should call the base update proc at the end of the proc's
      logic.


v0.3
----

[X]Factor out library setup routines.

[X]Factor out queue helper routines.

[X]Save queue data on exit and reload on open so users can continue where they
   left off.

[X]Implement library caching system.

   [X]Cache the artist, album, and song lists.

   [X]Force rescan if we modify the library folder settings.

[X]Stop timer when performing actions that can take a long time.

[X]Fix mixed tabs/spaces.

[X]Implement font size override. The user should be able to specify a preferred
   font size to override a theme's font size. This override should cause the
   theme system to load the font in the correct size so we get a properly sized
   font throughout the GUI system.

[X]Implement track looping.

   [X]Add codec handler function for setting up the loop for a loaded track.
      The codec handler will be responsible for keeping track of this data and
      ensuring playback respects the passed loop settings.

   [X]Add loop handling to MP3A5. So we can implement track looping in the
      MP3A5 codec handler.

   [X]Add loop handling to all codec handlers that can support it.

[X]Implement seek() for DUMBA5 codec handler.

   I think we can get this working by calling duh_end_sigrenderer() and
   generate a new sigrenderer for the player with duh_start_sigrenderer(),
   passing in the desired seek time. We should add the requisite functionality
   to DUMBA5. This will require utilizing mutex locking to prevent accessing
   the sigrenderer while it is in the process of being swapped out.

   We should fix dumba5_set_player_pattern(), too. It looks like the function
   is using pointers incorrectly. Since this and the new
   dumba5_set_player_position() are functionally similar, we can probably use
   most of the same code for both functions.

[X]Implement track split dialog and tag system. We need a way to store track
   split data in the base file's metedata so we can keep it in the online
   database instead of requiring each user to split tracks on their own.

[X]Update artists/albums/songs lists after editing tags.

   [X]Delete our library caches, since they are no longer valid.

[X]Add status bar to library view. We should show library-related messages in
   this status bar instead of using the list box.

[X]Implement get_length() and get_position() for all codec handlers that can
   support it. These functions should take looping into account. If the
   playback is looped, we should count the total playback length. This includes
   the total time of the looped audio and the specified fade time.

[X]Finish main UI.

   [X]Modularize UI setup.

      [X]Use separate function for adding each module to the total UI. Each
         section of the UI should be a separate module. The player module will
         consist of the player controls, the seek control, the volume control,
         and the two info lines. The library artist, album, and song lists
         should each be their own modules as well as the status bar.

         We need to do this to make the UI setup code simpler and easier to
         maintain. With each module being created individually, we can
         calculate a total UI space for the user's device and add the modules
         that the user wants or the ones that will fit on the screen.

         Each function should be given a space to occupy on the total UI and
         the setup code for that module will smartly fill the available space
         with the required UI elements.

   [X]Add volume and seek controls to the player module.

   [X]Add song info to the player module. The plan is to have 2 lines for this,
      one line for the artist, title, etc. of the currently playing song and
      another for track-specific info from the codec handler.

[X]Finish implementing midiOut.

   [X]Add get_length();

   [X]Add get_position();

   [X]Add seek();

   [X]Add set_volume();

   [X]Add get_info();

[X]Fix slider GUI element.

   [X]Vertical slider renders incorrectly.

[X]Fix shuffle not starting playback.

[X]Add CJK font support to T3GUI.

   [X]Add cjk_font theme state parameter. If a CJK font is specified, use
      al_set_fallback_font() to map this font as the fallback font.

[X]Add a CJK font to the basic theme.

[X]Look into using a monospace font for the song info display. Some of the
   codec handlers have potential to do neat animations based on playback info
   if we can gaurantee the font spacing. We need to supply a CJK monospace font
   as well if we implement this.


v0.2
----

[X]Fix queue list display swapping album and title.

[X]Fix queue list not scrolling to keep up with the currently playing queue
   item. If the current item is on screen when it finishes playing,
   automatically scroll the list to put the new current item at the top if the
   current item is now past the bottom of the visible part of the list.

[X]Don't require user to select a library folder if they press L and haven't
   set a library folder yet.

[X]Show text indicating no library has been set up in library view when
   appropriate.

[X]Ensure we are spawning the library scanning thread in all places the library
   setup routing is being called.

[X]Keep queue list tags updated.

   [X]When editing tags, the new tags need to be displayed upon okaying them.

   [X]Tags need to be updated with the info from the library if the library
      gets finished loading.

[X]Specify where archive handlers extract files to. We need the library scanner
   to extract to a different location than the player so we don't get conflicts
   that cause playback or scanning errors.

[X]Get tags for queued files using codec handler if library has not been loaded
   yet.

[X]Add more detailed scanning info to the library view. Show which file is
   currently being scanned and total progress.

[X]Add 'Shuffle All' item to song list.

[X]Allow Shift+Double-Click to add items to the queue instead of replacing it.

[X]Implement window constraints. Use theme data to calculate a good minimum
   window size.

[X]Figure out why window position settings aren't restored properly when
   switching back to player-only view.

[X]Update menus to include items for all current functionality.

[X]See if we can add some stuff to info.plist to make associating music files
   with OMO work correctly.

[X]Update version numbers.

[X]Update changelog.

[X]Improve default theme button graphics.

[X]Don't use t3f_get_filename() in multi-threaded situations.

[X]Don't restore window positions on Windows since we can't guarantee the
   window position will be correct.
