#ifndef CPPCADES_CERTIFICATE_OBJECT_H_
#define CPPCADES_CERTIFICATE_OBJECT_H_

#include "cppcades.h"
#include "CPPCadesCPKeyUsage.h"
#include "CPPCadesCPExtendedKeyUsage.h"
#include "CPPCadesCPBasicConstraints.h"
#include "CPPCadesCPPublicKey.h"
#include "CPPCadesCPPrivateKey.h"
#include "CPPCadesCPCertificateStatus.h"
#include "CPPCadesCPStore.h"

namespace CryptoPro {
namespace PKI {
namespace CAdES {

class CPPCadesCPCertificateStatusObject;
class CPPCadesCPStoreObject;

class CPPCadesCPCertificateObject
{
public:
    CPPCadesCPCertificateObject();
    ~CPPCadesCPCertificateObject();

    HRESULT GetInfo(CAPICOM_CERT_INFO_TYPE infoType, CAtlString& value);
    HRESULT HasPrivateKey(BOOL* value);
    HRESULT IsValid(boost::shared_ptr<CPPCadesCPCertificateStatusObject>& pVal);
    HRESULT ExtendedKeyUsage(boost::shared_ptr<CPPCadesCPExtendedKeyUsageObject>& value);
    HRESULT KeyUsage(boost::shared_ptr<CPPCadesCPKeyUsageObject>& value);
    HRESULT Export(CAPICOM_ENCODING_TYPE findType, CryptoPro::CBlob& value);
    HRESULT Import(CryptoPro::CBlob& value);
    HRESULT get_SerialNumber(CAtlString& value);
    HRESULT get_Thumbprint(CAtlString& value);
    HRESULT get_SubjectName(CAtlString& value);
    HRESULT get_IssuerName(CAtlString& value);
    HRESULT get_Version(DWORD* value);
    HRESULT get_ValidToDate(CryptoPro::CDateTime& value);
    HRESULT get_ValidFromDate(CryptoPro::CDateTime& value);
    HRESULT BasicConstraints(boost::shared_ptr<CPPCadesCPBasicConstraintsObject>& value);
    HRESULT get_CertContext(CCertContext& pVal);
    HRESULT put_CertContext(const CCertContext& pVal);
    HRESULT FreeContext(PCCERT_CONTEXT pVal);
    HRESULT PublicKey(boost::shared_ptr<CPPCadesCPPublicKeyObject>& pVal);
    HRESULT PrivateKey(boost::shared_ptr<CPPCadesCPPrivateKeyObject>& pVal);
    HRESULT FindPrivateKey(CAtlString cont_name);
    HRESULT AdditionalStore(boost::shared_ptr<CPPCadesCPStoreObject>& pStore);

#ifndef UNIX
    HRESULT Display(LONG hwndParent, const wchar_t* Title);
#endif
    //internal use
    HRESULT Clear();
    HRESULT Assign(CCertContext& value);
    PCCERT_CONTEXT GetHandle();
    PCCERT_CHAIN_CONTEXT BuildChain(void);
    void CheckValidState();
private:
    DISALLOW_COPY_AND_ASSIGN(CPPCadesCPCertificateObject);

    HRESULT FillExtendedKeyUsage();
    HRESULT FillKeyUsage();
    HRESULT FillBasicConstraints();
    HRESULT FillPublicKey();

#pragma warning(push)
#pragma warning(disable: 4251)
    CCertContext m_certificate;
    CCertChainContext m_certificateChain;
#pragma warning(pop)
    boost::shared_ptr<CPPCadesCPCertificateStatusObject> m_pCertStatus;
    boost::shared_ptr<CPPCadesCPExtendedKeyUsageObject> m_pExtendedKeyUsage;
    boost::shared_ptr<CPPCadesCPKeyUsageObject> m_pKeyUsage;
    boost::shared_ptr<CPPCadesCPBasicConstraintsObject> m_pBasicConstraints;
    boost::shared_ptr<CPPCadesCPPublicKeyObject> m_pPublicKey;
    boost::shared_ptr<CPPCadesCPPrivateKeyObject> m_pPrivateKey;
    boost::shared_ptr<CPPCadesCPStoreObject> m_pAdditionalStore;
};

} /* namespace CAdES */
} /* namespace PKI */
} /* namespace CryptoPro */

#endif // CPPCADES_CERTIFICATE_OBJECT_H_
