/*
 * psdatabase.h - Author: Keith Fulton
 *
 * Copyright (C) 2001 Atomic Blue (info@planeshift.it, http://www.atomicblue.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 (version 2 of the License)
 * 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 __PSDATABASE_H__
#define __PSDATABASE_H__

#include <stdio.h>
#include <string.h>

#include "../../server/iserver/idal.h"      // Database Abstraction Layer Interface

struct iObjectRegistry;
class psAdminResponseList;
class stringList;
class csVector3;
class psString;
class csRandomGen;

// implementation of the plugin

#define  PS_DBNAME  "planeshift"
#define  PS_USER    "planeshift"
#define  PS_PASS    "planeshift"

class psDatabase
{
public:
    /** Initializing Constructor.
     *
     * @param objectreg: The object registry for later use.
     */
    psDatabase(iObjectRegistry *objectreg);

    /** Destructor.
     * Calls the Close() function upon destruction of the object.
     *
     * @see Close()
     */
    virtual ~psDatabase();

    /** Initialize the database manager.
     * This will connect to
     * the database and log on using the given username, password
     * and start using the given database.
     *
     * @param host: The URL of the server that hosts the mysql database.
     * @param user: The username for the database.
     * @param password: The password used to access the database.
     * @param database: The name of the database to use for the current user.
     * @return Returns success in initializing or faliure.
     * @see iConnection::Initialize()
     */
    virtual bool Initialize(const char* host, const char* user,
                            const char* password, const char* database);

    /// Closes sql database connection.
    void Close();

    /// Utility functions

    /** Returns the last error generated by SQL
     * 
     * @return Returns a string that describes the last sql error.
     * @see iConnection::GetLastError()
     */
    const char* GetLastSQLError ();

    /// Sets the last error that occured.
    void SetLastError(const char *str) { lasterror = str; }

    /** Returns the last error that occured.
     * This error is usually
     * intended to be explanatory to a user, rather than the SQL
     * error technical description of the problem.
     *
     * @return Returns a string that describes the last error that occured.
     * @see iConnection::GetLastError()
     */
    const char* GetLastError ();
    /** Returns the last query that was performed.
     * Used to help
     * diagnose why a particular error occurred.
     *
     * @return Returns a string that contains the last query performed.
     * @see iConnection::GetLastQuery()
     */
    const char* GetLastQuery ();

 protected:
    
    iObjectRegistry *object_reg;
    csRef<iDataConnection> mysql;

    /// Contains a string that describes the last error that happened.
    csString lasterror;

    int InsertResponse ( psAdminResponseList& responses );
    int InsertResponse ( csString &response );

    int InsertResponseSet( stringList& responseSet );
    int InsertTrigger( const char* trigger, const char* area, 
                      int maxAttitude, int minAttitude, 
                      int responseID, int priorID );
};


/**
 * This is a wrapper class for result sets which makes syntax for getting
 * at the data easier and also uses dtors to make ResultSets safer from memory leaks.
 */
struct Result
{
    iResultSet *rs;

    Result() { rs = NULL; }
    Result(iResultSet* resset) : rs(resset) {}
    ~Result() { if (rs) rs->Release(); }

    bool IsValid() { return rs != NULL; }

    void operator = (iResultSet* resset)
    { 
        if (rs) rs->Release();
        rs = resset; 
    }

    iResultRow& operator[](unsigned long whichrow)
    {
        return (*rs)[whichrow];
    }
    
    unsigned long Count(void) { return rs->Count(); }
};



#endif
