QtAndroidExtras: modified to use the macro RQSTRING

Modified:
source/QtAndroidExtras/QAndroidJniObject.prg

/*

  Qt5xHb - bibliotecas de ligao entre Harbour/xHarbour e Qt Framework 5

  Copyright (C) 2012-2017 Marcos Antonio Gambeta <marcosgambeta@uol.com.br>

*/

#include "hbclass.ch"

CLASS QAndroidJniObject

   DATA pointer
   DATA class_flags INIT 0
   DATA self_destruction INIT .F.

   METHOD new1
   METHOD new2
   METHOD new
   METHOD delete
   METHOD callObjectMethod1
   METHOD callObjectMethod
   METHOD getObjectField
   METHOD toString
   METHOD isValid
   METHOD callStaticObjectMethod1
   METHOD callStaticObjectMethod
   METHOD getStaticObjectField1
   METHOD getStaticObjectField2
   METHOD getStaticObjectField
   METHOD fromString
   METHOD isClassAvailable

   METHOD newFrom
   METHOD newFromObject
   METHOD newFromPointer
   METHOD selfDestruction
   METHOD setSelfDestruction

   DESTRUCTOR destroyObject

END CLASS

PROCEDURE destroyObject () CLASS QAndroidJniObject
   IF ::self_destruction
      ::delete()
   ENDIF
RETURN

#pragma BEGINDUMP

#include <Qt>

#ifndef __XHARBOUR__
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
#include <QAndroidJniObject>
#endif
#endif

#include "qt5xhb_common.h"
#include "qt5xhb_macros.h"
#include "qt5xhb_utils.h"

#ifdef __XHARBOUR__
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
#include <QAndroidJniObject>
#endif
#endif

/*
QAndroidJniObject()
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEW1 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * o = new QAndroidJniObject ();
  _qt5xhb_storePointerAndFlag( o, false );
#endif
}

/*
QAndroidJniObject(const char *className)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEW2 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  const char * par1 = hb_parc(1);
  QAndroidJniObject * o = new QAndroidJniObject (  (const char *) par1 );
  _qt5xhb_storePointerAndFlag( o, false );
#endif
}

// TODO: revisar e implementar(?) construtores
//[1]QAndroidJniObject()
//[2]QAndroidJniObject(const char *className)
//[3]QAndroidJniObject(const char *className, const char *sig, ...)
//[4]QAndroidJniObject(jclass clazz)
//[5]QAndroidJniObject(jclass clazz, const char *sig, ...)
//[6]QAndroidJniObject(jobject obj)

HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEW )
{
  if( ISNUMPAR(0) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_NEW1 );
  }
  else if( ISNUMPAR(1) && ISCHAR(1) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_NEW2 );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_DELETE )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * obj = (QAndroidJniObject *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );

  if( obj )
  {
    delete obj;
    obj = NULL;
    PHB_ITEM self = hb_stackSelfItem();
    PHB_ITEM ptr = hb_itemPutPtr( NULL, NULL );
    hb_objSendMsg( self, "_pointer", 1, ptr );
    hb_itemRelease( ptr );
  }

  hb_itemReturn( hb_stackSelfItem() );
#endif
}

/*
QAndroidJniObject callObjectMethod(const char *methodName) const
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_CALLOBJECTMETHOD1 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * obj = (QAndroidJniObject *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    const char * par1 = hb_parc(1);
    QAndroidJniObject * ptr = new QAndroidJniObject( obj->callObjectMethod<const char*> (  (const char *) par1 ) );
    _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
  }
#endif
}

// TODO: revisar e implementar(?) caso [2]
//[1]QAndroidJniObject callObjectMethod(const char *methodName) const
//[2]QAndroidJniObject callObjectMethod(const char *methodName, const char *sig, ...) const

HB_FUNC_STATIC( QANDROIDJNIOBJECT_CALLOBJECTMETHOD )
{
  if( ISNUMPAR(1) && ISCHAR(1) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_CALLOBJECTMETHOD1 );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

/*
QAndroidJniObject getObjectField(const char *fieldName) const
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_GETOBJECTFIELD )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * obj = (QAndroidJniObject *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    if( ISCHAR(1) )
    {
      const char * par1 = hb_parc(1);
      QAndroidJniObject * ptr = new QAndroidJniObject( obj->getObjectField<const char*> (  (const char *) par1 ) );
      _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
    }
    else
    {
      hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
    }
  }
#endif
}

/*
QString toString() const
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_TOSTRING )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * obj = (QAndroidJniObject *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    hb_retc( RQSTRING( obj->toString () ) );
  }
#endif
}

/*
bool isValid() const
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_ISVALID )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * obj = (QAndroidJniObject *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    hb_retl( obj->isValid () );
  }
#endif
}

/*
static QAndroidJniObject callStaticObjectMethod(const char *className, const char *methodName)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_CALLSTATICOBJECTMETHOD1 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  const char * par1 = hb_parc(1);
  const char * par2 = hb_parc(2);
  QAndroidJniObject * ptr = new QAndroidJniObject( QAndroidJniObject::callStaticObjectMethod<const char*> (  (const char *) par1,  (const char *) par2 ) );
  _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
#endif
}

// TODO: revisar e implementar(?) metodos
//[1]static QAndroidJniObject callStaticObjectMethod(const char *className, const char *methodName)
//[2]static QAndroidJniObject callStaticObjectMethod(const char *className, const char *methodName, const char *sig, ...)
//[3]static QAndroidJniObject callStaticObjectMethod(jclass clazz, const char *methodName)
//[4]static QAndroidJniObject callStaticObjectMethod(jclass clazz, const char *methodName, const char *sig, ...)

HB_FUNC_STATIC( QANDROIDJNIOBJECT_CALLSTATICOBJECTMETHOD )
{
  if( ISNUMPAR(2) && ISCHAR(1) && ISCHAR(2) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_CALLSTATICOBJECTMETHOD1 );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

/*
static QAndroidJniObject getStaticObjectField(const char *className, const char *fieldName)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_GETSTATICOBJECTFIELD1 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  const char * par1 = hb_parc(1);
  const char * par2 = hb_parc(2);
  QAndroidJniObject * ptr = new QAndroidJniObject( QAndroidJniObject::getStaticObjectField<const char*> (  (const char *) par1,  (const char *) par2 ) );
  _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
#endif
}

/*
static QAndroidJniObject getStaticObjectField(const char *className, const char *fieldName, const char *sig)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_GETSTATICOBJECTFIELD2 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  const char * par1 = hb_parc(1);
  const char * par2 = hb_parc(2);
  const char * par3 = hb_parc(3);
  QAndroidJniObject * ptr = new QAndroidJniObject( QAndroidJniObject::getStaticObjectField<const char*> (  (const char *) par1,  (const char *) par2,  (const char *) par3 ) );
  _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
#endif
}

// TODO: revisar e implementar(?) metodos
//[1]static QAndroidJniObject getStaticObjectField(const char *className, const char *fieldName)
//[2]static QAndroidJniObject getStaticObjectField(const char *className, const char *fieldName, const char *sig)
//[3]static QAndroidJniObject getStaticObjectField(jclass clazz, const char *fieldName)
//[4]static QAndroidJniObject getStaticObjectField(jclass clazz, const char *fieldName, const char *sig)

HB_FUNC_STATIC( QANDROIDJNIOBJECT_GETSTATICOBJECTFIELD )
{
  if( ISNUMPAR(2) && ISCHAR(1) && ISCHAR(2) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_GETSTATICOBJECTFIELD1 );
  }
  else if( ISNUMPAR(3) && ISCHAR(1) && ISCHAR(2) && ISCHAR(3) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_GETSTATICOBJECTFIELD2 );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

/*
static QAndroidJniObject fromString(const QString &string)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_FROMSTRING )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  if( ISCHAR(1) )
  {
    QAndroidJniObject * ptr = new QAndroidJniObject( QAndroidJniObject::fromString ( PQSTRING(1) ) );
    _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
#endif
}

/*
static bool isClassAvailable(const char *className)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_ISCLASSAVAILABLE )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  if( ISCHAR(1) )
  {
    const char * par1 = hb_parc(1);
    hb_retl( QAndroidJniObject::isClassAvailable (  (const char *) par1 ) );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
#endif
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEWFROM )
{
  PHB_ITEM self = hb_stackSelfItem();

  if( hb_pcount() == 1 && ISOBJECT(1) )
  {
    PHB_ITEM ptr = hb_itemPutPtr( NULL, (void *) hb_itemGetPtr( hb_objSendMsg( hb_param(1, HB_IT_OBJECT ), "POINTER", 0 ) ) );
    hb_objSendMsg( self, "_pointer", 1, ptr );
    hb_itemRelease( ptr );
    PHB_ITEM des = hb_itemPutL( NULL, false );
    hb_objSendMsg( self, "_self_destruction", 1, des );
    hb_itemRelease( des );
  }
  else if( hb_pcount() == 1 && ISPOINTER(1) )
  {
    PHB_ITEM ptr = hb_itemPutPtr( NULL, (void *) hb_itemGetPtr( hb_param(1, HB_IT_POINTER ) ) );
    hb_objSendMsg( self, "_pointer", 1, ptr );
    hb_itemRelease( ptr );
    PHB_ITEM des = hb_itemPutL( NULL, false );
    hb_objSendMsg( self, "_self_destruction", 1, des );
    hb_itemRelease( des );
  }

  hb_itemReturn( self );
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEWFROMOBJECT )
{
  HB_FUNC_EXEC( QANDROIDJNIOBJECT_NEWFROM );
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEWFROMPOINTER )
{
  HB_FUNC_EXEC( QANDROIDJNIOBJECT_NEWFROM );
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_SELFDESTRUCTION )
{
  hb_retl( (bool) hb_itemGetL( hb_objSendMsg( hb_stackSelfItem(), "SELF_DESTRUCTION", 0 ) ) );
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_SETSELFDESTRUCTION )
{
  PHB_ITEM self = hb_stackSelfItem();

  if( hb_pcount() == 1 && ISLOG(1) )
  {
    PHB_ITEM des = hb_itemPutL( NULL, hb_parl(1) );
    hb_objSendMsg( self, "_self_destruction", 1, des );
    hb_itemRelease( des );
  }

  hb_itemReturn( self );
}

#pragma ENDDUMP

/*

  Qt5xHb - bibliotecas de ligao entre Harbour/xHarbour e Qt Framework 5

  Copyright (C) 2012-2017 Marcos Antonio Gambeta <marcosgambeta@uol.com.br>

*/

