/*
   (c) Copyright 2001-2008  The world wide DirectFB Open Source Community (directfb.org)
   (c) Copyright 2000-2004  Convergence (integrated media) GmbH

   All rights reserved.

   Written by Denis Oliver Kropp <dok@directfb.org>,
              Andreas Hundt <andi@fischlustig.de>,
              Sven Neumann <neo@directfb.org>,
              Ville Syrjälä <syrjala@sci.fi> and
              Claudio Ciccani <klan@users.sf.net>.

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

   This library 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
   Lesser General Public License for more details.

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

#ifndef __DIRECT__RESULT_H__
#define __DIRECT__RESULT_H__

#include "./types.h"

/**********************************************************************************************************************/

#define D_RESULT_TYPE_CHAR_MASK         ((unsigned int) 0x2F)
#define D_RESULT_TYPE_CHAR_MIN          ((unsigned int) 0x30)
#define D_RESULT_TYPE_CHAR_MAX          (D_RESULT_TYPE_CHAR_MIN + D_RESULT_TYPE_CHAR_MASK)
#define D_RESULT_TYPE_CHAR_MUL_0        ((unsigned int) 1)
#define D_RESULT_TYPE_CHAR_MUL_1        ((unsigned int)(D_RESULT_TYPE_CHAR_MASK + 1))
#define D_RESULT_TYPE_CHAR_MUL_2        (D_RESULT_TYPE_CHAR_MUL_1 * D_RESULT_TYPE_CHAR_MUL_1)
#define D_RESULT_TYPE_CHAR_MUL_3        (D_RESULT_TYPE_CHAR_MUL_1 * D_RESULT_TYPE_CHAR_MUL_2)
#define D_RESULT_TYPE_CHAR( C )         (((unsigned int)(C) - D_RESULT_TYPE_CHAR_MIN) & D_RESULT_TYPE_CHAR_MASK)
#define D_RESULT_TYPE_SPACE             ((unsigned int)(0xFFFFFFFF / (D_RESULT_TYPE_CHAR_MASK * D_RESULT_TYPE_CHAR_MUL_3 +   \
                                                                      D_RESULT_TYPE_CHAR_MASK * D_RESULT_TYPE_CHAR_MUL_2 +   \
                                                                      D_RESULT_TYPE_CHAR_MASK * D_RESULT_TYPE_CHAR_MUL_1 +   \
                                                                      D_RESULT_TYPE_CHAR_MASK * D_RESULT_TYPE_CHAR_MUL_0) - 1))

/**********************************************************************************************************************/

#ifndef DIRECT_DISABLE_DEPRECATED


#define D_RESULT_TYPE_BASE( a,b,c )                         \
     D_RESULT_TYPE_CODE_BASE( '@', a,b,c )


#define D_RESULT_TYPE_MAX( a,b,c )                          \
     (D_RESULT_TYPE_BASE( a,b,c ) + D_RESULT_TYPE_SPACE - 1)


#define D_RESULT_TYPE_IS( code, a,b,c )                     \
     ((code) >= D_RESULT_TYPE_BASE(a,b,c) && (code) <= D_RESULT_TYPE_MAX(a,b,c))

#endif


/*
 * Generate result code base for API ('A','B','C','D'), e.g. ('C','O','R','E')
 *
 * Allowed are ASCII values between (inclusive)
 *   D_RESULT_TYPE_CHAR_MIN   (0x30)    and
 *   D_RESULT_TYPE_CHAR_MAX   (0x5F)
 *
 *
 *  0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?
 *
 *  @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O
 *
 *  P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _
 *
 */
#define D_RESULT_TYPE_CODE_BASE(a,b,c,d)     ((D_RESULT_TYPE_CHAR( a ) * (D_RESULT_TYPE_CHAR_MUL_3) +  \
                                               D_RESULT_TYPE_CHAR( b ) * (D_RESULT_TYPE_CHAR_MUL_2) +  \
                                               D_RESULT_TYPE_CHAR( c ) * (D_RESULT_TYPE_CHAR_MUL_1) +  \
                                               D_RESULT_TYPE_CHAR( d ) * (D_RESULT_TYPE_CHAR_MUL_0)) * \
                                              D_RESULT_TYPE_SPACE)

