// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2009
// http://flock.com
//
// This file may be used under the terms of the
// GNU General Public License Version 2 or later (the "GPL"),
// http://www.gnu.org/licenses/gpl.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// END FLOCK GPL
var _logger = Cc["@flock.com/logger;1"].createInstance(Ci.flockILogger);
_logger.init("topmedia");

const FAVES_MEDIA = "urn:media:favorites";

const FLOCK_NS = "http://flock.com/rdf#";
const NSCP_NS = 'http://home.netscape.com/NC-rdf#';
const RDF_NS = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';

var _coop = Cc["@flock.com/singleton;1"]
            .getService(Ci.flockISingleton)
            .getSingleton("chrome://flock/content/common/load-faves-coop.js")
            .wrappedJSObject;

var _photoApiMgr = Cc["@flock.com/photo-api-manager;1?"]
                   .getService(Ci.flockIPhotoAPIManager);

var favesRDF = Cc['@mozilla.org/rdf/datasource;1?name=flock-favorites']
               .getService(Ci.flockIRDFObservable);

var gTopMedia;

var draggingObserver = {
  onDragStart: function topsites_onDragStart(aEvent, aTransferData, aAction) {
    var url = aEvent.target.getAttribute("imageURL")
    var title = aEvent.target.getAttribute("title");

    if (!url) {
      return;
    }

    aTransferData.data = new TransferData();
    aTransferData.data.addDataForFlavour("text/x-moz-url", url + "\n" + title);
    var link = "<a href='" + url + "'>" + title + "</a>";
    aTransferData.data.addDataForFlavour("text/html", link);
    aTransferData.data.addDataForFlavour("text/unicode", url);
  },
  onDragOver: function topsites_onDragOver(aEvent, aTransferData, aAction) {
  },
  onDrop: function topsites_onDrop(aEvent, aTransferData, aAction) {
  },
  onDragExit: function topsites_onDragExit(aEvent, aTransferData, aAction) {
  }
}

function TopMedia(aContainerId) {
  this._mediaStreamBox = document.getElementById(aContainerId);

  this._rdfSvc = Cc["@mozilla.org/rdf/rdf-service;1"]
                 .getService(Ci.nsIRDFService);

  var prefs = Cc["@mozilla.org/preferences-service;1"]
              .getService(Ci.nsIPrefBranch);
  this.mMaxCount = prefs.getIntPref("flock.myworld.topmedia.count");

  var sb = Cc["@mozilla.org/intl/stringbundle;1"]
            .getService(Ci.nsIStringBundleService)
            .createBundle("chrome://flock/locale/start/myworld.properties");
  this.mQueryOn = sb.GetStringFromName("flock.myworld.media.queryOn");
}

