#pragma once
#include <string.h>
#include "staticVector.h"

template < int S >
class StaticString 
{
    char    _Arr[S];
    void    _SetString( const char* Str ) ;
public:
    StaticString( const char* Str );
    StaticString( ){ Clear(); };

    const char* Begin() const;
    const int   Size() const;
    void    Clear();

    const char* operator = ( const char* Str );
    const char* operator = ( char* Str );

    template < class T >  
        bool operator == ( const T& Src2 );

    template < class T >  
        bool operator != ( const T& Src2 );


    template < class T >  
    char* operator = ( const T& SrcStr  );

    void MakeLower( );
    void MakeUpper( );

    template < class T > 
        int  Compare( const T& SrcStr ) const;

    template < class T >
        int  CompareNoCase( const T& SrcStr  ) const; 

    int  Compare( const char* SrcStr ) const;  
    int  CompareNoCase( const char* SrcStr  ) const; 
    
};


template < int S >
StaticString<S>::StaticString( const char* Str )
{
    _SetString( Str );
};

template < int S >
const char* StaticString<S>::operator = ( const char* Str )
{
    _SetString( Str );
    return _Arr;
};

template < int S >
const char* StaticString<S>::operator = ( char* Str )
{
    _SetString( Str );
    return _Arr;
};

template < int S >
template < class T >
char* StaticString<S>::operator = ( const T& SrcStr  )
{
    _SetString( SrcStr.Begin() );
    return _Arr;
};


template < int S >
void    StaticString<S>::_SetString( const char* Str )
{
    int Size = (int)strlen( Str )+1;
    if( Size >= S )
    {
        Size = S-1;
        _Arr[ Size ] = 0;
    }

    memcpy( _Arr , Str , Size ); 
 
};

template < int S >
void StaticString<S>::MakeLower( )
{
    _strlwr( _Arr );
}

template < int S >
void StaticString<S>::MakeUpper( )
{
    _strupr( _Arr );
}

template < int S >
template < class T >
int  StaticString<S>::Compare( const T& SrcStr ) const
{
    return strcmp( _Arr , SrcStr.Begin() );
}

template < int S >
template < class T >
int  StaticString<S>::CompareNoCase( const T& SrcStr  ) const
{
    return stricmp( _Arr , SrcStr.Begin() );
}

template < int S >
int  StaticString<S>::Compare( const char* SrcStr ) const
{
    return strcmp( _Arr , SrcStr );
}

template < int S >
int  StaticString<S>::CompareNoCase( const char* SrcStr  ) const 
{
    return stricmp( _Arr , SrcStr );
}

template < int S >
template < class T >  
bool StaticString<S>::operator == ( const T& Src2 )
{
    return ( Compare( Src2 ) == 0 );
}

template < int S >
template < class T >  
bool StaticString<S>::operator != ( const T& Src2 )
{
    return ( Compare( Src2 ) != 0 );
}

template < int S >
const char* StaticString<S>::Begin() const
{
    return (const char*)_Arr;
}

template < int S >
const int   StaticString<S>::Size() const
{
    return int( strlen( _Arr ) );
}
template < int S >
void    StaticString<S>::Clear()
{
    _Arr[0] = 0;
}