/*
** This file is part of awisetoolbox.
** Copyright (C) 2008-2017 by Alan Wise (awisesoftware@gmail.com)
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


/**
*** \file versionstring.h
*** \brief Manipulate and compare version numbers.
*** \details Breaks version text (x.y.z) into a format that can be compared
***   using normal comparison operators.
**/


#ifndef   VERSIONSTRING_H
#define   VERSIONSTRING_H


/****
*****
***** INCLUDES
*****
****/

#include  "errorcode.h"


/****
*****
***** DEFINES
*****
****/

/**
*** \brief Maximum number of digits.
*** \details Maximum number of digits (between periods) in the version string.
**/
#define   DIGITS_MAXIMUMCOUNT   (8)   /* Should be more than enough. */


/****
*****
***** DATA TYPES
*****
****/

/**
*** \brief Version string.
*** \details A version broken down into the numbers between each period.
**/
typedef struct structVERSIONSTRING
{
  /**
  *** \brief A list of numbers.
  *** \details The list of numbers between each period.
  **/
  short Digits[DIGITS_MAXIMUMCOUNT];
} VERSIONSTRING_T;

#if       defined(__cplusplus)
extern "C" {
#endif    /* defined(__cplusplus) */

/* These prototypes must be placed here because the class definition uses
    uses them. */

/**
*** \brief Compares two version strings.
*** \details Compares two version strings.
*** \param pLHS Pointer to version string #1.
*** \param pRHS Pointer to version string #2.
*** \retval <0 Version string #1 is less than version string #2.
*** \retval 0 Version string #1 is equal to version string #2.
*** \retval >0 Version string #1 is greater than version string #2.
**/
int VersionString_Compare(
    VERSIONSTRING_T const *pLHS,VERSIONSTRING_T const *pRHS);
/**
*** \brief Initializes a version string.
*** \details Initializes a version string.
*** \param pVersionString Pointer to storage for the version string.
*** \param pString Pointer to version text.
*** \retval >0 Success.
*** \retval <0 Failure.
**/
ERRORCODE_T VersionString_Set(
    VERSIONSTRING_T *pVersionString,char const *pString);

#if       defined(__cplusplus)
}
#endif    /* defined(__cplusplus) */

#if       defined(__cplusplus)
class VERSIONSTRING_C
{
  public:
    /**
    *** \brief Constructor.
    *** \details Constructor.
    **/
    VERSIONSTRING_C(void)
    {
      VersionString_Set(&m_VersionString,""); return;
    };
    /**
    *** \brief Constructor.
    *** \details Constructor.
    *** \param pString Pointer to version text.
    **/
    VERSIONSTRING_C(char const *pString)
    {
      VersionString_Set(&m_VersionString,pString); return;
    };
    /**
    *** \brief Destructor.
    *** \details Destructor.
    **/
    ~VERSIONSTRING_C(void)
    {
      return;
    };

    /**
    *** \brief Less than operator.
    *** \details Less than operator.
    *** \param RHS Version string #2.
    *** retval true Version string is less than version string #2.
    *** retval false Version string is equal to or greater than version string #2.
    **/
    bool operator<(const VERSIONSTRING_C &RHS) const
    {
      return(VersionString_Compare(
          &this->m_VersionString,&RHS.m_VersionString)<0);
    };
    /**
    *** \brief Less than or equal to operator.
    *** \details Less than or equal to operator.
    *** \param RHS Version string #2.
    *** retval true Version string is less than or equal to version string #2.
    *** retval false Version string is greater than version string #2.
    **/
    bool operator<=(const VERSIONSTRING_C &RHS) const
    {
      return(VersionString_Compare(
          &this->m_VersionString,&RHS.m_VersionString)<=0);
    };
    /**
    *** \brief Equal to operator.
    *** \details Equal to operator.
    *** \param RHS Version string #2.
    *** retval true Version string is equal to version string #2.
    *** retval false Version string is not equal to version string #2.
    **/
    bool operator==(const VERSIONSTRING_C &RHS) const
    {
      return(VersionString_Compare(
          &this->m_VersionString,&RHS.m_VersionString)==0);
    };
    /**
    *** \brief No equal to operator.
    *** \details No equal to operator.
    *** \param RHS Version string #2.
    *** retval true Version string is not equal to version string #2.
    *** retval false Version string is equal to version string #2.
    **/
    bool operator!=(const VERSIONSTRING_C &RHS) const
    {
      return(!(VersionString_Compare(
          &this->m_VersionString,&RHS.m_VersionString)==0));
    };
    /**
    *** \brief Equal to or greater than operator.
    *** \details Equal to or greater than operator.
    *** \param RHS Version string #2.
    *** retval true Version string is equal to to greater than version string #2.
    *** retval false Version string is less than version string #2.
    **/
    bool operator>=(const VERSIONSTRING_C &RHS) const
    {
      return(VersionString_Compare(
          &this->m_VersionString,&RHS.m_VersionString)>=0);
    };
    /**
    *** \brief Greater than operator.
    *** \details Greater operator.
    *** \param RHS Version string #2.
    *** retval true Version string is greater than version string #2.
    *** retval false Version string is less than or equal to version string #2.
    **/
    bool operator>(const VERSIONSTRING_C &RHS) const
    {
      return(VersionString_Compare(
          &this->m_VersionString,&RHS.m_VersionString)>0);
    };
    /**
    *** \brief Sets the version string.
    *** \details Sets the version string.
    *** \param pString Pointer to the version text.
    **/
    void Set(char const *pString)
    {
      VersionString_Set(&m_VersionString,pString);
      return;
    }

  private:
    /**
    *** \brief Version string.
    *** \details Version string.
    **/
    VERSIONSTRING_T m_VersionString;
};
#endif    /* defined(__cplusplus) */


/****
*****
***** DATA
*****
****/


/****
*****
***** VARIABLES
*****
****/


/****
*****
***** PROTOTYPES
*****
****/

#if       defined(__cplusplus)
extern "C" {
#endif    /* defined(__cplusplus) */

#if       defined(__cplusplus)
}
#endif    /* defined(__cplusplus) */


#endif    /* VERSIONSTRING_H */
