#pragma once

#include <string>
#include <vector>
#include "byteBuffer.h"
#include "Util.h"

#define UNSUPPORTED_TOKEN "Unsupported"

#define ASN1TYPE_ISO	1
#define ASN1TYPE_CERES	0

#define PATHENC_BIN		2
#define PATHENC_ASCII	0

//
// Máscaras de bits en m_iASN1Flags
//
#define ASNFLAG_TYPE	1
#define ASNFLAG_PATHENC	2


using namespace std;


/********************************************************************************************
	Clase que representa un tipo de tarjeta.
********************************************************************************************/
class CTokenType
{

	public:

		// Constructor
		CTokenType(string sName);

		CTokenType( const CTokenType & tt )
		{
			DBG_TRACE(( "Constructor copy CTokenType(0x%08x) [0x%08x]\n", &tt, this ));
		};

		// Destructor
		~CTokenType(void);

		// Método que obtiene el nombre del tipo de tarjeta
		string GetName() const;

		// Método que obtiene el número de distintos ATRs que tiene el tipo de tarjeta
		unsigned int GetNumberOfAtrs() const;

		//
		// Método para comprobar si un ATR encaja con los registrados
		//
		bool IsValidAtr( byte * pAtr, ulong size );

		// Método que añade un ATR y su máscara asociada a la lista de ATRs
		void AddAtr(byteBuffer & sAtr, byteBuffer & sAtrMask);

		// Método que añade un mecanismo a la lista de soportados
		void AddMechanism(ulong mechanism){m_mechanismList.push_back(mechanism);};

		//
		// Método para añadir los parámetros asociados al tipo de token
		//
		void setCommType( int commType, byte * pParams, int size );

		//
		// Método para añadir los parámetros asociados al canal de PIN
		//
		void setPinParams( byte * pParams, int size );

		//
		// Método para obtener el tipo de objetos de comunicaciones que se debe instanciar
		//
		int getCommType( void ) const { return m_commType; };

		const byteBuffer & getParams( void ) const { return m_params; };

		const byteBuffer & getParamsPIN( void ) const { return m_paramsPIN; };

		//
		// Métodos para gestionar el tipo de ASN1 del TokenType
		//
		/*void SetASN1Type(int iASN1Type)
		{
			m_iASN1Flags &= ~ASNFLAG_TYPE;
			if( iASN1Type == ASN1TYPE_ISO )
				m_iASN1Flags |= ASNFLAG_TYPE;
		}

		void SetASN1PathEncoding(int iASN1PathEnc)
		{
			m_iASN1Flags &= ~ASNFLAG_PATHENC;
			if( iASN1PathEnc == PATHENC_BIN )
				m_iASN1Flags |= ASNFLAG_PATHENC;
		}*/
		
		void SetASN1Flags(int iASN1Flags)
		{
			m_iASN1Flags = iASN1Flags;
		}

		int GetASN1Type(void)
		{
			return (m_iASN1Flags&ASNFLAG_TYPE)?ASN1TYPE_ISO:ASN1TYPE_CERES;
		}

		int GetPathEncodingType(void)
		{
			return (m_iASN1Flags&ASNFLAG_PATHENC)?PATHENC_BIN:PATHENC_ASCII;
		}

		//
		// Miembros públicos de la clase
		//
		vector<ulong> m_mechanismList;

		enum
		{
			COMM_TYPE_PLAIN,
			COMM_TYPE_DNIE,
			COMM_TYPE_CERES1_0
		};

	private:

		// Nombre
		string	m_sName;

		// Tipo de objeto de comunicaciones para comunicarse con este tipo de token
		int		m_commType;

		byteBuffer	m_params;

		byteBuffer	m_paramsPIN;

		// Miembro para identificar las peculiaridades de ASN1:
		//	bit 0: tipo codificación ASN1--> ISO / CERES
		//	bit 1: codificación del path --> BIN / ASCII
		int m_iASN1Flags;

		// Lista de los distintos ATRs y máscaras asociadas a éstos
		vector< pair<byteBuffer,byteBuffer> > m_vecAtrs;
//		vector< pair<string, string>> m_vecAtrs;

};
