/*****************************************************************************
* Copyright (c) 1990-98 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/


// Version.cpp: implementation of the CVersion class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Version.h"

//////////////////////////////////////////////////////////////////////
// For lack of a better place
//////////////////////////////////////////////////////////////////////

static int SplitString(CString strToSplit, TCHAR const chSplitOn, CStringArray & astrSplit)
{
   int cSplits = 0;

   TRACE("Split string %s on %c\n", strToSplit, chSplitOn);

   try
   {
      astrSplit.RemoveAll();

      if (strToSplit.Find(chSplitOn) >= 0)
      {
         CString strSplitOn;
         strSplitOn.Format(TEXT("%c"), chSplitOn);

         CString strSplit;
         do
         {
            strSplit = strToSplit.SpanExcluding(strSplitOn);
            TRACE("Split %s\n", strSplit);

            astrSplit.Add(strSplit);
            cSplits++;

            strToSplit = strToSplit.Right(strToSplit.GetLength() - strSplit.GetLength() - 1);
         }
         while (!strToSplit.IsEmpty());
      }
   }
   catch (CAffirmException ae)
   {
   }

   Affirm(cSplits == astrSplit.GetSize());
   return cSplits;
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

#define VER_MAJ_MIN_BLD_FMT   TEXT("%d.%d.%d")
#define VER_DELIMITER         TEXT('.')

enum
{
   VER_POS_MAJOR,
   VER_POS_MINOR,
   VER_COUNT_MINOR,
   VER_POS_BUILDNUMBER = VER_COUNT_MINOR,
   VER_COUNT_BUILDNUMBER,
};


CVersion::CVersion()
{
   m_nMajor   = 0;
   m_nMinor   = 0;
   m_nBuild   = 0;
   m_strVersion.Empty();
}

CVersion::CVersion(int const nMajor, int const nMinor, int const nBuild)
{
   m_nMajor   = nMajor;
   m_nMinor   = nMinor;
   m_nBuild   = nBuild;
   m_strVersion.Format(VER_MAJ_MIN_BLD_FMT, nMajor, nMinor, nBuild);
}

CVersion::CVersion(CString const & str)
{
   *this = str;
}

CVersion::~CVersion()
{
}

//////////////////////////////////////////////////////////////////////
// Operations
//////////////////////////////////////////////////////////////////////

const CVersion& CVersion::operator=(CString const & str)
{
   Affirm(!str.IsEmpty());

   // reset
   m_nMajor   = 0;
   m_nMinor   = 0;
   m_nBuild   = 0;
   m_strVersion.Empty();

   // split string passed in
   CStringArray astrVers;
   int cVers = SplitString(str, VER_DELIMITER, astrVers);
   Affirm(cVers >= 0);

   if (cVers == 0)
   {
      m_nMajor = atoi(str);
   }
   else
   {
                                          m_nMajor = atoi(astrVers[VER_POS_MAJOR]);
      if (cVers >= VER_COUNT_MINOR)       m_nMinor = atoi(astrVers[VER_POS_MINOR]);
      if (cVers >= VER_COUNT_BUILDNUMBER) m_nBuild = atoi(astrVers[VER_POS_BUILDNUMBER]);
   }
   m_strVersion = str;

   return *this;
}

const CVersion& CVersion::operator=(TCHAR const * const psz)
{
   CString str = psz;
   *this = str;
   return *this;
}

int CVersion::Compare(CVersion const & verCompareTo) const
{
   int nComparison = m_nMajor - verCompareTo.m_nMajor;

   if (nComparison == 0)
   {
      nComparison = m_nMinor - verCompareTo.m_nMinor;

      if (nComparison == 0)
      {
         nComparison = m_nBuild - verCompareTo.m_nBuild;
      }
   }

   return nComparison;
}
