package playlist import ( "log" "time" "errors" "strconv" "math/rand" "encoding/json" "../archive" "../config" ) var pln = log.Println 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) } } 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 // 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 } func (p *Playlist) index(track_id uint32) int { k := -1 for i := 0; i < len(p.LIST); i++ { if p.LIST[i] == track_id { k = i } } return k } func (p *Playlist) Delete(track_id uint32) error { k := p.index(track_id); if k < 0 { return errors.New("Invalid track ID") } p.LIST = append(p.LIST[:k-1], p.LIST[k+1:]...) return nil } 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 } 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 }