"
" CyberDJ v2.0 programming documentation
" by Bret Victor, 9/7/98
" bret@ugcs.caltech.edu
" http://www.ugcs.caltech.edu/~bret
"
" code v2.07
"

Included with this file should be the complete source code to the
CyberDJ program, which manages the Lloyd radio station at Caltech
(http://lloydradio.caltech.edu when it is up and running).

The source is being made public primarily for educational reasons --
so others can look at it and learn from it.  Feel free to use parts
of it in your own programs, but be sure to give credit where credit
is due, and I wouldn't mind being informed as well.

If you compile the program as is and try to run it, it will crash.
This is because it needs a bunch of HTML files in order to work and
also expects a certain directory setup.  If you really want to run it
for some reason, let me know and I'll help you out.


GENERAL OVERVIEW
""""""""""""""""
CyberDJ takes care of random song selection, accepting song requests,
managing live shows, web serving, Winamp front-ending, and much more.
The code is written in C++, and is organized into classes that take
care of specific tasks.  Anyway, you can mostly tell where each class
is defined by looking at the filename.  Each file has a hopefully
informative comment section at the top, and will also be briefly
discussed below.  But first, here is a general overview of the major
segments of the program:

Main Window:  takes care of maintaining the main window.  It also has
   the only thread with a Windows message loop, so it receives messages 
   to pass on to others, such as the web server.

Web Server:  takes care of accepting incoming web requests.  The server
   does not have its own thread; it uses WSAAsyncSelect to receive a
   message about the incoming request in the main window thread.  It
   then spawns off a new thread to deal with the web request.

CyberDJ request handler:  is called by the server's new thread (the
   WebResponse) after all the data has been parsed.  In addition to
   simply sending out HTML files (or DynamicFiles), song requests,
   live DJ mail, and all other user interaction is handled here.

CyberDJ playlist maintanance:  does have its own thread, which sleeps
   most of the time, and wakes up every half-second or so to check on
   the status of the music player, and select a new song to play if
   necessary.  Autoplay selection, scheduled songs, and all other
   automatic events are handled here.  This thread is terminated in
   live DJ mode.

If you check, you will find that there are actually three threads
running instead of two (main window and CyberDJ threads).  This
mystery thread appears after the first web request, and is just
WSAAsyncGetHostByAddr being stupid.  (But not as stupid as
gethostbyaddr.  You can read about that in webserver.cpp.)

CyberDJ does not use the registry, and uses mostly local pathnames.
So if CyberDJ is shared on my computer, you can simply double-click on
it and it'll run fine on your computer.  It'll even open up your Winamp
to play songs.

The directory structure is such that the main CyberDJ directory
contains nothing but the executable and two directories, html and
shows.  CyberDJ keeps all of its messy files in shows/CyberDJ/xxx where
xxx is a directory that depends on the type of file.  All of the user-
editable files can be accessed from the "administrator settings"
window, so there is no need to go into the shows/CyberDJ folder at all
most of the time.  Here is the basic directory structure:

CyberDJ.exe
html/
shows/
      CyberDJ/
                       user/
                       auto/
                       htmlout/
                       temp/
      Unscheduled Show/
                       mail/
                       My Stuff/
      (some show name)/
                       mail/
                       My Stuff/
      (etc, for all the live shows)


FILE-BY-FILE AND CLASS-BY-CLASS OVERVIEW
""""""""""""""""""""""""""""""""""""""""
(All of the .cpp files listed have corresponding .h files which
 contain the class prototype and define any constants.)

main.cpp:  contains WinMain() and dispatch().  WinMain starts up the
   pieces and shuts them down when they're done.  dispatch is the local
   message dispatcher that allows the pieces to communicate with one
   another.

mainwindow.cpp:  contains the MainWindow class, which implements the
   main message loop and the main window dialog procedure.

registerwindow.cpp:  contains the RegisterWindow class, which implements
   the "register new show" and "edit show properties" dialog box.

optionswindow.cpp:  contains the OptionsWindow class, which implements
   the "administrator settings" dialog box.  Basically acts as an
   OptionBlock editor.

livedjmailwindow.cpp:  contains the LiveDJMailWindow class,
   which implements the "live dj messages" window.  Basically acts as a
   LiveDJMailList viewer.

aboutwindow.cpp:  contains the AboutWindow class, which simply shows the
   "about" dialog box.

webserver.cpp:  contains the WebServer class and WebResponse class.
   WebServer initializes the network stuff and the WebResponse array.
   When a web request comes in, it finds an available WebResponse and
   tells it to begin.  The WebResponse parses the HTTP request and
   calls CyberDJ's request handler.  WebResponse is one of the most
   important classes because it is CyberDJ's interface with the world.
   All of CyberDJ's inputs, such as the URL, form data, cookies, etc.,
   are members of the WebResponse object, and likewise, all HTML data
   that CyberDJ outputs is handled through the WebResponse.  Thus, the
   web server implementation can be completely modified without having
   to change CyberDJ at all.

cyberdj.cpp:  contains the CyberDJ class, another rather important
   class.  :)  The first half of the file deals with the CyberDJ thread
   and playlist maintanance, which is deactivated in live DJ mode.  The
   second half has the request handler and the DynamicFile insertion
   handlers, which take care of sending out HTML and accepting song
   request.

cyberdjfiles.cpp:  contains the CyberDJFiles class, which is sort of
   just an organizational class to manage the DynamicFiles that CyberDJ
   uses.  It makes adding and changing DynamicFiles (on the programmer's
   end) much easier.

livedj.cpp:  contains the LiveDJ class, which manages things related to
   live shows, such as taking all the information from the different
   DJ folders and putting it into one place.

