/* vim: ts=2 sw=2 expandtab
 * 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
 */

#include "nsIRDFDataSource.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "flockIIndexer.h"
#include "flockILogger.h"
#include "flockIProfiler.h"
#include "nsITimer.h"
#include "nsIRDFObserver.h"
#include "flockIRDFObserver.h"
#include "rdfIDataSource.h"
#include "nsCOMArray.h"

class flockRDFService : public nsIRDFDataSource,
                        public nsIRDFRemoteDataSource,
                        public nsIObserver,
                        public nsITimerCallback,
                        public nsIRDFObserver,
                        public flockIRDFObservable,
                        public rdfIDataSource
{
public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIRDFDATASOURCE
  NS_DECL_NSIRDFREMOTEDATASOURCE
  NS_DECL_NSIOBSERVER
  NS_DECL_NSITIMERCALLBACK
  NS_DECL_NSIRDFOBSERVER
  NS_DECL_FLOCKIRDFOBSERVABLE
  NS_DECL_RDFIDATASOURCE

  flockRDFService();

  static flockRDFService* GetSingleton ();

private:
  ~flockRDFService () {
  }

  /* called on construction (app-startup) */
  nsresult Initialize();

  /* called when we're ready (profile-after-change) */
  nsresult Setup();

  /* called to tell our users to startup (flock-data-startup) */
  nsresult StartupNotify();

  /* called when we're about to go away (xpcom-shutdown) */
  nsresult Shutdown();

  /* this is the datasource */
  nsCOMPtr<nsIRDFDataSource> mDataSource;
  nsCOMPtr<nsIRDFRemoteDataSource> mRemoteDataSource;

  /* the observer service */
  nsCOMPtr<nsIObserverService> mObserverService;

  /* the indexer service */
  nsCOMPtr<flockIIndexer> mIndexerService;

  /* the timer used to flush to disk */
  nsCOMPtr<nsITimer> mFlushTimer;

  /* If TRUE, the datasource should be flushed at the next opportunity */
  PRBool mDirty;

  /* Logger */
  nsCOMPtr<flockILogger> mLogger;

  /* Profiler */
  nsCOMPtr<flockIProfiler> mProfiler;

  /* what patterns are we matching? */
  class Pattern : public nsISupports {
    public:
      NS_DECL_ISUPPORTS

      Pattern (PRUint16 aType, 
               nsIRDFResource* aSubject, 
               nsIRDFResource* aPredicate,
               nsIRDFNode* aObject,
               flockIRDFObserver* aObserver) :
        mType (aType), mSubject (aSubject), mPredicate (aPredicate),
        mObject (aObject), mObserver (aObserver) { }

      NS_IMETHOD Match (nsIRDFDataSource* aDataSource,
                        PRUint16 aType, 
                        nsIRDFResource* aSubject, 
                        nsIRDFResource* aPredicate,
                        nsIRDFNode* aObject,
                        nsIRDFNode* aOldObject);

      PRBool Equals(Pattern *aPattern);

      PRUint16 mType;
      nsCOMPtr<nsIRDFResource> mSubject;
      nsCOMPtr<nsIRDFResource> mPredicate;
      nsCOMPtr<nsIRDFNode> mObject;
      nsCOMPtr<flockIRDFObserver> mObserver;
  };
  nsCOMArray<Pattern> mPatterns;

  NS_IMETHOD Match (PRUint16 aType, 
                    nsIRDFResource* aSubject, 
                    nsIRDFResource* aPredicate,
                    nsIRDFNode* aObject,
                    nsIRDFNode* aOldObject);

protected:
};