// Delete elements from the bottom if it exceeds the MaxCount
TopMedia.prototype.insert =
function TopMedia_insert(aCoopMediaStream) {
  _logger.debug("insert " + aCoopMediaStream.id());
  var service = _photoApiMgr.getAPIFromShortname(aCoopMediaStream.service);

  // If it's already there, remove it first from its parent
  var elementCreated = false;
  var mediaElement = document.getElementById(aCoopMediaStream.id());
  if (mediaElement) {
    this._mediaStreamBox.removeChild(mediaElement);
    removeChildren(mediaElement)
  } else {
    // Create the new DOM node
    elementCreated = true;
    mediaElement = document.createElement("mediaquery");
    var name = aCoopMediaStream.name;
    mediaElement.id = aCoopMediaStream.id();
    mediaElement.setAttribute("svc", service.shortName);
    mediaElement.setAttribute("query", aCoopMediaStream.query);
    mediaElement.setAttribute("favIconLoc", aCoopMediaStream.favicon);
    mediaElement.setAttribute("name", name);
    var text = this.mQueryOn.replace("%query", name)
                            .replace("%service", service.title);
    mediaElement.setAttribute("description", text);
  }
  var startDrag = "nsDragAndDrop.startDrag(event, draggingObserver, true);"
  mediaElement.latestDate = aCoopMediaStream.latestDate;

  var richPhotoEntryEnum = aCoopMediaStream.children.enumerate();

  if (!richPhotoEntryEnum.hasMoreElements()) {
    // No content in stream.
    var sb = Cc["@mozilla.org/intl/stringbundle;1"]
             .getService(Ci.nsIStringBundleService)
             .createBundle("chrome://flock/locale/start/myworld.properties");

    var noContentMessage = sb.GetStringFromName("flock.myworld.media.noContent");

    var label = document.createElement("label");
    label.setAttribute("value", noContentMessage);
    label.setAttribute("class", "noMediaMessage");
    mediaElement.appendChild(label);
    insertElement(this._mediaStreamBox, mediaElement);
    return;
  }

  while (richPhotoEntryEnum.hasMoreElements()) {
    var richEntry = richPhotoEntryEnum.getNext();
    if (!richEntry) {
      continue;
    }
    var thumbnail = document.createElement("mediaitem");
    thumbnail.setAttribute("ondraggesture", startDrag);
    thumbnail.setAttribute("isVideo", richEntry.is_video);
    thumbnail.setAttribute("username", richEntry.username);
    thumbnail.setAttribute("title", richEntry.name);
    thumbnail.setAttribute("tooltiptext", richEntry.name);
    thumbnail.setAttribute("imageURL", richEntry.URL);
    thumbnail.setAttribute("imgClass", "imagePreview");
    thumbnail.setAttribute("imgSrc", richEntry.thumbnail);

    // Show an overlay of text over default images
    if (richEntry.thumbnail.match(/chrome:\/\//)) {
      var stack = document.createElement("stack");

      // We pull in all this because it's needed for openImage()
      stack.setAttribute("onclick", "openImage(this, event)");
      stack.setAttribute("ondraggesture", startDrag);
      stack.setAttribute("isVideo", richEntry.is_video);
      stack.setAttribute("username", richEntry.username);
      stack.setAttribute("title", richEntry.name);
      stack.setAttribute("tooltiptext", richEntry.name);
      stack.setAttribute("imageURL", richEntry.URL);
      stack.setAttribute("imgClass", "imagePreview");
      stack.setAttribute("imgSrc", richEntry.thumbnail);
      stack.setAttribute("class", "ratingStack");

      var vbox = document.createElement("vbox");
      vbox.setAttribute("class", "ratingBox");
      vbox.setAttribute("align", "center");
      
      var label = document.createElement("label");
      label.setAttribute("value", richEntry.rating_count);
      label.setAttribute("class", "ratingCount");

      var labelText = document.createElement("label");
      labelText.setAttribute("class", "ratingText");

      var ratingStrName = "flock.photo." + service.shortName + ".ratingText";
      try {
        var ratingTextValue =
          service.getStringBundle().GetStringFromName(ratingStrName);
        labelText.setAttribute("value", ratingTextValue);
      } catch (ex) {
        _logger.error("Service does not have a myworld ratings string defined");
      }

      vbox.appendChild(label);
      vbox.appendChild(labelText);

      stack.appendChild(thumbnail);
      stack.appendChild(vbox);

      mediaElement.appendChild(stack);
    } else {
      mediaElement.appendChild(thumbnail);
    }
  }
  insertElement(this._mediaStreamBox, mediaElement);

  if (elementCreated) {
    var os = Cc["@mozilla.org/observer-service;1"]
             .getService(Ci.nsIObserverService);
    os.notifyObservers(null, "refresh-myworld-size", false);
  }
}

TopMedia.prototype.remove =
function TopMedia_remove(aMediaQueryId) {
  var mediaElement = document.getElementById(aMediaQueryId);
  if (mediaElement) {
    this._mediaStreamBox.removeChild(mediaElement);
    setNoItemMessage(this._mediaStreamBox, "noMediaID");
  }
}

// Private method used recursively to walk the media query tree
TopMedia.prototype.insertAll =
function TopMedia_insertAll(aMediaQueryFolder) {
  var childrenEnum = aMediaQueryFolder.children.enumerate()
  while (childrenEnum.hasMoreElements()) {
    var child = childrenEnum.getNext();
    if (child.isA(_coop.Folder)) {
      this.insertAll(child);
      continue;
    }
    if (this._mediaStreamBox.childNodes.length < this.mMaxCount ||
        this._mediaStreamBox.lastChild.latestDate < child.latestDate) {
      // the media query is new enough
      this.insert(child);
    }
  }
}

// flockIRDFObserver
TopMedia.prototype.rdfChanged =
function TopMedia_rdfChanged(aDs, aType, aSource, aPredicate, aNewTarget, aOldTarget)
{
  if (aType == Ci.flockIRDFObserver.TYPE_CHANGE
      || aType == Ci.flockIRDFObserver.TYPE_ASSERT) {
    // A MediaQuery has just been refreshed
    var mediaQuery = _coop.get_from_resource(aSource);
    this.insert(mediaQuery);
    cutToMax(this._mediaStreamBox, this.mMaxCount);
    return;
  }

  if (aType == Ci.flockIRDFObserver.TYPE_UNASSERT) {
    // A MediaQuery is being deleted.
    this.remove(aSource.Value);
  }
}

TopMedia.prototype.init =
function TopMedia_init() {
  this.insertAll(_coop.get(FAVES_MEDIA));
  cutToMax(this._mediaStreamBox, this.mMaxCount);
  setNoItemMessage(this._mediaStreamBox, "noMediaID");

  // Observe the datasource
  favesRDF.addArcObserver(Ci.flockIRDFObserver.WATCH_TYPES,
                          null,
                          this._rdfSvc.GetResource(FLOCK_NS + "latestDate"),
                          null,
                          this);
  favesRDF.addArcObserver(Ci.flockIRDFObserver.TYPE_UNASSERT,
                          null,
                          this._rdfSvc.GetResource(RDF_NS + "type"),
                          this._rdfSvc.GetResource(NSCP_NS + "MediaQuery"),
                          this);
  gObsrvr = {};
  gObsrvr.observe = function date_observe(aSubject, aTopic, aString) {
    if (aTopic == "refresh-myworld-date") {
      var mediaStreamBox = document.getElementById("mediastreambox");
      var nodeList = mediaStreamBox.childNodes;
      for (var c = 0; c < nodeList.length; c++) {
        nodeList.item(c).updateDate();
      }
      _logger.debug("refreshed Media Dates");
    }
  }

  // Add observer for time change
  var os = Cc["@mozilla.org/observer-service;1"]
           .getService(Ci.nsIObserverService);
  os.addObserver(gObsrvr, "refresh-myworld-date", false);
}

TopMedia.prototype.uninit =
function TopMedia_uninit() {
  favesRDF.removeArcObserver(Ci.flockIRDFObserver.WATCH_TYPES,
                             null,
                             this._rdfSvc.GetResource(FLOCK_NS + "latestDate"),
                             null,
                             this);
  favesRDF.removeArcObserver(Ci.flockIRDFObserver.TYPE_UNASSERT,
                             null,
                             this._rdfSvc.GetResource(RDF_NS + "type"),
                             this._rdfSvc.GetResource(NSCP_NS + "MediaQuery"),
                             this);
  var os = Cc["@mozilla.org/observer-service;1"]
           .getService(Ci.nsIObserverService);
  os.removeObserver(gObsrvr, "refresh-myworld-date");
}

function onLoad() {
  var sb = Cc["@mozilla.org/intl/stringbundle;1"]
            .getService(Ci.nsIStringBundleService)
            .createBundle("chrome://flock/locale/start/myworld.properties");

  gTopMedia = new TopMedia("mediastreambox");
  gTopMedia.init();
}

function onUnload() {
  if (gTopMedia) {
    gTopMedia.uninit();
    gTopMedia = null;
  }
}
