//
// 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
//

const CLASS_ID                = Components.ID("{61D8E631-FE24-499A-906C-6937D939EA71}");
const CLASS_NAME              = "Flock Protocol Channel";
const CONTRACT_ID             = "@flock.com/flock-channel;1";

const LOAD_NORMAL =                Components.interfaces.nsIRequest.LOAD_NORMAL;
const LOAD_BACKGROUND =            Components.interfaces.nsIRequest.LOAD_BACKGROUND;
const INHIBIT_CACHING =            Components.interfaces.nsIRequest.INHIBIT_CACHING;
const INHIBIT_PERSISTENT_CACHING = Components.interfaces.nsIRequest.INHIBIT_PERSISTENT_CACHING;
const LOAD_BYPASS_CACHE =          Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
const LOAD_FROM_CACHE =            Components.interfaces.nsIRequest.LOAD_FROM_CACHE;
const VALIDATE_ALWAYS =            Components.interfaces.nsIRequest.VALIDATE_ALWAYS;
const VALIDATE_NEVER =             Components.interfaces.nsIRequest.VALIDATE_NEVER;
const VALIDATE_ONCE_PER_SESSION =  Components.interfaces.nsIRequest.VALIDATE_ONCE_PER_SESSION;

function flockFlockChannel()
{
  debug("flockFlockChannel: starting up...\n");
}

flockFlockChannel.prototype = {

  contentCharset: "utf-8",
  contentLength: -1,
  contentType: "text/html",
  loadAttributes: null,
  loadGroup: null,
  notificationCallbacks: null,
  owner: null,
  securityInfo: null,
  shouldCache: false,
  bypassCache: false,
  loadFlags: null,
  
  init: function(AURI)
  {
    this.URI = AURI;
    this.originalURI = AURI;
    this._pending = true;
  },
  
  asyncOpen: function(listener, context)
  {
    this.listener = listener;
    this.context  = context;

    if (this.loadFlags & LOAD_BYPASS_CACHE || this.loadFlags & VALIDATE_ALWAYS) {
      // They pressed reload or shift+reload.
      this.bypassCache = true;
    } else {
      this.bypassCache = false;
    }
    if (this.loadFlags & INHIBIT_CACHING || this.loadFlags & INHIBIT_PERSISTENT_CACHING) {
      // For privacy reasons we shouldn't cache this (eg it is HTTPS).
      // XXX we do not currently honor this.
      this.shouldCache = false;
    } else {
      this.shouldCache = true;
    }

    if (this.loadGroup) {
      this.loadGroup.addRequest(this, null);
    }
  },

  open: function()
  {
    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  },
  
  // nsIRequest
  isPending: function()
  {
    return this._pending;
  },

  // nsIRequest
  status: Components.results.NS_OK,

  // nsIRequest
  cancel: function(status)
  {
    if (this._pending) {
      this._pending = false;
      this.listener.onStopRequest(this, this.context, status);
      if (this.loadGroup) {
        this.loadGroup.removeRequest(this, null, status);
      }
    }
    this.status = status;
  },

  // nsIRequest
  suspend: function()
  {
    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  },
  
  // nsIRequest
  resume: function()
  {
    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  },

  // nsIClassInfo
  getInterfaces: function(aCount)
  {
    var interfaces = [Components.interfaces.nsIChannel, Components.interfaces.flockIFlockChannel, Components.interfaces.nsIRequest, Components.interfaces.nsIClassInfo];
    aCount.value = interfaces.length;
    return interfaces;
  },

  // nsIClassInfo
  getHelperForLanguage: function(aLanguage)
  {
    return null;
  },

  // nsIClassInfo
  contractID: CONTRACT_ID,

  // nsIClassInfo
  classDescription: CLASS_NAME,

  // nsIClassInfo
  classID: CLASS_ID,

  // nsIClassInfo
  implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,

  // nsIClassInfo
  flags: null,
  
  // nsISupports
  QueryInterface: function(aIID)
  {
    if (!aIID.equals(Components.interfaces.nsISupports) && !aIID.equals(Components.interfaces.flockIFlockChannel) && !aIID.equals(Components.interfaces.nsIChannel) && !aIID.equals(Components.interfaces.nsIRequest) && !aIID.equals(Components.interfaces.nsIClassInfo))
      throw Components.results.NS_ERROR_NO_INTERFACE;
    return this;
  }

};

/******************************************************************************
 * XPCOM Functions for construction and registration
 ******************************************************************************/
var Module = {
  _firstTime: true,
  registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
  {
    if (this._firstTime) {
      this._firstTime = false;
      throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
    }
    aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
    aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, CONTRACT_ID, aFileSpec, aLocation, aType);
  },

  unregisterSelf: function(aCompMgr, aLocation, aType)
  {
    aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
    aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);        
  },
  
  getClassObject: function(aCompMgr, aCID, aIID)
  {
    if (!aIID.equals(Components.interfaces.nsIFactory))
      throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
    if (aCID.equals(CLASS_ID))
      return Factory;
    throw Components.results.NS_ERROR_NO_INTERFACE;
  },

  canUnload: function(aCompMgr) { return true; }
};

var Factory = {
  createInstance: function(aOuter, aIID)
  {
    if (aOuter != null)
      throw Components.results.NS_ERROR_NO_AGGREGATION;
    return (new flockFlockChannel()).QueryInterface(aIID);
  }
};

function NSGetModule(aCompMgr, aFileSpec) { return Module; }
