1 /*
2  * Copyright (c) 2010, 2011 Ryan Flannery <ryan.flannery@gmail.com>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #ifndef PLAYLIST_H
18 #define PLAYLIST_H
19 
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 
23 #include <err.h>
24 #include <errno.h>
25 #include <glob.h>
26 #include <libgen.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 
32 #include "debug.h"
33 #include "meta_info.h"
34 
35 #include "compat.h"
36 
37 #define PLAYLIST_CHUNK_SIZE   100
38 #define DEFAULT_HISTORY_SIZE  100
39 extern int history_size;
40 
41 typedef struct {
42 #define CHANGE_ADD    0
43 #define CHANGE_REMOVE 1
44    short       type;
45    size_t      size;
46    meta_info **files;
47    int         location;
48 
49 } playlist_changeset;
50 
51 /* the core playlist structure */
52 typedef struct {
53    char  *filename;     /* filename containing the playlist */
54    char  *name;         /* name of the playlist used in display */
55    bool   needs_saving; /* does this playlist have unsaved changes? */
56 
57    /* the array of files (their meta information) in the playlist */
58    meta_info **files;
59    int         nfiles;     /* number of files in the playlist */
60    int         capacity;   /* current size malloc()'d for the files */
61 
62    /* history of the playlist */
63    playlist_changeset   **history;        /* complete history */
64    int                    hist_present;   /* current changeset in history */
65 
66 } playlist;
67 
68 /*
69  * IMPORTANT NOTES ABOUT THE "playlist" STRUCTURE:
70  * 1. The elements of the "files" array are simply pointers to the
71  *    already existing meta-info elements in the media database.
72  *
73  * 2. When loading a playlist from a file, each element of the playlist
74  *    is compared against the media database to find a corresponding entry.
75  *    If no such file exists in the media database, a new record is added
76  *    to the DB but it contains *only* the filename read from the playlist
77  *    file (no meta info).
78  *
79  * 3. The media database mentioned above is simply an array of meta_info
80  *    structs, passed to the functions when necessary below.
81  */
82 
83 /* create/destroy/duplicate playlist structs */
84 playlist *playlist_new(void);
85 void playlist_free(playlist *p);
86 playlist *playlist_dup(const playlist *original, const char *filename,
87                        const char* name);
88 
89 /* add/remove/replace files from a playlist */
90 void playlist_files_add(playlist *p, meta_info **f, int start, int size, bool);
91 void playlist_files_append(playlist *p, meta_info **f, int size, bool);
92 void playlist_files_remove(playlist *p, int start, int size, bool);
93 void playlist_file_replace(playlist *p, int index, meta_info *newEntry);
94 
95 /* load/save/delete playlists from/to/from filesystem */
96 playlist *playlist_load(const char *filename, meta_info **db, int ndb);
97 void playlist_save(const playlist *p);
98 void playlist_delete(playlist *p);
99 
100 /* filter a playlist to all records matching/not-matching a given string */
101 playlist *playlist_filter(const playlist *p, bool m);
102 
103 /* retrieve all playlist files in a given directory and return number found */
104 int retrieve_playlist_filenames(const char *dirname, char ***files);
105 
106 /* for modification and use of the playlist history */
107 playlist_changeset *changeset_create(short t, size_t s, meta_info **f, int l);
108 void changeset_free(playlist_changeset *c);
109 
110 playlist_changeset **playlist_history_new();
111 void playlist_history_free(playlist *p);
112 
113 void playlist_history_push(playlist *p, playlist_changeset *c);
114 int  playlist_undo(playlist *p);
115 int  playlist_redo(playlist *p);
116 
117 #endif
118