/* This file is -*-C++-*-
------------------------------------------------------------------------------
MetaCam - Extract EXIF information from digital camera files, with
support for Vendor specific blocks.
Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org)

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

$Id: metacam.h,v 1.6 2004/08/21 17:11:17 daniel Exp $

*/

#ifndef METACAM_H_INCLUDED
#define METACAM_H_INCLUDED

#include <map>

#include "metatiff.h"

class idpair
{
private:
    unsigned long tag;
    unsigned short type;
public:
    idpair() : tag(0), type(0) {};
    idpair(unsigned long a, unsigned short b) : tag(a), type(b) {};

    bool operator==(const idpair &i) const {
	return (tag==i.tag) && (type == i.type);
    }
    bool operator!=(const idpair &i) const {
	return (tag!=i.tag) || (type != i.type);
    }
    bool operator<=(const idpair &i) const {
	if (tag < i.tag) return true;
	if (tag > i.tag) return false;
	return (type <= i.type);
    }
    bool operator<(const idpair &i) const {
	if (tag < i.tag) return true;
	if (tag > i.tag) return false;
	return (type < i.type);
    }
    bool operator>(const idpair &i) const {
	if (tag > i.tag) return true;
	if (tag < i.tag) return false;
	return (type > i.type);
    }
    bool operator>=(const idpair &i) const {
	if (tag > i.tag) return true;
	if (tag < i.tag) return false;
	return (type >= i.type);
    }
};


typedef map<idpair, IFDEntry> tagmap;

class OutputContext
{
private:
    map<string,string> cmap;
public:
    OutputContext() {};
    virtual ~OutputContext();

    string getContextValue(string key) {
	map<string,string>::iterator iter = cmap.find(key);
	if (iter == cmap.end()) return string();
	return (*iter).second;
    }
    void setContextValue(string key, string val) {
	cmap[key] = val;
    }
    bool hasContextValue(string key) {
	map<string,string>::iterator iter = cmap.find(key);
	return (iter != cmap.end());
    }

    virtual ostream &startBlock(const char *hdr) = 0;
    virtual ostream &startBlock(const string &hdr) = 0;
    virtual ostream &os() = 0; 
    virtual void endBlock() = 0;
};

class OutputDriver
{
public:
    virtual ~OutputDriver();
    virtual void startFile(const char *fname) = 0;
    virtual OutputContext *startGroup(const char *header) = 0;
    virtual OutputContext *startGroup(const string &header) = 0;
    virtual void endGroup() = 0;
    virtual void endFile() = 0;
    virtual void close() = 0;
};

typedef void dpyFunction(OutputContext &ctx, const char *, const IFDEntry &e,
			 const void *fdata);

struct knowntag
{
    unsigned long tag;
    unsigned short type;
    int verbose;
    const char *name;
    dpyFunction *func;
    const void *funcdata;
};

struct lookupValue
{
    int key;
    const char *value;
};

#endif /* METACAM_H_INCLUDED */