#define D_RESULT_TYPE(code)                  ((code) - ((code) % D_RESULT_TYPE_SPACE))
#define D_RESULT_INDEX(code)                 ((code) % D_RESULT_TYPE_SPACE)

/**********************************************************************************************************************/

typedef enum {
     DR_OK,              /* No error occured */


     DR__RESULT_BASE = D_RESULT_TYPE_CODE_BASE( 'D','R','_', '1' ),

     DR_FAILURE,         /* A general or unknown error occured */
     DR_INIT,            /* A general initialization error occured */
     DR_BUG,             /* Internal bug or inconsistency has been detected */
     DR_DEAD,            /* Interface has a zero reference counter (available in debug mode) */
     DR_UNSUPPORTED,     /* The requested operation or an argument is (currently) not supported */
     DR_UNIMPLEMENTED,   /* The requested operation is not implemented, yet */
     DR_ACCESSDENIED,    /* Access to the resource is denied */
     DR_INVAREA,         /* An invalid area has been specified or detected */
     DR_INVARG,          /* An invalid argument has been specified */
     DR_NOLOCALMEMORY,   /* There's not enough local system memory */
     DR_NOSHAREDMEMORY,  /* There's not enough shared system memory */
     DR_LOCKED,          /* The resource is (already) locked */
     DR_BUFFEREMPTY,     /* The buffer is empty */
     DR_FILENOTFOUND,    /* The specified file has not been found */
     DR_IO,              /* A general I/O error occured */
     DR_BUSY,            /* The resource or device is busy */
     DR_NOIMPL,          /* No implementation for this interface or content type has been found */
     DR_TIMEOUT,         /* The operation timed out */
     DR_THIZNULL,        /* 'thiz' pointer is NULL */
     DR_IDNOTFOUND,      /* No resource has been found by the specified id */
     DR_DESTROYED,       /* The requested object has been destroyed */
     DR_FUSION,          /* Internal fusion error detected, most likely related to IPC resources */
     DR_BUFFERTOOLARGE,  /* Buffer is too large */
     DR_INTERRUPTED,     /* The operation has been interrupted */
     DR_NOCONTEXT,       /* No context available */
     DR_TEMPUNAVAIL,     /* Temporarily unavailable */
     DR_LIMITEXCEEDED,   /* Attempted to exceed limit, i.e. any kind of maximum size, count etc */
     DR_NOSUCHMETHOD,    /* Requested method is not known */
     DR_NOSUCHINSTANCE,  /* Requested instance is not known */
     DR_ITEMNOTFOUND,    /* No such item found */
     DR_VERSIONMISMATCH, /* Some versions didn't match */
     DR_EOF,             /* Reached end of file */
     DR_SUSPENDED,       /* The requested object is suspended */
     DR_INCOMPLETE,      /* The operation has been executed, but not completely */
     DR_NOCORE,          /* Core part not available */
     DR_SIGNALLED,       /* Received a signal, e.g. while waiting */
     DR_TASK_NOT_FOUND,  /* The corresponding task has not been found */

     DR__RESULT_END,
     /*
         * Aliases for backward compatibility and uniform look in DirectFB code
          */
     DFB_OK              = DR_OK,                 /* No error occured. */
     DFB_FAILURE         = DR_FAILURE,            /* A general or unknown error occured. */
     DFB_INIT            = DR_INIT,               /* A general initialization error occured. */
     DFB_BUG             = DR_BUG,                /* Internal bug or inconsistency has been detected. */
     DFB_DEAD            = DR_DEAD,               /* Interface has a zero reference counter (available in debug mode). */
     DFB_UNSUPPORTED     = DR_UNSUPPORTED,        /* The requested operation or an argument is (currently) not supported. */
     DFB_UNIMPLEMENTED   = DR_UNIMPLEMENTED,      /* The requested operation is not implemented, yet. */
     DFB_ACCESSDENIED    = DR_ACCESSDENIED,       /* Access to the resource is denied. */
     DFB_INVAREA         = DR_INVAREA,            /* An invalid area has been specified or detected. */
     DFB_INVARG          = DR_INVARG,             /* An invalid argument has been specified. */
     DFB_NOSYSTEMMEMORY  = DR_NOLOCALMEMORY,      /* There's not enough system memory. */
     DFB_NOSHAREDMEMORY  = DR_NOSHAREDMEMORY,     /* There's not enough shared memory. */
     DFB_LOCKED          = DR_LOCKED,             /* The resource is (already) locked. */
     DFB_BUFFEREMPTY     = DR_BUFFEREMPTY,        /* The buffer is empty. */
     DFB_FILENOTFOUND    = DR_FILENOTFOUND,       /* The specified file has not been found. */
     DFB_IO              = DR_IO,                 /* A general I/O error occured. */
     DFB_BUSY            = DR_BUSY,               /* The resource or device is busy. */
     DFB_NOIMPL          = DR_NOIMPL,             /* No implementation for this interface or content type has been found. */
     DFB_TIMEOUT         = DR_TIMEOUT,            /* The operation timed out. */
     DFB_THIZNULL        = DR_THIZNULL,           /* 'thiz' pointer is NULL. */
     DFB_IDNOTFOUND      = DR_IDNOTFOUND,         /* No resource has been found by the specified id. */
     DFB_DESTROYED       = DR_DESTROYED,          /* The underlying object (e.g. a window or surface) has been destroyed. */
     DFB_FUSION          = DR_FUSION,             /* Internal fusion error detected, most likely related to IPC resources. */
     DFB_BUFFERTOOLARGE  = DR_BUFFERTOOLARGE,     /* Buffer is too large. */
     DFB_INTERRUPTED     = DR_INTERRUPTED,        /* The operation has been interrupted. */
     DFB_NOCONTEXT       = DR_NOCONTEXT,          /* No context available. */
     DFB_TEMPUNAVAIL     = DR_TEMPUNAVAIL,        /* Temporarily unavailable. */
     DFB_LIMITEXCEEDED   = DR_LIMITEXCEEDED,      /* Attempted to exceed limit, i.e. any kind of maximum size, count etc. */
     DFB_NOSUCHMETHOD    = DR_NOSUCHMETHOD,       /* Requested method is not known, e.g. to remote site. */
     DFB_NOSUCHINSTANCE  = DR_NOSUCHINSTANCE,     /* Requested instance is not known, e.g. to remote site. */
     DFB_ITEMNOTFOUND    = DR_ITEMNOTFOUND,       /* No such item found. */
     DFB_VERSIONMISMATCH = DR_VERSIONMISMATCH,    /* Some versions didn't match. */
     DFB_EOF             = DR_EOF,                /* Reached end of file. */
     DFB_SUSPENDED       = DR_SUSPENDED,          /* The requested object is suspended. */
     DFB_INCOMPLETE      = DR_INCOMPLETE,         /* The operation has been executed, but not completely. */
     DFB_NOCORE          = DR_NOCORE,             /* Core part not available. */

     /*
      * DirectFB specific result codes starting at (after) this offset
      */
     DFB__RESULT_BASE    = D_RESULT_TYPE_CODE_BASE( 'D','F','B','1' ),

     DFB_NOVIDEOMEMORY,  /* There's not enough video memory. */
     DFB_MISSINGFONT,    /* No font has been set. */
     DFB_MISSINGIMAGE,   /* No image has been set. */

     DFB__RESULT_END
} DirectResult;

typedef DirectResult DFBResult;

/**********************************************************************************************************************/


typedef struct {
     int            magic;
     int            refs;

     unsigned int   base;

     const char   **result_strings;
     unsigned int   result_count;
} DirectResultType;


const char   DIRECT_API *DirectResultString( DirectResult result );

DirectResult DIRECT_API  DirectResultTypeRegister  ( DirectResultType *type );
DirectResult DIRECT_API  DirectResultTypeUnregister( DirectResultType *type );


/*
 * Example usage:
 *
 *   static const char *FooResult__strings[] = {
 *        "FooResult",        // result type name
 *
 *        "General foobar",   // FOO_GENERAL_FOOBAR
 *        "Too bar",          // FOO_TOO_BAR
 *   };
 *
 *
 * Corresponding example enumeration:
 *
 *   typedef enum {
 *        FOO__RESULT_BASE = D_RESULT_TYPE_BASE( 'F','o','o' ),
 *
 *        FOO_GENERAL_FOOBAR, // General foobar
 *        FOO_TOO_BAR,        // Too bar
 * 
 *        FOO__RESULT_END
 *   } FooResult;
 */


void __D_result_init( void );
void __D_result_deinit( void );

#endif

