/**
 * @param params {Object} parameters for the server function.
 *    Parameter name is object property, property value is parameter value.
 *    Values will be encoded automatically, so they must be unencoded.
 * @param host {String} Zeipis core server hostname:port, e.g. "marchingband:4962".
 * @param successCallback {Function(Array of Recording)}
 * @param errorCallback {Function(Exception or error msg string)}
 * @throws XMLHttpRequest exceptions and others
 */
function RecordingsList(params, host, successCallback, errorCallback)
{
  var url = "http://" + host + "/recorded/list/";
  this._host = host;
  this._onlyDone = true;
  var me = this;
  FetchHTTP.call(this, url, params, false,
  function(result)
  {
    me._readXML(result, successCallback);
  },
  errorCallback);
  this.start();
}
RecordingsList.prototype =
{
  _readXML : function(xml, successCallback)
  {
    var result = new Array();
    // @see API.txt
    for each (x in xml)
    {
      try {
        let r = new Recording(x, this._host);
        if (this._onlyDone && ! r.done)
          continue;
        result.push(r);
      } catch (e) { errorNonCritical(e); }
    }
    successCallback(result);
  }
}
extend(RecordingsList, FetchHTTP);

function Recording(xml, host)
{
  this.readFromXML(xml);
  this._serverhost = host;
}
Recording.prototype =
{
  // object is invalid, if ID or title are null
  id : null, // globally unique and stable ID
  title : null, 
  subtitle : "",
  fullTitle : null,
  originaltitle : null, 
  originalsubtitle : null, 
  description : null, 
  showtype : null, // kShowtype*
  genre : null,
  firstshown : null,
  videoURL : null, // {String} full res and full length video
  previewImageURL : null, // {String}
  previewVideoURL : null, // {String}
  seen : null,
  keep : null,
  broken : null,
  // Internal only
  _serverhost : null, // {String} hostname:port of Zeipis server

  markSeen : function(newValue, successCallback, errorCallback)
  {
    var me = this;
    this._mark("seen", newValue, function() {
      me.seen = newValue;
      successCallback();
    }, errorCallback);
  },
  markKeep : function(newValue, successCallback, errorCallback)
  {
    var me = this;
    this._mark("keep", newValue, function() {
      me.keep = newValue;
      successCallback();
    }, errorCallback);
  },
  markBroken : function(newValue, successCallback, errorCallback)
  {
    var me = this;
    this._mark("broken", newValue, function() {
      me.broken = newValue;
      successCallback();
    }, errorCallback);
  },
  _mark : function(param, newValue, successCallback, errorCallback)
  {
    assert(typeof(newValue) == "boolean", "newValue must be boolean");
    var url = "http://" + this._serverhost + "/recorded/management/mark/" + this.id + "?" + param + "=" + newValue;
    new FetchHTTP(url, null, true, successCallback, errorCallback).start();
  },
  deleteVideo : function(successCallback, errorCallback)
  {
    var url = "http://" + this._serverhost + "/recorded/management/delete/" + this.id;
    new FetchHTTP(url, null, true, successCallback, errorCallback).start();
  },
  /*
  refreshObjectData : function(successCallback, errorCallback)
  {
    var me = this;
    new RecordingsList({ recordid : String(id) }, this._serverhost,
    function(xml)
    {
      me.readFromXML(xml.*[0]);
      successCallback;
    },
    errorCallback);
  },
  */

  readFromXML : function(x)
  {
    this.done = ("@done" in x && x.@done == "true");
    this.id = x.@recordingid.toString();
    this.title = this.fullTitle = x.title.toString();
    if ("subtitle" in x && x.subtitle)
    {
      this.subtitle = x.subtitle.toString();
      this.fullTitle += " - " + this.subtitle.toString();
    }
    if ("description" in x && x.description)
      this.description = x.description.toString();
    if ("originaltitle" in x && x.originaltitle)
      this.originaltitle = x.originaltitle.toString();
    if ("originalsubtitle" in x && x.originalsubtitle)
      this.originalsubtitle = x.originalsubtitle.toString();
    if ("genre" in x && x.genre)
      this.genre = x.genre.toString();
    if ("firstshown" in x && "@year" in x.firstshown)
      this.firstshown = parseInt(x.firstshown.@year);
    if ("showtype" in x && "@name" in x.showtype)
    {
      let t = x.showtype.@name;
      if (t == "movie")
        this.showtype = Recording.kShowtypeMovie;
      else if (t == "series")
        this.showtype = Recording.kShowtypeSeries;
      else if (t == "tvshow")
        this.showtype = Recording.kShowtypeTVShow;
      else if (t == "news")
        this.showtype = Recording.kShowtypeNews;
      else if (t == "sports")
        this.showtype = Recording.kShowtypeSports;
    }
    if ("location" in x && "@url" in x.location)
      this.videoURL = x.location.@url.toString();
    for each (xpreview in x.preview)
    {
      if ("@type" in xpreview && xpreview.@type == "image" &&
        "@url" in xpreview)
        this.previewImageURL = x.preview.@url.toString();
      if ("@type" in xpreview && xpreview.@type == "video" &&
        "@url" in xpreview)
          this.previewVideoURL = x.preview.@url.toString();
    }
    if ("management" in x)
    {
      if ("@seen" in x.management)
        this.seen = x.management.@seen == "true";
      if ("@keep" in x.management)
        this.keep = x.management.@keep == "true";
    }
  },
  
  __end : null
}
Recording.kShowtypeMovie = 1;
Recording.kShowtypeSeries = 2; // episode of a series
Recording.kShowtypeTVShow = 3; // game show, cooking etc.
Recording.kShowtypeNews = 4;
Recording.kShowtypeSports = 5;
