/* The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 * 
 * 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.
 * 
 * The Original Code is the Bugzilla Bug Tracking System.
 * 
 * The Initial Developer of the Original Code is Netscape Communications
 * Corporation. Portions created by Netscape are
 * Copyright (C) 1998 Netscape Communications Corporation. All
 * Rights Reserved.
 * 
 * Contributor(s): Myk Melez <myk@mozilla.org>
 */

// When the XUL window finishes loading, load the RDF data into it.
window.addEventListener('load', loadData, false);

// The base URL of this Bugzilla installation; derived from the page's URL.
var gBaseURL = window.location.href.replace(/(jar:)?(.*?)duplicates\.(jar!|xul).*/, "$2");

function loadData()
{
  // Loads the duplicates data as an RDF data source, attaches it to the tree,
  // and rebuilds the tree to display the data.

  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  
  // Get the RDF service so we can use it to load the data source.
  var rdfService = 
    Components
      .classes["@mozilla.org/rdf/rdf-service;1"]
        .getService(Components.interfaces.nsIRDFService);

  // When a bug report loads in the content iframe, a 'load' event bubbles up
  // to the browser window, which calls this load handler again, which reloads
  // the RDF data, which causes the tree to lose the selection.  To prevent
  // this, we have to remove this handler.
  window.removeEventListener('load', loadData, false);

  // The URL of the RDF file; by default for performance a static file 
  // generated by collectstats.pl, but a call to duplicates.cgi if the page's 
  // URL contains parameters (so we can dynamically generate the RDF data 
  // based on those parameters).
  var dataURL = gBaseURL + "data/duplicates.rdf";
  if (window.location.href.search(/duplicates\.xul\?.+/) != -1)
    dataURL = window.location.href.replace(/(duplicates\.jar!\/)?duplicates\.xul\?/, "duplicates.cgi?ctype=rdf&");
  
  // Get the data source and add it to the XUL tree's database to populate
  // the tree with the data.
  var dataSource = rdfService.GetDataSource(dataURL);
  
  // If we're using the static file, add an observer that detects failed loads
  // (in case this installation isn't generating the file nightly) and redirects
  // to the CGI version when loading of the static version fails.
  if (window.location.href.search(/duplicates\.xul\?.+/) == -1)
  {
    var sink = dataSource.QueryInterface(Components.interfaces.nsIRDFXMLSink);
    sink.addXMLSinkObserver(StaticDataSourceObserver);
  }
  
  // Add the data source to the tree, set the tree's "ref" attribute
  // to the base URL of the data source, and rebuild the tree.
  var resultsTree = document.getElementById('results-tree');
  resultsTree.database.AddDataSource(dataSource);
  resultsTree.setAttribute('ref', gBaseURL + "data/duplicates.rdf");
  resultsTree.builder.rebuild();
}

function getBugURI()
{
  var tree = document.getElementById('results-tree');
  var index = tree.currentIndex;

  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  var builder = tree.builder.QueryInterface(Components.interfaces.nsIXULTreeBuilder);
  var resource = builder.getResourceAtIndex(index);

  return resource.Value;
}

function loadBugInWindow()
{
  // Loads the selected bug in the browser window, replacing the duplicates report
  // with the bug report.

  var bugURI = getBugURI();
  window.location = bugURI;
}

function loadBugInPane()
{
  // Loads the selected bug in the iframe-based content pane that is part of 
  // this XUL document.

  var splitter = document.getElementById('report-content-splitter');
  var state = splitter.getAttribute('state');
  if (state != "collapsed")
  {
    var bugURI = getBugURI();
    var browser = document.getElementById('content-browser');
    browser.setAttribute('src', bugURI);
  }
}

var StaticDataSourceObserver = {
  onBeginLoad: function(aSink) { } , 
  onInterrupt: function(aSink) { } , 
  onResume: function(aSink) { } , 
  onEndLoad: function(aSink)
  {
    // Removes the observer from the data source so it doesn't stay around
    // when duplicates.xul is reloaded from scratch.
    
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
    
    aSink.removeXMLSinkObserver(StaticDataSourceObserver);
  } , 
  onError: function(aSink, aStatus, aErrorMsg)
  {
    // Tries the dynamic data source since the static one failed to load.
    
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
    
    // Get the RDF service so we can use it to load the data source.
    var rdfService = 
      Components
        .classes["@mozilla.org/rdf/rdf-service;1"]
          .getService(Components.interfaces.nsIRDFService);
    
    // Remove the observer from the data source so it doesn't stay around
    // when duplicates.xul is reloaded from scratch.
    aSink.removeXMLSinkObserver(StaticDataSourceObserver);
    
    // Remove the static data source from the tree.
    var oldDataSource = aSink.QueryInterface(Components.interfaces.nsIRDFDataSource);
    var resultsTree = document.getElementById('results-tree');
    resultsTree.database.RemoveDataSource(oldDataSource);

    // Munge the URL to point to the CGI and load the data source.
    var dataURL = gBaseURL + "duplicates.cgi?ctype=rdf";
    newDataSource = rdfService.GetDataSource(dataURL);
    
    // Add the data source to the tree and rebuild the tree with the new data.
    resultsTree.database.AddDataSource(newDataSource);
    resultsTree.builder.rebuild();
  }
};