#include "hbclass.ch"

CLASS QAndroidJniObject

   DATA pointer
   DATA class_flags INIT 0
   DATA self_destruction INIT .F.

   METHOD new1
   METHOD new2
   METHOD new
   METHOD delete
   METHOD callObjectMethod1
   METHOD callObjectMethod
   METHOD getObjectField
   METHOD toString
   METHOD isValid
   METHOD callStaticObjectMethod1
   METHOD callStaticObjectMethod
   METHOD getStaticObjectField1
   METHOD getStaticObjectField2
   METHOD getStaticObjectField
   METHOD fromString
   METHOD isClassAvailable

   METHOD newFrom
   METHOD newFromObject
   METHOD newFromPointer
   METHOD selfDestruction
   METHOD setSelfDestruction

   DESTRUCTOR destroyObject

END CLASS

PROCEDURE destroyObject () CLASS QAndroidJniObject
   IF ::self_destruction
      ::delete()
   ENDIF
RETURN

#pragma BEGINDUMP

#include <Qt>

#ifndef __XHARBOUR__
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
#include <QAndroidJniObject>
#endif
#endif

#include "qt5xhb_common.h"
#include "qt5xhb_macros.h"
#include "qt5xhb_utils.h"

#ifdef __XHARBOUR__
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
#include <QAndroidJniObject>
#endif
#endif

/*
QAndroidJniObject()
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEW1 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * o = new QAndroidJniObject ();
  _qt5xhb_storePointerAndFlag( o, false );
#endif
}

/*
QAndroidJniObject(const char *className)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEW2 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  const char * par1 = hb_parc(1);
  QAndroidJniObject * o = new QAndroidJniObject (  (const char *) par1 );
  _qt5xhb_storePointerAndFlag( o, false );
#endif
}

// TODO: revisar e implementar(?) construtores
//[1]QAndroidJniObject()
//[2]QAndroidJniObject(const char *className)
//[3]QAndroidJniObject(const char *className, const char *sig, ...)
//[4]QAndroidJniObject(jclass clazz)
//[5]QAndroidJniObject(jclass clazz, const char *sig, ...)
//[6]QAndroidJniObject(jobject obj)

HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEW )
{
  if( ISNUMPAR(0) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_NEW1 );
  }
  else if( ISNUMPAR(1) && ISCHAR(1) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_NEW2 );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_DELETE )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * obj = (QAndroidJniObject *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );

  if( obj )
  {
    delete obj;
    obj = NULL;
    PHB_ITEM self = hb_stackSelfItem();
    PHB_ITEM ptr = hb_itemPutPtr( NULL, NULL );
    hb_objSendMsg( self, "_pointer", 1, ptr );
    hb_itemRelease( ptr );
  }

  hb_itemReturn( hb_stackSelfItem() );
#endif
}

/*
QAndroidJniObject callObjectMethod(const char *methodName) const
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_CALLOBJECTMETHOD1 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * obj = (QAndroidJniObject *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    const char * par1 = hb_parc(1);
    QAndroidJniObject * ptr = new QAndroidJniObject( obj->callObjectMethod<const char*> (  (const char *) par1 ) );
    _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
  }
#endif
}

// TODO: revisar e implementar(?) caso [2]
//[1]QAndroidJniObject callObjectMethod(const char *methodName) const
//[2]QAndroidJniObject callObjectMethod(const char *methodName, const char *sig, ...) const

HB_FUNC_STATIC( QANDROIDJNIOBJECT_CALLOBJECTMETHOD )
{
  if( ISNUMPAR(1) && ISCHAR(1) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_CALLOBJECTMETHOD1 );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

/*
QAndroidJniObject getObjectField(const char *fieldName) const
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_GETOBJECTFIELD )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * obj = (QAndroidJniObject *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    if( ISCHAR(1) )
    {
      const char * par1 = hb_parc(1);
      QAndroidJniObject * ptr = new QAndroidJniObject( obj->getObjectField<const char*> (  (const char *) par1 ) );
      _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
    }
    else
    {
      hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
    }
  }
#endif
}

/*
QString toString() const
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_TOSTRING )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * obj = (QAndroidJniObject *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    hb_retc( (const char *) obj->toString ().toLatin1().data() );
  }
#endif
}

/*
bool isValid() const
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_ISVALID )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  QAndroidJniObject * obj = (QAndroidJniObject *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    hb_retl( obj->isValid () );
  }
#endif
}

/*
static QAndroidJniObject callStaticObjectMethod(const char *className, const char *methodName)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_CALLSTATICOBJECTMETHOD1 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  const char * par1 = hb_parc(1);
  const char * par2 = hb_parc(2);
  QAndroidJniObject * ptr = new QAndroidJniObject( QAndroidJniObject::callStaticObjectMethod<const char*> (  (const char *) par1,  (const char *) par2 ) );
  _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
#endif
}

// TODO: revisar e implementar(?) metodos
//[1]static QAndroidJniObject callStaticObjectMethod(const char *className, const char *methodName)
//[2]static QAndroidJniObject callStaticObjectMethod(const char *className, const char *methodName, const char *sig, ...)
//[3]static QAndroidJniObject callStaticObjectMethod(jclass clazz, const char *methodName)
//[4]static QAndroidJniObject callStaticObjectMethod(jclass clazz, const char *methodName, const char *sig, ...)

HB_FUNC_STATIC( QANDROIDJNIOBJECT_CALLSTATICOBJECTMETHOD )
{
  if( ISNUMPAR(2) && ISCHAR(1) && ISCHAR(2) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_CALLSTATICOBJECTMETHOD1 );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

/*
static QAndroidJniObject getStaticObjectField(const char *className, const char *fieldName)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_GETSTATICOBJECTFIELD1 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  const char * par1 = hb_parc(1);
  const char * par2 = hb_parc(2);
  QAndroidJniObject * ptr = new QAndroidJniObject( QAndroidJniObject::getStaticObjectField<const char*> (  (const char *) par1,  (const char *) par2 ) );
  _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
#endif
}

/*
static QAndroidJniObject getStaticObjectField(const char *className, const char *fieldName, const char *sig)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_GETSTATICOBJECTFIELD2 )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  const char * par1 = hb_parc(1);
  const char * par2 = hb_parc(2);
  const char * par3 = hb_parc(3);
  QAndroidJniObject * ptr = new QAndroidJniObject( QAndroidJniObject::getStaticObjectField<const char*> (  (const char *) par1,  (const char *) par2,  (const char *) par3 ) );
  _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
#endif
}

// TODO: revisar e implementar(?) metodos
//[1]static QAndroidJniObject getStaticObjectField(const char *className, const char *fieldName)
//[2]static QAndroidJniObject getStaticObjectField(const char *className, const char *fieldName, const char *sig)
//[3]static QAndroidJniObject getStaticObjectField(jclass clazz, const char *fieldName)
//[4]static QAndroidJniObject getStaticObjectField(jclass clazz, const char *fieldName, const char *sig)

HB_FUNC_STATIC( QANDROIDJNIOBJECT_GETSTATICOBJECTFIELD )
{
  if( ISNUMPAR(2) && ISCHAR(1) && ISCHAR(2) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_GETSTATICOBJECTFIELD1 );
  }
  else if( ISNUMPAR(3) && ISCHAR(1) && ISCHAR(2) && ISCHAR(3) )
  {
    HB_FUNC_EXEC( QANDROIDJNIOBJECT_GETSTATICOBJECTFIELD2 );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

/*
static QAndroidJniObject fromString(const QString &string)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_FROMSTRING )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  if( ISCHAR(1) )
  {
    QAndroidJniObject * ptr = new QAndroidJniObject( QAndroidJniObject::fromString ( PQSTRING(1) ) );
    _qt5xhb_createReturnClass ( ptr, "QANDROIDJNIOBJECT" );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
#endif
}

/*
static bool isClassAvailable(const char *className)
*/
HB_FUNC_STATIC( QANDROIDJNIOBJECT_ISCLASSAVAILABLE )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
  if( ISCHAR(1) )
  {
    const char * par1 = hb_parc(1);
    hb_retl( QAndroidJniObject::isClassAvailable (  (const char *) par1 ) );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
#endif
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEWFROM )
{
  PHB_ITEM self = hb_stackSelfItem();

  if( hb_pcount() == 1 && ISOBJECT(1) )
  {
    PHB_ITEM ptr = hb_itemPutPtr( NULL, (void *) hb_itemGetPtr( hb_objSendMsg( hb_param(1, HB_IT_OBJECT ), "POINTER", 0 ) ) );
    hb_objSendMsg( self, "_pointer", 1, ptr );
    hb_itemRelease( ptr );
    PHB_ITEM des = hb_itemPutL( NULL, false );
    hb_objSendMsg( self, "_self_destruction", 1, des );
    hb_itemRelease( des );
  }
  else if( hb_pcount() == 1 && ISPOINTER(1) )
  {
    PHB_ITEM ptr = hb_itemPutPtr( NULL, (void *) hb_itemGetPtr( hb_param(1, HB_IT_POINTER ) ) );
    hb_objSendMsg( self, "_pointer", 1, ptr );
    hb_itemRelease( ptr );
    PHB_ITEM des = hb_itemPutL( NULL, false );
    hb_objSendMsg( self, "_self_destruction", 1, des );
    hb_itemRelease( des );
  }

  hb_itemReturn( self );
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEWFROMOBJECT )
{
  HB_FUNC_EXEC( QANDROIDJNIOBJECT_NEWFROM );
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_NEWFROMPOINTER )
{
  HB_FUNC_EXEC( QANDROIDJNIOBJECT_NEWFROM );
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_SELFDESTRUCTION )
{
  hb_retl( (bool) hb_itemGetL( hb_objSendMsg( hb_stackSelfItem(), "SELF_DESTRUCTION", 0 ) ) );
}

