2019-01-02 16:11:22 +01:00
|
|
|
package playlist
|
|
|
|
|
|
|
|
|
|
import (
|
2019-01-02 19:06:45 +01:00
|
|
|
"log"
|
2019-01-02 16:11:22 +01:00
|
|
|
"time"
|
|
|
|
|
"errors"
|
|
|
|
|
"strconv"
|
|
|
|
|
"math/rand"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"../archive"
|
|
|
|
|
"../config"
|
|
|
|
|
)
|
|
|
|
|
|
2019-01-02 19:06:45 +01:00
|
|
|
var pln = log.Println
|
2019-01-02 16:11:22 +01:00
|
|
|
|
|
|
|
|
type Playlist struct {
|
|
|
|
|
NAME string
|
|
|
|
|
CTRACK config.Track_t
|
|
|
|
|
CALBUM config.Album_t
|
|
|
|
|
LIST []uint32
|
|
|
|
|
MAX int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PrettyPlaylist struct {
|
|
|
|
|
NAME string
|
|
|
|
|
CTRACK config.Track_t
|
|
|
|
|
CALBUM config.Album_t
|
|
|
|
|
LIST []config.Track_t
|
|
|
|
|
MAX int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func MakeRandom(name string, max int) (*Playlist, error) {
|
|
|
|
|
err := archive.Build()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p := &Playlist{NAME: name, MAX: max}
|
|
|
|
|
p.LIST = make([]uint32, max)
|
|
|
|
|
|
|
|
|
|
for i := 0; i < max; i++ {
|
|
|
|
|
r, _ := Random()
|
|
|
|
|
p.LIST[i] = r // might duplicate
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return p, nil;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Playlist) Encode() string {
|
|
|
|
|
|
|
|
|
|
pp := p.Pretty()
|
|
|
|
|
res, _ := json.Marshal(pp)
|
|
|
|
|
return string(res)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Decode(jsonstr string) (*Playlist, error) {
|
|
|
|
|
|
|
|
|
|
pp := &PrettyPlaylist{}
|
|
|
|
|
|
|
|
|
|
if err := json.Unmarshal([]byte(jsonstr), pp); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p := pp.Unpretty()
|
|
|
|
|
return p, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Playlist) Pretty() *PrettyPlaylist {
|
|
|
|
|
pp := &PrettyPlaylist{NAME: p.NAME, CTRACK: p.CTRACK, CALBUM: p.CALBUM, MAX: p.MAX}
|
|
|
|
|
pp.LIST = make([]config.Track_t, len(p.LIST))
|
|
|
|
|
for i := 0; i < len(p.LIST); i++ {
|
|
|
|
|
pp.LIST[i] = archive.Archive_map[p.LIST[i]]
|
|
|
|
|
}
|
|
|
|
|
return pp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (pp *PrettyPlaylist) Unpretty() *Playlist {
|
|
|
|
|
p := &Playlist{NAME: pp.NAME, CTRACK: pp.CTRACK, CALBUM: pp.CALBUM, MAX: pp.MAX}
|
|
|
|
|
p.LIST = make([]uint32, len(pp.LIST))
|
|
|
|
|
for i := 0; i < len(pp.LIST); i++ {
|
|
|
|
|
p.LIST = append(p.LIST, pp.LIST[i].ID)
|
|
|
|
|
}
|
|
|
|
|
return p
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// type PrettyPlaylist struct {
|
|
|
|
|
// NAME string
|
|
|
|
|
// CTRACK config.Track_t
|
|
|
|
|
// CALBUM config.Album_t
|
|
|
|
|
// LIST []config.Track_t
|
|
|
|
|
// MAX int
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (pp *PrettyPlaylist) Print() {
|
|
|
|
|
|
|
|
|
|
pln("Name: " + pp.NAME)
|
|
|
|
|
pln("CTRACK: " + pp.CTRACK.NAME)
|
|
|
|
|
pln("CALBUM: " + pp.CALBUM.NAME)
|
|
|
|
|
pln("Next:")
|
|
|
|
|
for i, r := range pp.LIST {
|
|
|
|
|
pln(" " + strconv.Itoa(i) + " - " + r.NAME)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-02 19:06:45 +01:00
|
|
|
func print(slice []uint32) {
|
|
|
|
|
for i, r := range slice {
|
|
|
|
|
pln(" " + strconv.Itoa(i) + " - " + archive.Archive_map[r].NAME)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// https://github.com/golang/go/wiki/SliceTricks
|
2019-01-02 16:11:22 +01:00
|
|
|
// https://stackoverflow.com/questions/33834742/remove-and-adding-elements-to-array-in-go-lang
|
|
|
|
|
|
|
|
|
|
func (p *Playlist) Pop() error {
|
|
|
|
|
if len(p.LIST) == 0 {
|
|
|
|
|
return errors.New("Playlist is empty")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
t := p.LIST[0]
|
|
|
|
|
if len(p.LIST) < 2 {
|
|
|
|
|
p.LIST = make([]uint32, 0)
|
|
|
|
|
} else {
|
|
|
|
|
p.LIST = p.LIST[1:]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p.CTRACK = archive.Archive_map[t]
|
|
|
|
|
p.CALBUM = config.Xcfg.Archive.ALBUMS[p.CTRACK.AID]
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Playlist) Push(track_id uint32) error {
|
|
|
|
|
if len(p.LIST) == p.MAX {
|
|
|
|
|
return errors.New("Playlist is full")
|
|
|
|
|
}
|
|
|
|
|
p.LIST = append(p.LIST, track_id)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Playlist) PushFront(track_id uint32) error {
|
|
|
|
|
if len(p.LIST) == p.MAX {
|
|
|
|
|
return errors.New("Playlist is full")
|
|
|
|
|
}
|
|
|
|
|
p.LIST = append([]uint32{ track_id }, p.LIST...) // don't forget '...''
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Playlist) Insert(track_id uint32, at_index int) error {
|
|
|
|
|
if at_index > p.MAX {
|
|
|
|
|
return errors.New("Invalid insert index")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p.LIST = append(p.LIST, 0)
|
|
|
|
|
copy(p.LIST[at_index+1:], p.LIST[at_index:])
|
|
|
|
|
p.LIST[at_index] = track_id
|
|
|
|
|
|
|
|
|
|
if len(p.LIST) > p.MAX {
|
|
|
|
|
p.LIST = p.LIST[:p.MAX]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-02 19:06:45 +01:00
|
|
|
func (p *Playlist) index(track_id uint32) int {
|
2019-01-02 16:11:22 +01:00
|
|
|
k := -1
|
2019-01-02 19:06:45 +01:00
|
|
|
for i := 0; i < len(p.LIST); i++ {
|
2019-01-02 16:11:22 +01:00
|
|
|
if p.LIST[i] == track_id { k = i }
|
|
|
|
|
}
|
2019-01-02 19:06:45 +01:00
|
|
|
return k
|
|
|
|
|
}
|
2019-01-02 16:11:22 +01:00
|
|
|
|
2019-01-02 19:06:45 +01:00
|
|
|
func (p *Playlist) Delete(track_id uint32) error {
|
|
|
|
|
k := p.index(track_id);
|
2019-01-02 16:11:22 +01:00
|
|
|
if k < 0 {
|
|
|
|
|
return errors.New("Invalid track ID")
|
|
|
|
|
}
|
|
|
|
|
p.LIST = append(p.LIST[:k-1], p.LIST[k+1:]...)
|
|
|
|
|
return nil
|
2019-01-02 19:06:45 +01:00
|
|
|
}
|
2019-01-02 16:11:22 +01:00
|
|
|
|
2019-01-02 19:06:45 +01:00
|
|
|
func (p *Playlist) Move(track_id uint32, at_index int) error {
|
|
|
|
|
if at_index > p.MAX {
|
|
|
|
|
return errors.New("Invalid insert index")
|
|
|
|
|
}
|
|
|
|
|
k := p.index(track_id);
|
|
|
|
|
if k < 0 {
|
|
|
|
|
return errors.New("Invalid track ID")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
slice_head := p.LIST[:k]
|
|
|
|
|
slice_move := p.LIST[k+1:at_index+1]
|
|
|
|
|
slice_tail := make([]uint32, len(p.LIST[at_index+1:]))
|
|
|
|
|
copy(slice_tail, p.LIST[at_index+1:])
|
|
|
|
|
|
|
|
|
|
// slice_move = append(slice_move, track_id)
|
|
|
|
|
|
|
|
|
|
pln("from_index: " + strconv.Itoa(k))
|
|
|
|
|
pln("at_index: " + strconv.Itoa(at_index))
|
|
|
|
|
pln("------")
|
|
|
|
|
pln("slice head: ")
|
|
|
|
|
print(slice_head)
|
|
|
|
|
pln("slice move: ")
|
|
|
|
|
print(slice_move)
|
|
|
|
|
pln("** ")
|
|
|
|
|
pln("slice tail: ")
|
|
|
|
|
print(slice_tail)
|
|
|
|
|
pln("...........................")
|
|
|
|
|
|
|
|
|
|
p.LIST = append(slice_head, append(append(slice_move, track_id), slice_tail...)...)
|
|
|
|
|
|
|
|
|
|
return nil
|
2019-01-02 16:11:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func Random() (uint32, string) {
|
|
|
|
|
rand.Seed(time.Now().UTC().UnixNano())
|
|
|
|
|
index := archive.Archive_map_keys[rand.Intn(len(archive.Archive_map_keys) - 1)]
|
|
|
|
|
return archive.Archive_map[index].ID, archive.Archive_map[index].NAME
|
|
|
|
|
}
|