musicplayer.cpp:  contains the MusicPlayer class, which implements the
   Winamp front end.  The interface is pretty generic, so you could
   simply rewrite MusicPlayer for some other player, and CyberDJ would
   use it automatically.

winamp.h:  is pretty much the frontend.txt file that comes with Winamp.
   Contains definitions for interfacing with Winamp.

dynamicfile.cpp:  contains the DynamicFile class, which is used for
   creating and sending out files that need to change.  DynamicFile is
   based around substitutions, or inserts.  A special code in the
   HTML file will cause a function in CyberDJ to be called, to fill in
   some data, or even insert another DynamicFile.  There are two types
   of insertions, one that is filled in when the file is updated to
   disk, and the other when the file is sent out.  A very important
   class.  See the comments at the top of the file for details.

dynamicnames.h:  contains the names of the DynamicFile inserts.  Making
   a new insert is as easy as adding a name to the list and defining
   a constant for the corresponding number.

filestuff.cpp:  contains a lot of classes:  LocalName, LocalFile,
   DirFile, SelectFileName, ProgramDir.  LocalName turns an
   unqualified pathname into a full pathname referenced to the program
   directory, and LocalFile open and closes a file, getting the
   name through LocalName.  These two classes are used just about
   everywhere, for almost all file I/O.  DirFile creates and opens
   a file that contains a list of the contents of a directory.
   SelectFileName brings up a standard file select box for the user
   to choose a file.  ProgramDir holds the name of the program dir.

livedjmaillist.cpp:  contains the LiveDJMailList class, which implements
   a DJ's "inbox" and allows messages to be accepted, saved, and
   deleted.

playlist.cpp:  contains the classes:  PlayList, PlayStruct,
   CommentStruct, VoteStruct.  PlayList is a dynamic list of
   PlayStructs, and allows songs to be inserted, deleted, and moved.
   CyberDJ currently uses two PlayLists, one for the song queue and
   one for the history list.  PlayStruct descends from SongStruct, and
   contains additional information about the requester and votes, and
   also has a list of CommentStructs and VoteStructs, which keep track
   of who has voted/commented and what they said.

timelist.cpp:  contains the TimeList class, which descends from 
   StringList.  Reads in a list of events, and allows you to see which
   event is next, previous, new, etc.  This class should be rewritten,
   I think.  (Bad organization.)  CyberDJ's schedule and LiveDJ's
   list of live shows are both TimeLists.

songlist.cpp:  contains the SongList and SongStruct classes.  SongList
   is a static, sorted list of SongStructs.  CyberDJ currently uses
   two SongLists, one for the main song list and one for the promo list.
   SongStruct contains a song's artist, title, and filename, and can
   extract the artist and title from the filename.

linkedlist.cpp:  contains the LinkedList class, which implements a
   simple linked list.  Used by PlayList for the PlayStructs, and by
   PlayStruct for the CommentStruct and VoteStructs.

permissionlist.cpp:  contains the PermissionList class, which descends
   from StringList.  It reads a list of ip addresses and computer names
   (wildcards allows), which can be marked as either allowed or not
   allowed.  You can then ask the PermissionList to verify a particular
   computer or ip address, and it will tell you if it's allowed or not.
   CyberDJ currently uses three PermissionLists, one for requests off
   the song list, one for local network requests (and eventually
   uploads), and one for commenting and voting.

stringlist.cpp:  contains the StringList class, which is fundamental to
   a lot of stuff throughout the program.  StringList implements a
   static list of strings, which it can get from a file or from a null-
   separated list in memory, and allows you to get strings and search
   through the list.  StringList implements the #include, #dir, and
   #dirtree directives.

optionblock.cpp:  contains the OptionBlock class, which lets you get
   or set user options.  Adding or changing an option is as easy as
   adding a few lines to the optionblock.h file (as well as updating
   the option window resource.  You do not, however, have to change
   the optionswindow.cpp file at all!)

processlock.cpp:  contains the ProcessLock class, which allows for 
   mutual exclusion between threads.  Before using a shared resource,
   such as the main PlayList or the LiveDJMailList, the function will
   ask for a lock, so it knows that no other thread will be accessing
   it at the same time.  Currently, each PlayList comes with a 
   ProcessLock, and LiveDJ uses one too.

webstring.cpp:  contains the WebString class, and the OpaqueString and
   NonopaqueString classes which are descendants of WebString.  These
   classes allow strings in the convoluted text style used by URLs and
   form data to be converted into normal text, and vice versa.

messagedialog.cpp:  contains the MessageDialog class, which pops up a
   non-modal message dialog to inform the user that something is
   happening.

goodies.cpp:  contains a whole bunch of random functions, many having
   to do with string manipulation.  Includes wildcardcmp, the all-
   purpose string comparison function.

dategoodies.cpp:  contains functions that deal with date and time
   manipulation and output.

filenames.h:  contains definitions for every filename, directory name,
   and anything that could be part of a filename.  Changing the entire
   CyberDJ directory structure is as easy as modifying the definitions
   in this file.

cyberdj.rc:  is the resource script that defines the windows and their
   controls and various other resource objects.  It was generated by
   the resource editor, and cleaned up and organized manually.

resource.h:  contains the definitions for the resource id constants.
   (Except for the ones used by OptionsWindow, which are defined in
   optionblock.h)

helpstrings.h:  contains the text for the online help boxes.  The help
   strings are compiled into stringtable resources.


WHEW
""""
That's all the files.  :)  I use Borland C++, so I don't know if it'll
compile under Visual, but I don't see why not.

Let me know what you think.

-Bret
bret@ugcs.caltech.edu