HB_FUNC_STATIC( QANDROIDJNIOBJECT_SETSELFDESTRUCTION )
{
  PHB_ITEM self = hb_stackSelfItem();

  if( hb_pcount() == 1 && ISLOG(1) )
  {
    PHB_ITEM des = hb_itemPutL( NULL, hb_parl(1) );
    hb_objSendMsg( self, "_self_destruction", 1, des );
    hb_itemRelease( des );
  }

  hb_itemReturn( self );
}

#pragma ENDDUMP


[ErrorDialog] Merged constructors. Disable Copy to Clipboard when not [STAThread]

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING System.Windows.Forms
USING System.Drawing

PROCEDURE InitializeErrorDialogHandler() _INIT1
   ShowErrorDialog_Handler := ErrorDialog

INTERNAL DEFINE IDABORT         := 3
INTERNAL DEFINE IDRETRY         := 4
INTERNAL DEFINE IDIGNORE        := 5
FUNCTION ErrorDialog( e AS Error ) AS INT
   LOCAL eResult AS DialogResult
   LOCAL nResult AS INT
   eResult := XSharp.ErrorDialog{ e }:ShowDialog()
   SWITCH eResult
   CASE DialogResult.Ignore
       nResult := IDIGNORE
   CASE DialogResult.Retry
       nResult := IDRETRY
   OTHERWISE
       nResult := IDABORT
   END SWITCH
   RETURN nResult

FUNCTION ErrorDialog( e AS Exception ) AS INT
   RETURN (INT) XSharp.ErrorDialog{ e }:ShowDialog()

FUNCTION ErrorDialog( txt AS STRING ) AS INT
   RETURN (INT) XSharp.ErrorDialog{ txt }:ShowDialog()

CLASS XSharp.ErrorDialog INHERIT System.Windows.Forms.Form

    EXPORT INSTANCE ErrorText AS System.Windows.Forms.TextBox
    EXPORT INSTANCE CloseButton AS System.Windows.Forms.Button
    EXPORT INSTANCE CopyButton AS System.Windows.Forms.Button
    EXPORT INSTANCE AbortButton AS System.Windows.Forms.Button
    EXPORT INSTANCE RetryButton AS System.Windows.Forms.Button
    EXPORT INSTANCE IgnoreButton AS System.Windows.Forms.Button

    PRIVATE lAbortRetryIgnoreMode := FALSE AS LOGIC

    CONSTRUCTOR( e AS Exception)
        SELF( e:ToString() )
        IF e IS Error VAR oError
            SELF:CloseButton:Hide()
            SELF:AbortButton:Show()
            SELF:RetryButton:Show()
            SELF:IgnoreButton:Show()
            SELF:RetryButton:Enabled := oError:CanRetry

            SELF:ControlBox := FALSE
            SELF:lAbortRetryIgnoreMode := TRUE
            SELF:Text := IIF(oError:Severity == ES_WARNING, "WARNING", "ERROR")

            LOCAL y := SELF:CloseButton:Top AS INT
            LOCAL w := SELF:CloseButton:Width AS INT
            SELF:AbortButton:Location  := Point{SELF:Width / 2 - (w * 2 + 30) , y}
            SELF:RetryButton:Location  := Point{SELF:Width / 2 - (w + 10) , y}
            SELF:IgnoreButton:Location := Point{SELF:Width / 2 + 10 , y}
            SELF:CopyButton:Location   := Point{SELF:Width / 2 + w + 30 , y}
      ENDIF
      VAR threadState := System.Threading.Thread.CurrentThread:GetApartmentState()
      IF threadState != System.Threading.ApartmentState.STA
         SELF:CopyButton:Enabled := FALSE
      ENDIF
      RETURN

    CONSTRUCTOR( txt AS STRING )
      SUPER()
      SELF:InitializeComponent()
      SELF:SetLanguageStrings()
      SELF:Text += System.Reflection.Assembly.GetEntryAssembly():Location
      ErrorText:Text := txt
      ErrorText:Select( 0, 0 )
      RETURN

    PRIVATE METHOD SetLanguageStrings() AS VOID
        SELF:Text               := __CavoStr(XSharp.VOErrors.ERRORDIALOG_TITLE)
        SELF:CloseButton:Text   := __CavoStr(XSharp.VOErrors.ERRORDIALOG_CLOSE)
        SELF:CopyButton:Text    := __CavoStr(XSharp.VOErrors.ERRORDIALOG_COPY)
        SELF:AbortButton:Text   := __CavoStr(XSharp.VOErrors.ERRORDIALOG_ABORT)
        SELF:RetryButton:Text   := __CavoStr(XSharp.VOErrors.ERRORDIALOG_RETRY)
        SELF:IgnoreButton:Text  := __CavoStr(XSharp.VOErrors.ERRORDIALOG_IGNORE)

    PRIVATE METHOD InitializeComponent() AS VOID
        SELF:ErrorText := System.Windows.Forms.TextBox{}
        SELF:CloseButton := System.Windows.Forms.Button{}
        SELF:CopyButton := System.Windows.Forms.Button{}
        SELF:AbortButton := System.Windows.Forms.Button{}
        SELF:RetryButton := System.Windows.Forms.Button{}
        SELF:IgnoreButton := System.Windows.Forms.Button{}
        SELF:SuspendLayout()
        //
        // ErrorText
        //
        SELF:ErrorText:Anchor := ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) ;
                    | System.Windows.Forms.AnchorStyles.Left) ;
                    | System.Windows.Forms.AnchorStyles.Right)))
        SELF:ErrorText:BackColor := System.Drawing.SystemColors.Window
        SELF:ErrorText:CausesValidation := FALSE
        SELF:ErrorText:Font := System.Drawing.Font{"Courier New", ((Single) 8)}
        SELF:ErrorText:Location := System.Drawing.Point{13, 12}
        SELF:ErrorText:Multiline := TRUE
        SELF:ErrorText:Name := "ErrorText"
        SELF:ErrorText:ReadOnly := TRUE
        SELF:ErrorText:ScrollBars := System.Windows.Forms.ScrollBars.Both
        SELF:ErrorText:Size := System.Drawing.Size{782, 279}
        SELF:ErrorText:TabIndex := 0
        SELF:ErrorText:WordWrap := FALSE
        //
        // CloseButton
        //
        SELF:CloseButton:Anchor := System.Windows.Forms.AnchorStyles.Bottom
        SELF:CloseButton:CausesValidation := FALSE
        SELF:CloseButton:DialogResult := System.Windows.Forms.DialogResult.OK
        SELF:CloseButton:Location := System.Drawing.Point{250, 297}
        SELF:CloseButton:Name := "CloseButton"
        SELF:CloseButton:Size := System.Drawing.Size{122, 23}
        SELF:CloseButton:TabIndex := 1
        SELF:CloseButton:Text := "Close"
        SELF:CloseButton:UseVisualStyleBackColor := TRUE
        //
        // CopyButton
        //
        SELF:CopyButton:Anchor := System.Windows.Forms.AnchorStyles.Bottom
        SELF:CopyButton:Location := System.Drawing.Point{410, 297}
        SELF:CopyButton:Name := "CopyButton"
        SELF:CopyButton:Size := System.Drawing.Size{122, 23}
        SELF:CopyButton:TabIndex := 2
        SELF:CopyButton:Text := "&Copy To Clipboard"
        SELF:CopyButton:UseVisualStyleBackColor := TRUE
        SELF:CopyButton:Click += System.EventHandler{ SELF, @CopyButton_Click() }
        //
        // AbortButton
        //
        SELF:AbortButton:Anchor := System.Windows.Forms.AnchorStyles.Bottom
        SELF:AbortButton:Location := System.Drawing.Point{510, 297}
        SELF:AbortButton:Name := "AbortButton"
        SELF:AbortButton:Size := System.Drawing.Size{122, 23}
        SELF:AbortButton:TabIndex := 2
        SELF:AbortButton:Text := "&Abort"
        SELF:AbortButton:UseVisualStyleBackColor := TRUE
        SELF:AbortButton:Visible := FALSE
        SELF:AbortButton:DialogResult := DialogResult.Abort
        //
        // RetryButton
        //
        SELF:RetryButton:Anchor := System.Windows.Forms.AnchorStyles.Bottom
        SELF:RetryButton:Location := System.Drawing.Point{510, 297}
        SELF:RetryButton:Name := "RetryButton"
        SELF:RetryButton:Size := System.Drawing.Size{122, 23}
        SELF:RetryButton:TabIndex := 2
        SELF:RetryButton:Text := "&Retry"
        SELF:RetryButton:UseVisualStyleBackColor := TRUE
        SELF:RetryButton:Visible := FALSE
        SELF:RetryButton:DialogResult := DialogResult.Retry
        //
        // IgnoreButton
        //
        SELF:IgnoreButton:Anchor := System.Windows.Forms.AnchorStyles.Bottom
        SELF:IgnoreButton:Location := System.Drawing.Point{510, 297}
        SELF:IgnoreButton:Name := "IgnoreButton"
        SELF:IgnoreButton:Size := System.Drawing.Size{122, 23}
        SELF:IgnoreButton:TabIndex := 2
        SELF:IgnoreButton:Text := "&Ignore"
        SELF:IgnoreButton:UseVisualStyleBackColor := TRUE
        SELF:IgnoreButton:Visible := FALSE
        SELF:IgnoreButton:DialogResult := DialogResult.Ignore
        //
        // ErrorDialog
        //
        SELF:AutoScaleDimensions := System.Drawing.SizeF{((Single) 6), ((Single) 13)}
        SELF:AutoScaleMode := System.Windows.Forms.AutoScaleMode.Font
        SELF:ClientSize := System.Drawing.Size{807, 332}
        SELF:Controls:Add(SELF:AbortButton)
        SELF:Controls:Add(SELF:RetryButton)
        SELF:Controls:Add(SELF:IgnoreButton)
        SELF:Controls:Add(SELF:CopyButton)
        SELF:Controls:Add(SELF:CloseButton)
        SELF:Controls:Add(SELF:ErrorText)
        SELF:Name := "ErrorDialog"
        SELF:Text := "Application Error - "
        SELF:ResumeLayout(FALSE)
        SELF:PerformLayout()

    PROTECTED VIRTUAL METHOD OnClosing( e AS System.ComponentModel.CancelEventArgs ) AS VOID
       IF SELF:lAbortRetryIgnoreMode .AND. SELF:DialogResult == DialogResult.Cancel // Alt+F4
           e:Cancel := TRUE
       ENDIF
       RETURN
    PRIVATE METHOD CopyButton_Click( sender AS OBJECT, e AS System.EventArgs ) AS VOID
       System.Windows.Forms.Clipboard.SetDataObject( ErrorText:Text, TRUE )
       RETURN

