/* 
    These are the exceptions that fam++ can raise.

    Copyright (C) 2000 Ben Martin

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#ifndef INCLUDED_FAMEXCEPTIONS_HH
#define INCLUDED_FAMEXCEPTIONS_HH


namespace __FAM_NAMESPACE {

	// Forward decl
	class FamppRequest;

	class _exception : public exception {
  			string _what;
			string _extra;
			string _fullmsg;

			const string getSep() {
				return string("   ");
			}

		public:
			_exception(const string& what_arg): 
				_what (what_arg), _extra()
				{ }

			_exception(const string& what_arg, const string& extra): 
				_what (what_arg), _extra(extra)
				{ }

			virtual const char* what () { 
				if(string() != _extra) {
					_fullmsg = _what + getSep() + _extra;
					return _fullmsg.c_str();
				}
				return _what.c_str (); 
			}
		protected:
			_exception(): exception () 
				{ }
	};
	
	// FIXME:
	// Note that the template arg is really just ostream, but it must be a template arg
	// so that the compiler takes care of multiple template instances that are made by 
	// multiple inclusion.
	template <class ostreamT>
	ostream& operator<< (ostreamT& s, _exception ex) {
		return s << ex.what() << endl;
	}

	class FamppException : public _exception {
		public:
			FamppException(const string& what_arg):
				_exception(what_arg) 
			{}

			FamppException(const string& what_arg, const string& extra):
				_exception(what_arg,extra)
			{}

			FamppException():
				_exception(getStdFAMError())
			{}

			string getStdFAMError() {
				return "libfam Errors not used at the moment";//string("Fam exeption:")+string(FamErrlist[FAMErrno]);
			}
	};

	class getInstance_gnome_and_wait_user_wants_to_quit : public FamppException {
		public:
			getInstance_gnome_and_wait_user_wants_to_quit():
				FamppException("Could not connect to fam, and the user explicitly requested the application to quit")
				{}	
		
	};

	
	class FamppUnsupportedCopyByValueException : public FamppException {
		public:
			FamppUnsupportedCopyByValueException():
				FamppException("An attempt to copy a Fampp class by value was made that would violate the desired semantics")
				{}
	};


	class FamppOpenFailedException : public FamppException {
		public:
			FamppOpenFailedException()
				{}
	};


	class FamppCloseFailedException : public FamppException {
		public:
			FamppCloseFailedException()
				{}
	};

	class FamppRequestFailedException : public FamppException {
		public:
			FamppRequestFailedException(const FamppRequest* const req):
				FamppException(getStdFAMError(),
					string("hi"))
			{
			}
	};


	class FamppRequestCancelFailedException : public FamppRequestFailedException {
		public:
			FamppRequestCancelFailedException(const FamppRequest* const req):
				FamppRequestFailedException(req)
			{
			}
	};

	class FamppSuspendFailedException : public FamppRequestFailedException {
		public:
			FamppSuspendFailedException(const FamppRequest* const req):
				FamppRequestFailedException(req)
				{}
	};


	class FamppResumeFailedException : public FamppRequestFailedException {
		public:
			FamppResumeFailedException(const FamppRequest* const req):
				FamppRequestFailedException(req)
				{}
	};




///////


	class FamppMonitorInitFailedException : public FamppException {
		public:
			FamppMonitorInitFailedException()
				{}
		protected:
			FamppMonitorInitFailedException(
				const string& type, 
				const string& path):
					FamppException(getStdFAMError(),
						type + ":" + path)
				{}
	};

	class FamppDirMonitorInitFailedException : public FamppMonitorInitFailedException {
		public:
			FamppDirMonitorInitFailedException(string dirName):
				FamppMonitorInitFailedException(
					"dirName",dirName)
				{}
	};

	class FamppFileMonitorInitFailedException : public FamppMonitorInitFailedException {
		public:
			FamppFileMonitorInitFailedException(string dirName):
				FamppMonitorInitFailedException(
					"dirName",dirName)
				{}
	};



	class FamppNextEventFailedException : public FamppException {
		public:
			FamppNextEventFailedException()
				{}
	};

};

#endif /* INCLUDED_FAMEXCEPTIONS_HH */



