//
//  Copyright © 2002, RESON Inc. All Rights Reserved.
//
//  No part of this file may be reproduced or transmitted in any form or by
//  any means, electronic or mechanical, including photocopy, recording, or
//  information storage or retrieval system, without permission in writing
//  from RESON Inc.
//
//  Filename:   SonarConfiguration.h
//
//  Project:    6046
//
//  Author(s):  W. Arcus
//
//  Purpose:    
//
//  Notes:      
//

#if !defined(AFX_SONARCONFIGURATION_H__3501271A_E7A2_4D53_959A_55710D5F8225__INCLUDED_)
#define AFX_SONARCONFIGURATION_H__3501271A_E7A2_4D53_959A_55710D5F8225__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

template <typename tParams>
class CSonarConfiguration : public tParams
{
public:

    ///////////////
    // Definitions.

    typedef enum tagEACCESS
    {
        accessWrite     = 0,
        accessRead
    }
    EACCESS;

    ///////////////
    // Services.

                            CSonarConfiguration         (   void );
    virtual                ~CSonarConfiguration         (   void );

    bool                    Open                        (   const int               &riSensorIndex,
                                                            const EACCESS           &reAccess );

    bool                    Close                       (   void );

    bool                    IsOpen                      (   void )  const;

    bool                    Write                       (   void );
    bool                    Read                        (   void );

                            operator const tParams *    (   void )  const;

    bool                    SetDefault                  (   void );

private:


    ///////////////
    // Services.

    FILE                   *m_fpFile;

    ///////////////
    // Services.

    CString                 GetPath                     (   void )  const;
    size_t                  Size                        (   void )  const;

};

template <typename tParams>
CSonarConfiguration<tParams>::CSonarConfiguration( void )
                             :tParams()
{
    m_fpFile = NULL;
}

template <typename tParams>
CSonarConfiguration<tParams>::~CSonarConfiguration( void )
{
    Close();
    m_fpFile = NULL;
}

template <typename tParams>
bool CSonarConfiguration<tParams>::Open(    const int       &riSensorIndex,
                                            const EACCESS   &reAccess )
{
    bool bSuccess = false;

    CString FileName;

    FileName.Format( "%sRESON7KSonar%d.cfg", static_cast<LPCTSTR>( GetPath() ), riSensorIndex );

    LPCTSTR pszFileName = static_cast<LPCTSTR>( FileName );

    // Ensure any existing file is closed first.

    Close();

    // Open the newly specified file with the appropriate access rights.

    switch ( reAccess )
    {
        case accessWrite:

            bSuccess = (( m_fpFile = ::fopen( pszFileName, "wb" ) ) != NULL );
            break;

        case accessRead:
            
            // Open the file for read access. If it fails, it probably doesn't exist so try to create
            // it then re-open with read access rights.

            if ( ( m_fpFile = ::fopen( pszFileName, "rb" ) ) == NULL )
            {
                if ( ( m_fpFile = ::fopen( pszFileName, "wb" ) ) != NULL )
                {
                    Write();
                    Close();

                    bSuccess = ( ( m_fpFile = ::fopen( pszFileName, "rb" ) ) != NULL );
                }
            }

            bSuccess = ( m_fpFile != NULL );

            break;
    }

    return bSuccess;
}
                             
template <typename tParams>
bool CSonarConfiguration<tParams>::Close( void )
{
    if ( m_fpFile != NULL )
    {
        fclose( m_fpFile );
        m_fpFile = NULL;
    }

    return ( m_fpFile == NULL );
}
                             
template <typename tParams>
bool CSonarConfiguration<tParams>::IsOpen( void ) const
{
    return ( m_fpFile != NULL );
}
                             
template <typename tParams>
bool CSonarConfiguration<tParams>::Write( void )
{
    if ( IsOpen() )
    {
        return ( ::fwrite( this, Size(), 1, m_fpFile ) == 1 );
    }

    return false;
}

template <typename tParams>
bool CSonarConfiguration<tParams>::Read( void )
{
    bool bSuccess = false;

    if ( IsOpen() )
    {
        bSuccess = ( ::fread( this, Size(), 1, m_fpFile ) == 1 );
    }

    if ( ! bSuccess )
    {
        SetDefault();
    }

    return bSuccess;
}

template <typename tParams>
bool CSonarConfiguration<tParams>::SetDefault( void )
{
    return tParams::SetDefault();
}

template <typename tParams>
CSonarConfiguration<tParams>::operator const tParams * ( void ) const
{
    return static_cast<const tParams *>( this );
}

template <typename tParams>
CString CSonarConfiguration<tParams>::GetPath( void ) const
{
    CString Path;

    LPSTR pszAppPath = Path.GetBuffer( _MAX_PATH );

    ::GetModuleFileName( NULL, pszAppPath, _MAX_PATH );

    int iLength;

    if ( ( iLength = strlen( pszAppPath ) ) > 0 )
    {
        while ( --iLength )
        {
            if ( ( pszAppPath[ iLength ] == '\\' ) ||
                 ( pszAppPath[ iLength ] == ':' )   )
            {
                pszAppPath[ iLength + 1 ] = '\0';
                break;
            }
        }
    }

    Path.ReleaseBuffer();

    return Path;
}

template <typename tParams>
size_t CSonarConfiguration<tParams>::Size( void ) const
{
    return sizeof( tParams );
}

#endif // !defined(AFX_SONARCONFIGURATION_H__3501271A_E7A2_4D53_959A_55710D5F8225__INCLUDED_)