END CLASS

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING System.Windows.Forms
USING System.Drawing

PROCEDURE InitializeErrorDialogHandler() _INIT1
   ShowErrorDialog_Handler := ErrorDialog

INTERNAL DEFINE IDABORT         := 3
INTERNAL DEFINE IDRETRY         := 4
INTERNAL DEFINE IDIGNORE        := 5
FUNCTION ErrorDialog( e AS Error ) AS INT
   LOCAL eResult AS DialogResult
   LOCAL nResult AS INT
   eResult := XSharp.ErrorDialog{ e }:ShowDialog()
   SWITCH eResult
   CASE DialogResult.Ignore
       nResult := IDIGNORE
   CASE DialogResult.Retry
       nResult := IDRETRY
   OTHERWISE
       nResult := IDABORT
   END SWITCH
   RETURN nResult

FUNCTION ErrorDialog( e AS Exception ) AS INT
   RETURN (INT) XSharp.ErrorDialog{ e }:ShowDialog()

FUNCTION ErrorDialog( txt AS STRING ) AS INT
   RETURN (INT) XSharp.ErrorDialog{ txt }:ShowDialog()

CLASS XSharp.ErrorDialog INHERIT System.Windows.Forms.Form

    EXPORT INSTANCE ErrorText AS System.Windows.Forms.TextBox
    EXPORT INSTANCE CloseButton AS System.Windows.Forms.Button
    EXPORT INSTANCE CopyButton AS System.Windows.Forms.Button
    EXPORT INSTANCE AbortButton AS System.Windows.Forms.Button
    EXPORT INSTANCE RetryButton AS System.Windows.Forms.Button
    EXPORT INSTANCE IgnoreButton AS System.Windows.Forms.Button

    PRIVATE lAbortRetryIgnoreMode := FALSE AS LOGIC

    CONSTRUCTOR( oError AS XSharp.Error )
        SELF( oError:ToString() )

        SELF:CloseButton:Hide()
        SELF:AbortButton:Show()
        SELF:RetryButton:Show()
        SELF:IgnoreButton:Show()
        SELF:RetryButton:Enabled := oError:CanRetry

        SELF:ControlBox := FALSE
        SELF:lAbortRetryIgnoreMode := TRUE
        SELF:Text := IIF(oError:Severity == ES_WARNING, "WARNING", "ERROR")

        LOCAL y := SELF:CloseButton:Top AS INT
        LOCAL w := SELF:CloseButton:Width AS INT
        SELF:AbortButton:Location  := Point{SELF:Width / 2 - (w * 2 + 30) , y}
        SELF:RetryButton:Location  := Point{SELF:Width / 2 - (w + 10) , y}
        SELF:IgnoreButton:Location := Point{SELF:Width / 2 + 10 , y}
        SELF:CopyButton:Location   := Point{SELF:Width / 2 + w + 30 , y}
      RETURN

    CONSTRUCTOR( e AS Exception )
        SELF(e:ToString())
      RETURN

    CONSTRUCTOR( txt AS STRING )
      SUPER()
      SELF:InitializeComponent()
      SELF:SetLanguageStrings()
      SELF:Text += System.Reflection.Assembly.GetEntryAssembly():Location
      ErrorText:Text := txt
      ErrorText:Select( 0, 0 )
      RETURN

    PRIVATE METHOD SetLanguageStrings() AS VOID
        SELF:Text               := __CavoStr(XSharp.VOErrors.ERRORDIALOG_TITLE)
        SELF:CloseButton:Text   := __CavoStr(XSharp.VOErrors.ERRORDIALOG_CLOSE)
        SELF:CopyButton:Text    := __CavoStr(XSharp.VOErrors.ERRORDIALOG_COPY)
        SELF:AbortButton:Text   := __CavoStr(XSharp.VOErrors.ERRORDIALOG_ABORT)
        SELF:RetryButton:Text   := __CavoStr(XSharp.VOErrors.ERRORDIALOG_RETRY)
        SELF:IgnoreButton:Text  := __CavoStr(XSharp.VOErrors.ERRORDIALOG_IGNORE)

    PRIVATE METHOD InitializeComponent() AS VOID
        SELF:ErrorText := System.Windows.Forms.TextBox{}
        SELF:CloseButton := System.Windows.Forms.Button{}
        SELF:CopyButton := System.Windows.Forms.Button{}
        SELF:AbortButton := System.Windows.Forms.Button{}
        SELF:RetryButton := System.Windows.Forms.Button{}
        SELF:IgnoreButton := System.Windows.Forms.Button{}
        SELF:SuspendLayout()
        //
        // ErrorText
        //
        SELF:ErrorText:Anchor := ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) ;
                    | System.Windows.Forms.AnchorStyles.Left) ;
                    | System.Windows.Forms.AnchorStyles.Right)))
        SELF:ErrorText:BackColor := System.Drawing.SystemColors.Window
        SELF:ErrorText:CausesValidation := FALSE
        SELF:ErrorText:Font := System.Drawing.Font{"Courier New", ((Single) 8)}
        SELF:ErrorText:Location := System.Drawing.Point{13, 12}
        SELF:ErrorText:Multiline := TRUE
        SELF:ErrorText:Name := "ErrorText"
        SELF:ErrorText:ReadOnly := TRUE
        SELF:ErrorText:ScrollBars := System.Windows.Forms.ScrollBars.Both
        SELF:ErrorText:Size := System.Drawing.Size{782, 279}
        SELF:ErrorText:TabIndex := 0
        SELF:ErrorText:WordWrap := FALSE
        //
        // CloseButton
        //
        SELF:CloseButton:Anchor := System.Windows.Forms.AnchorStyles.Bottom
        SELF:CloseButton:CausesValidation := FALSE
        SELF:CloseButton:DialogResult := System.Windows.Forms.DialogResult.OK
        SELF:CloseButton:Location := System.Drawing.Point{250, 297}
        SELF:CloseButton:Name := "CloseButton"
        SELF:CloseButton:Size := System.Drawing.Size{122, 23}
        SELF:CloseButton:TabIndex := 1
        SELF:CloseButton:Text := "Close"
        SELF:CloseButton:UseVisualStyleBackColor := TRUE
        //
        // CopyButton
        //
        SELF:CopyButton:Anchor := System.Windows.Forms.AnchorStyles.Bottom
        SELF:CopyButton:Location := System.Drawing.Point{410, 297}
        SELF:CopyButton:Name := "CopyButton"
        SELF:CopyButton:Size := System.Drawing.Size{122, 23}
        SELF:CopyButton:TabIndex := 2
        SELF:CopyButton:Text := "&Copy To Clipboard"
        SELF:CopyButton:UseVisualStyleBackColor := TRUE
        SELF:CopyButton:Click += System.EventHandler{ SELF, @CopyButton_Click() }
        //
        // AbortButton
        //
        SELF:AbortButton:Anchor := System.Windows.Forms.AnchorStyles.Bottom
        SELF:AbortButton:Location := System.Drawing.Point{510, 297}
        SELF:AbortButton:Name := "AbortButton"
        SELF:AbortButton:Size := System.Drawing.Size{122, 23}
        SELF:AbortButton:TabIndex := 2
        SELF:AbortButton:Text := "&Abort"
        SELF:AbortButton:UseVisualStyleBackColor := TRUE
        SELF:AbortButton:Visible := FALSE
        SELF:AbortButton:DialogResult := DialogResult.Abort
        //
        // RetryButton
        //
        SELF:RetryButton:Anchor := System.Windows.Forms.AnchorStyles.Bottom
        SELF:RetryButton:Location := System.Drawing.Point{510, 297}
        SELF:RetryButton:Name := "RetryButton"
        SELF:RetryButton:Size := System.Drawing.Size{122, 23}
        SELF:RetryButton:TabIndex := 2
        SELF:RetryButton:Text := "&Retry"
        SELF:RetryButton:UseVisualStyleBackColor := TRUE
        SELF:RetryButton:Visible := FALSE
        SELF:RetryButton:DialogResult := DialogResult.Retry
        //
        // IgnoreButton
        //
        SELF:IgnoreButton:Anchor := System.Windows.Forms.AnchorStyles.Bottom
        SELF:IgnoreButton:Location := System.Drawing.Point{510, 297}
        SELF:IgnoreButton:Name := "IgnoreButton"
        SELF:IgnoreButton:Size := System.Drawing.Size{122, 23}
        SELF:IgnoreButton:TabIndex := 2
        SELF:IgnoreButton:Text := "&Ignore"
        SELF:IgnoreButton:UseVisualStyleBackColor := TRUE
        SELF:IgnoreButton:Visible := FALSE
        SELF:IgnoreButton:DialogResult := DialogResult.Ignore
        //
        // ErrorDialog
        //
        SELF:AutoScaleDimensions := System.Drawing.SizeF{((Single) 6), ((Single) 13)}
        SELF:AutoScaleMode := System.Windows.Forms.AutoScaleMode.Font
        SELF:ClientSize := System.Drawing.Size{807, 332}
        SELF:Controls:Add(SELF:AbortButton)
        SELF:Controls:Add(SELF:RetryButton)
        SELF:Controls:Add(SELF:IgnoreButton)
        SELF:Controls:Add(SELF:CopyButton)
        SELF:Controls:Add(SELF:CloseButton)
        SELF:Controls:Add(SELF:ErrorText)
        SELF:Name := "ErrorDialog"
        SELF:Text := "Application Error - "
        SELF:ResumeLayout(FALSE)
        SELF:PerformLayout()

    PROTECTED VIRTUAL METHOD OnClosing( e AS System.ComponentModel.CancelEventArgs ) AS VOID
       IF SELF:lAbortRetryIgnoreMode .AND. SELF:DialogResult == DialogResult.Cancel // Alt+F4
           e:Cancel := TRUE
       ENDIF
       RETURN
    PRIVATE METHOD CopyButton_Click( sender AS OBJECT, e AS System.EventArgs ) AS VOID
       System.Windows.Forms.Clipboard.SetDataObject( ErrorText:Text, TRUE )
       RETURN

