#! /usr/bin/env python

# BlinkenArea Stage Director
# Copyright 2013-2014 Stefan Schuermans <stefan@schuermans.info>
# Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
# a blinkenarea.org project - https://www.blinkenarea.org/

import re
from gi.repository import Pango

import time_fmt

class Playlist:
  """ playlist object, reads a playlist form a file and handles the playlist
  entries

  playlist file format:
    - each line is an entry or a stop point: <line> = <entry> | <stop point>
    - entries are played one after another
    - playing halts at stop points
    - <entry> = <name> <whitespace> <duration> <opt_comment>
    - <stop point> = <name> <opt_comment>
    - <name> = [A-Za-Z0-9_]+
    - <duration> = ((<hours>:)?<minutes>:)?<seconds>
    - <hours> = [0-9]+
    - <minutes> = [0-9]+
    - <seconds> = [0-9]+(.[0-9]+)
    - <opt_comment> = <whitespace> "#" <whitespace> <some text>"""

  def __init__(self):
    """create a new, empty playlist object"""
    self.entries = [] # list of entries
                      # entry = dictionary { "type": "normal" or "stop"
                      #                      "name": string, name of entry
                      #                      "durtaion": float, in seconds }
    self.reEntry = re.compile("^\s*([A-Za-z0-9_]+)\s+([0-9:.]+)\s*(#\s*(.*))?$")
    self.reStop = re.compile("^\s*([A-Za-z0-9_]+)\s*(#\s*(.*))?$")

  def read(self, filename):
    """read the playlist from filename, replacing the current playlist"""
    self.entries = []
    try:
      f = open(filename, "r")
      for line in f:
        mEntry = self.reEntry.match(line)
        if mEntry:
          name = mEntry.group(1)
          duration = time_fmt.str2sec(mEntry.group(2))
          if mEntry.group(4) is not None:
            comment = mEntry.group(4)
          else:
            comment = ""
          self.entries.append({"type":     "normal",
                               "name":     name,
                               "duration": duration,
                               "comment":  comment})
          #print("DEBUG playlist entry normal %s %f" %
          #      (self.entries[-1]["name"], self.entries[-1]["duration"]))
        else:
          mStop = self.reStop.match(line)
          if mStop:
            name = mStop.group(1)
            if mStop.group(3) is not None:
              comment = mStop.group(3)
            else:
              comment = ""
            self.entries.append({"type": "stop",
                                 "name": name,
                                 "comment":  comment})
            #print("DEBUG playlist entry stop")
      f.close()
    except IOError:
      pass

  def update(self, store):
    """update the contents of a Gtk ListStore with the contents of this
    playlist"""
    store.clear()
    idx = 0
    for entry in self.entries:
      if entry["type"] == "normal":
        name = entry["name"]
        duration = time_fmt.sec2str(entry["duration"])
        comment = entry["comment"]
      else:
        name = entry["name"]
        duration = "STOP"
        comment = entry["comment"]
      store.append([idx, Pango.Weight.NORMAL, name, duration, comment])
      idx = idx + 1