END CLASS


[Runtime] Reverted commit https://github.com/X-Sharp/XSharpPublic/commit/a880403ee10fdd294ae1b0197bb6aeced1da9248 for https://github.com/X-Sharp/XSharpPublic/issues/356 Workaround is no longer needed after compiler fix in handling of "-DWORD"

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System
USING System.Runtime.Serialization
USING System.Globalization
USING System.Runtime.InteropServices
USING System.Runtime.CompilerServices
USING XSharp
USING System.Diagnostics
BEGIN NAMESPACE XSharp
	/// Internal type that implements the VO Compatible DATE type

	/// This type has many operators and implicit converters that normally are never directly called from user code.
	/// It holds year, month, day in 32 bits. For date calculations it uses the System.DateTime calculation logic.
	/// There are implicit converters between Date and DateTime.
	///
	/// <seealso cref="T:XSharp.IDate"/>
	/// <seealso cref="T:XSharp.RDD.DbDate"/>
	[DebuggerDisplay("{ToString(),nq}", Type := "DATE" )];
	[DebuggerTypeProxy(TYPEOF(DateDebugView))];
	[StructLayout(LayoutKind.Explicit,Pack := 1)];
	PUBLIC STRUCTURE __Date IMPLEMENTS System.IComparable, ;
		System.IFormattable, ;
		System.IConvertible, ;
		IDate, ;
		IComparable<__Date>, ;
		IEquatable<__Date>
		// This structure uses an explicit layout to map
		// year, month and date into 32 bits
		// the _ymd field is for convenience, so we can do a single numeric comparison
		// to determine equality or relative comparisons in stead of doing 3 comparisons
		// for date calculation we use the Value PROPERTY which returns a System.DateTime type
		// Note that the Vulcan type uses a datetime which takes 8 bytes. We only use 4 bytes
		#region fields
			[FieldOffset(00)] PRIVATE _ymd   AS System.Int32
			[FieldOffset(00)] PRIVATE _year  AS System.UInt16
			[FieldOffset(02)] PRIVATE _month AS System.Byte
			[FieldOffset(03)] PRIVATE _day   AS System.Byte
		#endregion

		#region STATIC fields
			/// <exclude />
			STATIC INITONLY PUBLIC  _NULL_DATE AS DATE
			/// <exclude />
			CONST  CLIPPER_MIN_DATE := 2415386U AS DWORD	// 1901-01-01
			/// <exclude />
			CONST  CLIPPER_MAX_DATE := 4606840U AS DWORD	// 7900-12-31
			/// <exclude />
			STATIC INITONLY _dtCalc AS DateTime

		#endregion

		#region datetime conversions
            /// Return DATE value as DateTime.
			PUBLIC PROPERTY Value AS System.DateTime
				GET
					IF (_ymd == 0)
						RETURN System.DateTime.MinValue
					ENDIF
					RETURN System.DateTime{_year, _month, _day}
				END GET
				SET
				    IF value != DateTime.MinValue
					    _year  := (WORD) value:Year
					    _month := (BYTE) value:Month
					    _day   := (BYTE) value:Day
				    ELSE
					    _ymd := 0
				    ENDIF
				END SET
			END PROPERTY
		#endregion

		#region constructors
			STATIC CONSTRUCTOR()
				_NULL_DATE  := DATE{}
				_dtCalc     := DateTime{1901,1,1}
				RETURN
			/// Construct a date from a DateTime value.
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(dt AS System.DateTime)
                _ymd := _year := _month := _day := 0
                IF dt != DateTime.MinValue
				    _year  := (WORD) dt:Year
				    _month := (BYTE) dt:Month
				    _day   := (BYTE) dt:Day
                ELSE
                    _ymd := 0
                ENDIF
				RETURN

			/// Construct a date from another IDate type.
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(d AS IDate)
                _ymd := 0
				_year  := (WORD) d:Year
				_month := (BYTE) d:Month
				_day   := (BYTE) d:Day
				RETURN

			/// Construct a date from a number of Ticks.
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(ticks AS INT64)
				SELF(System.DateTime{ticks})
				RETURN

			/// Construct a date from a string. This assumes the string is in current Date format
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(strDate AS STRING)
				LOCAL dValue := CToD(strDate) AS DATE
                _year := _month := _day := 0
				_ymd := dValue:_ymd

			/// Construct a date from a string using the specified Date Format.
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(strDate AS STRING, strFormat AS STRING)
				LOCAL dValue := CToD(strDate,strFormat) AS DATE
                _year := _month := _day := 0
				_ymd := dValue:_ymd

			/// Construct a date from year, month, day
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(year AS INT, month AS INT, day AS INT)
                _ymd := _year := _month := _day := 0
                IF year != 0 .AND. month != 0 .AND. day != 0
				    TRY
					    // this may throw an exception when the combination is not valid
                        IF (year == 1 .AND. month == 1 .AND. day == 1)
                            // this is DateTime.Mindate, but a valid date in VO
					        _year  := 1
					        _month := 1
					        _day   := 1
                        ELSE
  				            VAR dt := System.DateTime{year, month, day}
					        _year  := (WORD) dt:Year
					        _month := (BYTE) dt:Month
					        _day   := (BYTE) dt:Day
                        ENDIF
				    CATCH
        				_ymd := 0 // null_date
					    NOP
                     END TRY
                ELSE
				    _ymd := 0 // null_date
                ENDIF
				RETURN

			/// Construct a date from year, month, day
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(year AS DWORD, month AS DWORD, day AS DWORD)
				// Chain to Int constructor
				SELF( (INT) year, (INT) month, (INT) day)
				RETURN

		#endregion

		#region methods
			/// <inheritdoc />
			METHOD CompareTo(o AS OBJECT) AS LONG
				VAR rhs := (DATE)o
				RETURN _ymd:CompareTo(rhs:_ymd)

			/// <inheritdoc />
			METHOD CompareTo(rhs AS DATE) AS LONG
				RETURN _ymd:CompareTo(rhs:_ymd)

			/// <inheritdoc />
			OVERRIDE METHOD GetHashCode() AS LONG
				RETURN _ymd:GetHashCode()

			/// <inheritdoc />
			METHOD GetTypeCode() AS System.TypeCode
				RETURN TypeCode.DateTime
		#endregion
		#region Operators
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR ++(lhs AS DATE) AS DATE
				RETURN lhs:Add(1)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR +(lhs AS DATE, days AS USUAL) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR +(lhs AS DATE, days AS REAL8) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR +(lhs AS DATE, days AS LONG) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR +(lhs AS DATE, days AS INT64) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR +(lhs AS DATE, ts AS System.TimeSpan) AS DATE
				RETURN lhs:Add(ts)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR +(lhs AS DATE, days AS DWORD) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR +(lhs AS DATE, days AS UINT64) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR --(lhs AS DATE) AS DATE
				RETURN lhs:Subtract(1)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, rhs AS DATE) AS LONG
				RETURN lhs:Subtract(rhs)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS USUAL) AS USUAL
				RETURN lhs:Subtract(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS REAL8) AS DATE
				RETURN lhs:Subtract(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS LONG) AS DATE
				RETURN lhs:Subtract(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS INT64) AS DATE
				RETURN lhs:Subtract(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, ts AS System.TimeSpan) AS DATE
				RETURN lhs:Subtract(ts)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS DWORD) AS DATE
				RETURN lhs:Subtract(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS UINT64) AS DATE
				RETURN lhs:Subtract(days)

		#endregion
		#region Equality Operators

			/// <inheritdoc />
			METHOD Equals(lhs AS DATE) AS LOGIC
				RETURN _ymd == lhs:_ymd

			/// <inheritdoc />
			OVERRIDE METHOD Equals(o AS OBJECT) AS LOGIC
				IF o != NULL
					IF o:GetType() == TYPEOF(DATE)
						RETURN SELF:Equals(  (DATE) o)
					ELSEIF o:GetType() == TYPEOF(System.DateTime)
						RETURN SELF:Equals( DATE{ (System.DateTime) o})
					ENDIF
				ENDIF
			RETURN FALSE

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR ==(lhs AS DATE, rhs AS DATE) AS LOGIC
				RETURN (lhs:_ymd == rhs:_ymd)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR !=(lhs AS DATE, rhs AS DATE) AS LOGIC
				RETURN (lhs:_ymd != rhs:_ymd)

		#endregion
		#region Implicit and Explicit converters

			/// <include file="RTComments.xml" path="Comments/Converter/*" />
			STATIC OPERATOR EXPLICIT(dvalue AS DATE) AS DWORD
				// convert to julian date like vo
				// # of days since 1-1-1901 + 2415386
				LOCAL nDays AS DWORD
				nDays := (DWORD) (dvalue:Value - _dtCalc):Days + CLIPPER_MIN_DATE
				RETURN nDays

			/// <include file="RTComments.xml" path="Comments/Converter/*" />
			STATIC OPERATOR EXPLICIT(dValue AS DATE) AS INT
				LOCAL nDays AS LONG
				nDays := (INT) ((dValue:Value - _dtCalc):Days + CLIPPER_MIN_DATE)
				RETURN nDays

			/// <include file="RTComments.xml" path="Comments/Converter/*" />
			STATIC OPERATOR EXPLICIT(dw AS DWORD ) AS DATE
				// convert julian date to our date
				LOCAL result := _NULL_DATE AS DATE
				IF dw >= CLIPPER_MIN_DATE .AND. dw <= CLIPPER_MAX_DATE
					LOCAL dt AS DateTime
					dt := _dtCalc:AddDays ( (INT) dw -CLIPPER_MIN_DATE)
					result := DATE{dt}
				ENDIF
				RETURN result

			/// <include file="RTComments.xml" path="Comments/Converter/*" />
			STATIC OPERATOR EXPLICIT(i AS INT) AS DATE
				LOCAL result := _NULL_DATE AS DATE
				IF i >= CLIPPER_MIN_DATE .AND. i <= CLIPPER_MAX_DATE
					LOCAL dt AS DateTime
					dt := _dtCalc:AddDays ( i - CLIPPER_MIN_DATE)
					result := DATE{dt}
				ENDIF
				RETURN result

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR IMPLICIT(v AS System.DateTime) AS DATE
				RETURN DATE{v}

			/// <exclude />
			METHOD ToDateTime() AS System.DateTime
				RETURN SELF:Value

			/// <exclude />
			METHOD FromDateTime(dtvalue AS System.DateTime) AS DATE
				RETURN DATE{dtvalue}

		#endregion
		#region Comparison Operators
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR >(lhs AS DATE, rhs AS DATE) AS LOGIC
				// note: cannot use _ymd for > comparison because that would depend
				//       on the processor layout
				IF lhs:_ymd == rhs:_ymd
					RETURN FALSE
				ELSEIF lhs:_year > rhs:_year
					RETURN TRUE
				ELSEIF lhs:_year == rhs:_year
					IF lhs:_month > rhs:_month
						RETURN TRUE
					ELSEIF lhs:_month == rhs:_month .AND. lhs:_day > rhs:_day
						RETURN TRUE
					ENDIF
				ENDIF
				RETURN FALSE

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR >=(lhs AS DATE, rhs AS DATE) AS LOGIC
				// note: cannot use _ymd for > comparison because that would depend
				//       on the processor layout
				IF lhs:_ymd == rhs:_ymd
					RETURN TRUE
				ELSEIF lhs:_year > rhs:_year
					RETURN TRUE
				ELSEIF lhs:_year == rhs:_year
					IF lhs:_month > rhs:_month
						RETURN TRUE
					ELSEIF lhs:_month == rhs:_month .AND. lhs:_day >= rhs:_day
						RETURN TRUE
					ENDIF
				ENDIF
				RETURN FALSE

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR IMPLICIT(v AS DATE) AS System.DateTime
				RETURN v:Value

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR <(lhs AS DATE, rhs AS DATE) AS LOGIC
				// note: cannot use _ymd for < comparison because that would depend
				//       on the processor layout
				IF lhs:_ymd == rhs:_ymd
					RETURN FALSE
				ELSEIF lhs:_year < rhs:_year
					RETURN TRUE
				ELSEIF lhs:_year == rhs:_year
					IF lhs:_month < rhs:_month
						RETURN TRUE
					ELSEIF lhs:_month == rhs:_month .AND. lhs:_day < rhs:_day
						RETURN TRUE
					ENDIF
				ENDIF
				RETURN FALSE

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR <=(lhs AS DATE, rhs AS DATE) AS LOGIC
				// note: cannot use _ymd for < comparison because that would depend
				//       on the processor layout
				IF lhs:_ymd == rhs:_ymd
					RETURN TRUE
				ELSEIF lhs:_year < rhs:_year
					RETURN TRUE
				ELSEIF lhs:_year == rhs:_year
					IF lhs:_month < rhs:_month
						RETURN TRUE
					ELSEIF lhs:_month == rhs:_month .AND. lhs:_day <= rhs:_day
						RETURN TRUE
					ENDIF
				ENDIF
				RETURN FALSE
		#endregion

		#region ADD and Subtract Methods
			/// <exclude />
			METHOD Add(days AS USUAL) AS DATE
				IF days:IsInteger
					RETURN SELF:Add( (INT64) days)
				ELSEIF days:IsNumeric
					 RETURN SELF:Add( (REAL8) days)
				ELSE
					THROW Error.ArgumentError(__ENTITY__,NAMEOF(days),1, "Incompatible argument for Date:Add()",{days})
				ENDIF
			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(days AS REAL8) AS DATE
				VAR res := SELF:Value:AddDays(days)
				RETURN DATE{res}
			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(days AS LONG) AS DATE
				VAR res := SELF:Value:AddDays(days)
				RETURN DATE{res}
			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(days AS INT64) AS DATE
				VAR res := SELF:Value:AddDays(days)
				RETURN DATE{res}

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(span AS System.TimeSpan) AS DATE
				VAR res := SELF:Value:Add(span)
				RETURN DATE{res}

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(days AS DWORD) AS DATE
				VAR res := SELF:Value:AddDays(days)
				RETURN DATE{res}

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(days AS UINT64) AS DATE
				VAR res := SELF:Value:AddDays(days)
				RETURN DATE{res}

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(lhs AS DATE) AS LONG
				LOCAL span AS System.TimeSpan
				span := (System.TimeSpan)(SELF:Value - lhs:Value)
				RETURN span:Days

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS USUAL) AS USUAL
				IF days:IsInteger
					RETURN SELF:Subtract( -(INT64) days)
				ELSEIF days:IsNumeric
					 RETURN SELF:Subtract( -(REAL8) days)
				ELSEIF days:IsDate
					 RETURN SELF:Subtract( (DATE) days)
				ELSE
					THROW Error.ArgumentError(__ENTITY__,NAMEOF(days), 1, "Incompatible argument for Date:Subtract()", {days})
				ENDIF

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS REAL8) AS DATE
				RETURN SELF:Add(-days)

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS LONG) AS DATE
				RETURN SELF:Add(-days)

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS INT64) AS DATE
				RETURN SELF:Add(-days)

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(ts AS System.TimeSpan) AS DATE
				RETURN SELF:Add(-ts)

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS DWORD) AS DATE
				RETURN SELF:Add(-days)

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS UINT64) AS DATE
				RETURN SELF:Add(-(INT64)days)
		#endregion

		#region IConvertable
			// forward most methods to the DateTime class so there will
			// be a proper (localized) error message
			/// <inheritdoc />
			METHOD IConvertible.ToBoolean(provider AS System.IFormatProvider) AS LOGIC
				RETURN ((IConvertible)SELF:Value):ToBoolean(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToByte(provider AS System.IFormatProvider) AS BYTE
				RETURN ((IConvertible)SELF:Value):ToByte(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToChar(provider AS System.IFormatProvider) AS CHAR
				RETURN ((IConvertible)SELF:Value):ToChar(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToDateTime(provider AS System.IFormatProvider) AS System.DateTime
				RETURN SELF:Value

			/// <inheritdoc />
			METHOD IConvertible.ToDecimal(provider AS System.IFormatProvider) AS Decimal
				RETURN ((IConvertible)SELF:Value):ToDecimal(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToDouble(provider AS System.IFormatProvider) AS REAL8
				RETURN ((IConvertible)SELF:Value):ToDouble(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToInt16(provider AS System.IFormatProvider) AS SHORT
				RETURN ((IConvertible)SELF:Value):ToInt16(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToInt32(provider AS System.IFormatProvider) AS LONG
				RETURN ((IConvertible)SELF:Value):ToInt32(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToInt64(provider AS System.IFormatProvider) AS INT64
				RETURN ((IConvertible)SELF:Value):ToInt64(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToSByte(provider AS System.IFormatProvider) AS SByte
				RETURN ((IConvertible)SELF:Value):ToSByte(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToSingle(provider AS System.IFormatProvider) AS REAL4
				RETURN ((IConvertible)SELF:Value):ToSingle(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToType(conversionType AS System.Type, provider AS System.IFormatProvider) AS OBJECT
				IF conversionType == TYPEOF(DATE)
					RETURN SELF
				ELSEIF conversionType == TYPEOF(System.DateTime)
					RETURN SELF:Value
				ENDIF
				RETURN ((IConvertible)SELF:Value):ToType(conversionType, provider)

			/// <inheritdoc />
			METHOD IConvertible.ToUInt16(provider AS System.IFormatProvider) AS WORD
				RETURN ((IConvertible)SELF:Value):ToUInt16(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToUInt32(provider AS System.IFormatProvider) AS DWORD
				RETURN ((IConvertible)SELF:Value):ToUInt32(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToUInt64(provider AS System.IFormatProvider) AS UINT64
				RETURN ((IConvertible)SELF:Value):ToUInt64(provider)
		#endregion

		#region ToString()
			// Use DateTime ToString() methods as helpers
			/// <inheritdoc />
			OVERRIDE METHOD ToString() AS STRING
				IF (_ymd == 0)
					RETURN RuntimeState.NullDateString
				ENDIF
			RETURN DToC(SELF)
			/// <inheritdoc />
			METHOD ToString(provider AS System.IFormatProvider) AS STRING
				IF (_ymd == 0)
					RETURN RuntimeState.NullDateString
				ENDIF
				RETURN SELF:Value:ToString(provider)
			/// <inheritdoc cref="M:System.DateTime.ToString(System.String)"/>
			METHOD ToString(s AS STRING) AS STRING
				IF (_ymd == 0)
					RETURN RuntimeState.NullDateString
				ENDIF
				RETURN SELF:Value:ToString(s)
			/// <inheritdoc />
			METHOD ToString(s AS STRING, fp AS System.IFormatProvider) AS STRING
				IF (_ymd == 0)
					RETURN RuntimeState.NullDateString
				ENDIF
				IF (s == NULL)
					s := XSharp.RuntimeState.GetValue<STRING>(Set.DateFormatNet)
				ENDIF
				RETURN SELF:Value:ToString(s, fp)
		#endregion
		#region properties

			/// <inheritdoc />
			PROPERTY IsEmpty AS LOGIC
				GET
					RETURN _ymd == 0
				END GET
			END PROPERTY
			/// <inheritdoc />
			PROPERTY Month	AS INT GET _month
			/// <inheritdoc />
			PROPERTY Year	AS INT GET _year
			/// <inheritdoc />
			PROPERTY Day	AS INT GET _day
			// Next properties for easy access in right type
			INTERNAL PROPERTY DYear		AS DWORD GET _year
			INTERNAL PROPERTY DMonth	AS DWORD GET _month
			INTERNAL PROPERTY DDay		AS DWORD GET _day

			INTERNAL CLASS DateDebugView
				PRIVATE _value AS DATE
				PUBLIC CONSTRUCTOR (d AS DATE)
					_value := d

				PUBLIC PROPERTY Year	AS INT GET _value:Year
				PUBLIC PROPERTY Month	AS INT GET _value:Month
				PUBLIC PROPERTY Day		AS INT GET _value:Day

			END CLASS

		#endregion

		#region STATIC Properties

			/// <exclude />
			STATIC METHOD NullDate AS DATE
				RETURN  _NULL_DATE

		#endregion
	END STRUCTURE
END NAMESPACE

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System
USING System.Runtime.Serialization
USING System.Globalization
USING System.Runtime.InteropServices
USING System.Runtime.CompilerServices
USING XSharp
USING System.Diagnostics
BEGIN NAMESPACE XSharp
	/// Internal type that implements the VO Compatible DATE type

	/// This type has many operators and implicit converters that normally are never directly called from user code.
	/// It holds year, month, day in 32 bits. For date calculations it uses the System.DateTime calculation logic.
	/// There are implicit converters between Date and DateTime.
	///
	/// <seealso cref="T:XSharp.IDate"/>
	/// <seealso cref="T:XSharp.RDD.DbDate"/>
	[DebuggerDisplay("{ToString(),nq}", Type := "DATE" )];
	[DebuggerTypeProxy(TYPEOF(DateDebugView))];
	[StructLayout(LayoutKind.Explicit,Pack := 1)];
	PUBLIC STRUCTURE __Date IMPLEMENTS System.IComparable, ;
		System.IFormattable, ;
		System.IConvertible, ;
		IDate, ;
		IComparable<__Date>, ;
		IEquatable<__Date>
		// This structure uses an explicit layout to map
		// year, month and date into 32 bits
		// the _ymd field is for convenience, so we can do a single numeric comparison
		// to determine equality or relative comparisons in stead of doing 3 comparisons
		// for date calculation we use the Value PROPERTY which returns a System.DateTime type
		// Note that the Vulcan type uses a datetime which takes 8 bytes. We only use 4 bytes
		#region fields
			[FieldOffset(00)] PRIVATE _ymd   AS System.Int32
			[FieldOffset(00)] PRIVATE _year  AS System.UInt16
			[FieldOffset(02)] PRIVATE _month AS System.Byte
			[FieldOffset(03)] PRIVATE _day   AS System.Byte
		#endregion

		#region STATIC fields
			/// <exclude />
			STATIC INITONLY PUBLIC  _NULL_DATE AS DATE
			/// <exclude />
			CONST  CLIPPER_MIN_DATE := 2415386U AS DWORD	// 1901-01-01
			/// <exclude />
			CONST  CLIPPER_MAX_DATE := 4606840U AS DWORD	// 7900-12-31
			/// <exclude />
			STATIC INITONLY _dtCalc AS DateTime

		#endregion

		#region datetime conversions
            /// Return DATE value as DateTime.
			PUBLIC PROPERTY Value AS System.DateTime
				GET
					IF (_ymd == 0)
						RETURN System.DateTime.MinValue
					ENDIF
					RETURN System.DateTime{_year, _month, _day}
				END GET
				SET
				    IF value != DateTime.MinValue
					    _year  := (WORD) value:Year
					    _month := (BYTE) value:Month
					    _day   := (BYTE) value:Day
				    ELSE
					    _ymd := 0
				    ENDIF
				END SET
			END PROPERTY
		#endregion

		#region constructors
			STATIC CONSTRUCTOR()
				_NULL_DATE  := DATE{}
				_dtCalc     := DateTime{1901,1,1}
				RETURN
			/// Construct a date from a DateTime value.
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(dt AS System.DateTime)
                _ymd := _year := _month := _day := 0
                IF dt != DateTime.MinValue
				    _year  := (WORD) dt:Year
				    _month := (BYTE) dt:Month
				    _day   := (BYTE) dt:Day
                ELSE
                    _ymd := 0
                ENDIF
				RETURN

			/// Construct a date from another IDate type.
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(d AS IDate)
                _ymd := 0
				_year  := (WORD) d:Year
				_month := (BYTE) d:Month
				_day   := (BYTE) d:Day
				RETURN

			/// Construct a date from a number of Ticks.
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(ticks AS INT64)
				SELF(System.DateTime{ticks})
				RETURN

			/// Construct a date from a string. This assumes the string is in current Date format
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(strDate AS STRING)
				LOCAL dValue := CToD(strDate) AS DATE
                _year := _month := _day := 0
				_ymd := dValue:_ymd

			/// Construct a date from a string using the specified Date Format.
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(strDate AS STRING, strFormat AS STRING)
				LOCAL dValue := CToD(strDate,strFormat) AS DATE
                _year := _month := _day := 0
				_ymd := dValue:_ymd

			/// Construct a date from year, month, day
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(year AS INT, month AS INT, day AS INT)
                _ymd := _year := _month := _day := 0
                IF year != 0 .AND. month != 0 .AND. day != 0
				    TRY
					    // this may throw an exception when the combination is not valid
                        IF (year == 1 .AND. month == 1 .AND. day == 1)
                            // this is DateTime.Mindate, but a valid date in VO
					        _year  := 1
					        _month := 1
					        _day   := 1
                        ELSE
  				            VAR dt := System.DateTime{year, month, day}
					        _year  := (WORD) dt:Year
					        _month := (BYTE) dt:Month
					        _day   := (BYTE) dt:Day
                        ENDIF
				    CATCH
        				_ymd := 0 // null_date
					    NOP
                     END TRY
                ELSE
				    _ymd := 0 // null_date
                ENDIF
				RETURN

			/// Construct a date from year, month, day
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			CONSTRUCTOR(year AS DWORD, month AS DWORD, day AS DWORD)
				// Chain to Int constructor
				SELF( (INT) year, (INT) month, (INT) day)
				RETURN

		#endregion

		#region methods
			/// <inheritdoc />
			METHOD CompareTo(o AS OBJECT) AS LONG
				VAR rhs := (DATE)o
				RETURN _ymd:CompareTo(rhs:_ymd)

			/// <inheritdoc />
			METHOD CompareTo(rhs AS DATE) AS LONG
				RETURN _ymd:CompareTo(rhs:_ymd)

			/// <inheritdoc />
			OVERRIDE METHOD GetHashCode() AS LONG
				RETURN _ymd:GetHashCode()

			/// <inheritdoc />
			METHOD GetTypeCode() AS System.TypeCode
				RETURN TypeCode.DateTime
		#endregion
		#region Operators
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR ++(lhs AS DATE) AS DATE
				RETURN lhs:Add(1)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR +(lhs AS DATE, days AS USUAL) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR +(lhs AS DATE, days AS REAL8) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR +(lhs AS DATE, days AS LONG) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR +(lhs AS DATE, days AS INT64) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR +(lhs AS DATE, ts AS System.TimeSpan) AS DATE
				RETURN lhs:Add(ts)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR +(lhs AS DATE, days AS DWORD) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR +(lhs AS DATE, days AS UINT64) AS DATE
				RETURN lhs:Add(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR --(lhs AS DATE) AS DATE
				RETURN lhs:Subtract(1)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, rhs AS DATE) AS LONG
				RETURN lhs:Subtract(rhs)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS USUAL) AS USUAL
				RETURN lhs:Subtract(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS REAL8) AS DATE
				RETURN lhs:Subtract(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS LONG) AS DATE
				RETURN lhs:Subtract(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS INT64) AS DATE
				RETURN lhs:Subtract(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, ts AS System.TimeSpan) AS DATE
				RETURN lhs:Subtract(ts)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS DWORD) AS DATE
				RETURN lhs:Subtract(days)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			STATIC OPERATOR -(lhs AS DATE, days AS UINT64) AS DATE
				RETURN lhs:Subtract(days)

		#endregion
		#region Equality Operators

			/// <inheritdoc />
			METHOD Equals(lhs AS DATE) AS LOGIC
				RETURN _ymd == lhs:_ymd

			/// <inheritdoc />
			OVERRIDE METHOD Equals(o AS OBJECT) AS LOGIC
				IF o != NULL
					IF o:GetType() == TYPEOF(DATE)
						RETURN SELF:Equals(  (DATE) o)
					ELSEIF o:GetType() == TYPEOF(System.DateTime)
						RETURN SELF:Equals( DATE{ (System.DateTime) o})
					ENDIF
				ENDIF
			RETURN FALSE

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR ==(lhs AS DATE, rhs AS DATE) AS LOGIC
				RETURN (lhs:_ymd == rhs:_ymd)

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR !=(lhs AS DATE, rhs AS DATE) AS LOGIC
				RETURN (lhs:_ymd != rhs:_ymd)

		#endregion
		#region Implicit and Explicit converters

			/// <include file="RTComments.xml" path="Comments/Converter/*" />
			STATIC OPERATOR EXPLICIT(dvalue AS DATE) AS DWORD
				// convert to julian date like vo
				// # of days since 1-1-1901 + 2415386
				LOCAL nDays AS DWORD
				nDays := (DWORD) (dvalue:Value - _dtCalc):Days + CLIPPER_MIN_DATE
				RETURN nDays

			/// <include file="RTComments.xml" path="Comments/Converter/*" />
			STATIC OPERATOR EXPLICIT(dValue AS DATE) AS INT
				LOCAL nDays AS LONG
				nDays := (INT) ((dValue:Value - _dtCalc):Days + CLIPPER_MIN_DATE)
				RETURN nDays

			/// <include file="RTComments.xml" path="Comments/Converter/*" />
			STATIC OPERATOR EXPLICIT(dw AS DWORD ) AS DATE
				// convert julian date to our date
				LOCAL result := _NULL_DATE AS DATE
				IF dw >= CLIPPER_MIN_DATE .AND. dw <= CLIPPER_MAX_DATE
					LOCAL dt AS DateTime
					dt := _dtCalc:AddDays ( (INT) dw -CLIPPER_MIN_DATE)
					result := DATE{dt}
				ENDIF
				RETURN result

			/// <include file="RTComments.xml" path="Comments/Converter/*" />
			STATIC OPERATOR EXPLICIT(i AS INT) AS DATE
				LOCAL result := _NULL_DATE AS DATE
				IF i >= CLIPPER_MIN_DATE .AND. i <= CLIPPER_MAX_DATE
					LOCAL dt AS DateTime
					dt := _dtCalc:AddDays ( i - CLIPPER_MIN_DATE)
					result := DATE{dt}
				ENDIF
				RETURN result

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR IMPLICIT(v AS System.DateTime) AS DATE
				RETURN DATE{v}

			/// <exclude />
			METHOD ToDateTime() AS System.DateTime
				RETURN SELF:Value

			/// <exclude />
			METHOD FromDateTime(dtvalue AS System.DateTime) AS DATE
				RETURN DATE{dtvalue}

		#endregion
		#region Comparison Operators
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR >(lhs AS DATE, rhs AS DATE) AS LOGIC
				// note: cannot use _ymd for > comparison because that would depend
				//       on the processor layout
				IF lhs:_ymd == rhs:_ymd
					RETURN FALSE
				ELSEIF lhs:_year > rhs:_year
					RETURN TRUE
				ELSEIF lhs:_year == rhs:_year
					IF lhs:_month > rhs:_month
						RETURN TRUE
					ELSEIF lhs:_month == rhs:_month .AND. lhs:_day > rhs:_day
						RETURN TRUE
					ENDIF
				ENDIF
				RETURN FALSE

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR >=(lhs AS DATE, rhs AS DATE) AS LOGIC
				// note: cannot use _ymd for > comparison because that would depend
				//       on the processor layout
				IF lhs:_ymd == rhs:_ymd
					RETURN TRUE
				ELSEIF lhs:_year > rhs:_year
					RETURN TRUE
				ELSEIF lhs:_year == rhs:_year
					IF lhs:_month > rhs:_month
						RETURN TRUE
					ELSEIF lhs:_month == rhs:_month .AND. lhs:_day >= rhs:_day
						RETURN TRUE
					ENDIF
				ENDIF
				RETURN FALSE

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR IMPLICIT(v AS DATE) AS System.DateTime
				RETURN v:Value

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR <(lhs AS DATE, rhs AS DATE) AS LOGIC
				// note: cannot use _ymd for < comparison because that would depend
				//       on the processor layout
				IF lhs:_ymd == rhs:_ymd
					RETURN FALSE
				ELSEIF lhs:_year < rhs:_year
					RETURN TRUE
				ELSEIF lhs:_year == rhs:_year
					IF lhs:_month < rhs:_month
						RETURN TRUE
					ELSEIF lhs:_month == rhs:_month .AND. lhs:_day < rhs:_day
						RETURN TRUE
					ENDIF
				ENDIF
				RETURN FALSE

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			STATIC OPERATOR <=(lhs AS DATE, rhs AS DATE) AS LOGIC
				// note: cannot use _ymd for < comparison because that would depend
				//       on the processor layout
				IF lhs:_ymd == rhs:_ymd
					RETURN TRUE
				ELSEIF lhs:_year < rhs:_year
					RETURN TRUE
				ELSEIF lhs:_year == rhs:_year
					IF lhs:_month < rhs:_month
						RETURN TRUE
					ELSEIF lhs:_month == rhs:_month .AND. lhs:_day <= rhs:_day
						RETURN TRUE
					ENDIF
				ENDIF
				RETURN FALSE
		#endregion

		#region ADD and Subtract Methods
			/// <exclude />
			METHOD Add(days AS USUAL) AS DATE
				IF days:IsInteger
					RETURN SELF:Add( (INT64) days)
				ELSEIF days:IsNumeric
					 RETURN SELF:Add( (REAL8) days)
				ELSE
					THROW Error.ArgumentError(__ENTITY__,NAMEOF(days),1, "Incompatible argument for Date:Add()",{days})
				ENDIF
			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(days AS REAL8) AS DATE
				VAR res := SELF:Value:AddDays(days)
				RETURN DATE{res}
			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(days AS LONG) AS DATE
				VAR res := SELF:Value:AddDays(days)
				RETURN DATE{res}
			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(days AS INT64) AS DATE
				VAR res := SELF:Value:AddDays(days)
				RETURN DATE{res}

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(span AS System.TimeSpan) AS DATE
				VAR res := SELF:Value:Add(span)
				RETURN DATE{res}

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(days AS DWORD) AS DATE
				VAR res := SELF:Value:AddDays(days)
				RETURN DATE{res}

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Add(days AS UINT64) AS DATE
				VAR res := SELF:Value:AddDays(days)
				RETURN DATE{res}

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(lhs AS DATE) AS LONG
				LOCAL span AS System.TimeSpan
				span := (System.TimeSpan)(SELF:Value - lhs:Value)
				RETURN span:Days

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS USUAL) AS USUAL
				IF days:IsInteger
					RETURN SELF:Subtract( -(INT64) days)
				ELSEIF days:IsNumeric
					 RETURN SELF:Subtract( -(REAL8) days)
				ELSEIF days:IsDate
					 RETURN SELF:Subtract( (DATE) days)
				ELSE
					THROW Error.ArgumentError(__ENTITY__,NAMEOF(days), 1, "Incompatible argument for Date:Subtract()", {days})
				ENDIF

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS REAL8) AS DATE
				RETURN SELF:Add(-days)

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS LONG) AS DATE
				RETURN SELF:Add(-days)

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS INT64) AS DATE
				RETURN SELF:Add(-days)

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(ts AS System.TimeSpan) AS DATE
				RETURN SELF:Add(-ts)

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS DWORD) AS DATE
				LOCAL i64days AS INT64
				i64days := days
				i64days := - i64days
				RETURN SELF:Add(i64days)

			/// <exclude />
            [MethodImpl(MethodImplOptions.AggressiveInlining)];
			METHOD Subtract(days AS UINT64) AS DATE
				RETURN SELF:Add(-(INT64)days)
		#endregion

		#region IConvertable
			// forward most methods to the DateTime class so there will
			// be a proper (localized) error message
			/// <inheritdoc />
			METHOD IConvertible.ToBoolean(provider AS System.IFormatProvider) AS LOGIC
				RETURN ((IConvertible)SELF:Value):ToBoolean(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToByte(provider AS System.IFormatProvider) AS BYTE
				RETURN ((IConvertible)SELF:Value):ToByte(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToChar(provider AS System.IFormatProvider) AS CHAR
				RETURN ((IConvertible)SELF:Value):ToChar(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToDateTime(provider AS System.IFormatProvider) AS System.DateTime
				RETURN SELF:Value

			/// <inheritdoc />
			METHOD IConvertible.ToDecimal(provider AS System.IFormatProvider) AS Decimal
				RETURN ((IConvertible)SELF:Value):ToDecimal(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToDouble(provider AS System.IFormatProvider) AS REAL8
				RETURN ((IConvertible)SELF:Value):ToDouble(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToInt16(provider AS System.IFormatProvider) AS SHORT
				RETURN ((IConvertible)SELF:Value):ToInt16(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToInt32(provider AS System.IFormatProvider) AS LONG
				RETURN ((IConvertible)SELF:Value):ToInt32(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToInt64(provider AS System.IFormatProvider) AS INT64
				RETURN ((IConvertible)SELF:Value):ToInt64(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToSByte(provider AS System.IFormatProvider) AS SByte
				RETURN ((IConvertible)SELF:Value):ToSByte(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToSingle(provider AS System.IFormatProvider) AS REAL4
				RETURN ((IConvertible)SELF:Value):ToSingle(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToType(conversionType AS System.Type, provider AS System.IFormatProvider) AS OBJECT
				IF conversionType == TYPEOF(DATE)
					RETURN SELF
				ELSEIF conversionType == TYPEOF(System.DateTime)
					RETURN SELF:Value
				ENDIF
				RETURN ((IConvertible)SELF:Value):ToType(conversionType, provider)

			/// <inheritdoc />
			METHOD IConvertible.ToUInt16(provider AS System.IFormatProvider) AS WORD
				RETURN ((IConvertible)SELF:Value):ToUInt16(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToUInt32(provider AS System.IFormatProvider) AS DWORD
				RETURN ((IConvertible)SELF:Value):ToUInt32(provider)

			/// <inheritdoc />
			METHOD IConvertible.ToUInt64(provider AS System.IFormatProvider) AS UINT64
				RETURN ((IConvertible)SELF:Value):ToUInt64(provider)
		#endregion

		#region ToString()
			// Use DateTime ToString() methods as helpers
			/// <inheritdoc />
			OVERRIDE METHOD ToString() AS STRING
				IF (_ymd == 0)
					RETURN RuntimeState.NullDateString
				ENDIF
			RETURN DToC(SELF)
			/// <inheritdoc />
			METHOD ToString(provider AS System.IFormatProvider) AS STRING
				IF (_ymd == 0)
					RETURN RuntimeState.NullDateString
				ENDIF
				RETURN SELF:Value:ToString(provider)
			/// <inheritdoc cref="M:System.DateTime.ToString(System.String)"/>
			METHOD ToString(s AS STRING) AS STRING
				IF (_ymd == 0)
					RETURN RuntimeState.NullDateString
				ENDIF
				RETURN SELF:Value:ToString(s)
			/// <inheritdoc />
			METHOD ToString(s AS STRING, fp AS System.IFormatProvider) AS STRING
				IF (_ymd == 0)
					RETURN RuntimeState.NullDateString
				ENDIF
				IF (s == NULL)
					s := XSharp.RuntimeState.GetValue<STRING>(Set.DateFormatNet)
				ENDIF
				RETURN SELF:Value:ToString(s, fp)
		#endregion
		#region properties

			/// <inheritdoc />
			PROPERTY IsEmpty AS LOGIC
				GET
					RETURN _ymd == 0
				END GET
			END PROPERTY
			/// <inheritdoc />
			PROPERTY Month	AS INT GET _month
			/// <inheritdoc />
			PROPERTY Year	AS INT GET _year
			/// <inheritdoc />
			PROPERTY Day	AS INT GET _day
			// Next properties for easy access in right type
			INTERNAL PROPERTY DYear		AS DWORD GET _year
			INTERNAL PROPERTY DMonth	AS DWORD GET _month
			INTERNAL PROPERTY DDay		AS DWORD GET _day

			INTERNAL CLASS DateDebugView
				PRIVATE _value AS DATE
				PUBLIC CONSTRUCTOR (d AS DATE)
					_value := d

				PUBLIC PROPERTY Year	AS INT GET _value:Year
				PUBLIC PROPERTY Month	AS INT GET _value:Month
				PUBLIC PROPERTY Day		AS INT GET _value:Day

			END CLASS

		#endregion

		#region STATIC Properties

			/// <exclude />
			STATIC METHOD NullDate AS DATE
				RETURN  _NULL_DATE

		#endregion
	END STRUCTURE
END NAMESPACE