#ifndef CPPCADESCPSIGNER_H_
#define CPPCADESCPSIGNER_H_
#include "cppcades.h"
#include "CPPCadesCPAttributes.h"
#include "CPPCadesCollections.h"
#include "CPPCadesCPCertificate.h"
#include "CPPCadesCPCertificates.h"
#include "CPPCadesSignatureStatus.h"
#include "CPPCadesDate.h"
#include "CPPProtectedPin.h"

namespace CryptoPro {
namespace PKI {
namespace CAdES {

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

    // Свойства и методы CAPICOM.Signer
    HRESULT get_Certificate(boost::shared_ptr<CPPCadesCPCertificateObject>& pVal);
    HRESULT put_Certificate(const boost::shared_ptr<CPPCadesCPCertificateObject>& pVal);

    HRESULT get_CheckCertificate(BOOL &pVal);
    HRESULT put_CheckCertificate(BOOL bVal);

    HRESULT get_Options(CAPICOM_CERTIFICATE_INCLUDE_OPTION* pVal);
    HRESULT put_Options(const CAPICOM_CERTIFICATE_INCLUDE_OPTION pVal);


    HRESULT get_AuthenticatedAttributes(
        boost::shared_ptr<CPPCadesCPAttributesObject>& pVal);
    HRESULT get_UnauthenticatedAttributes(
        boost::shared_ptr<CPPCadesCPAttributesObject>& pVal);
    HRESULT put_AuthenticatedAttributes(
        boost::shared_ptr<CPPCadesCPAttributesObject> pVal);
    HRESULT put_UnauthenticatedAttributes(
        boost::shared_ptr<CPPCadesCPAttributesObject> pVal);
    HRESULT get_CRLs(boost::shared_ptr<CPPCadesCPBlobsObject>& pVal);
    HRESULT get_OCSPResponses(boost::shared_ptr<CPPCadesCPBlobsObject>& pVal);

    HRESULT get_TSAAddress(CAtlString& Value);
    HRESULT put_TSAAddress(CAtlString newVal);

#if defined _WIN32
    HRESULT Display(LONG hwndParent, const wchar_t * Title);
    HRESULT Load(const wchar_t * FileName, const wchar_t * Password);
#endif	// _WIN32

    HRESULT get_SignatureTimeStampTime(CDateTime& pVal);
    HRESULT get_SignatureStatus(
        boost::shared_ptr<CPPCadesSignatureStatusObject>& pVal);
    HRESULT get_SigningTime(CDateTime& pVal);

    HRESULT put_MsgInfo(HCRYPTMSG hMsg, DWORD dwSignerIndex,
        boost::shared_ptr<CPPCadesCPCertificatesObject>& certs);
    HRESULT put_SigTimes(LPFILETIME pSigningTime,
        LPFILETIME pSignatureTimeStampTime);
    HRESULT put_SignatureStatus(bool bIsValid);

    HRESULT put_KeyPin(CAtlStringA& newVal);

    // internal
    HRESULT get_HashAlgorithmOID(CAtlStringA& Value);
    HRESULT set_KeyPinInternal();
    const CMSG_SIGNER_ENCODE_INFO& get_signerEncodeInfo();
    bool IsCertPresent();
    //HRESULT get_Chain(PCCERT_CHAIN_CONTEXT* pVal);

private:
    DISALLOW_COPY_AND_ASSIGN(CPPCadesCPSignerObject);
    HRESULT GetCertForSigner(PCCMSG_CMS_SIGNER_INFO signerInfo,
        boost::shared_ptr<CPPCadesCPCertificatesObject>& pCerts,
        boost::shared_ptr<CPPCadesCPCertificateObject>& pCert);

    boost::shared_ptr<CPPCadesCPAttributesObject> m_pAuthAttrs;
    boost::shared_ptr<CPPCadesCPAttributesObject> m_pUnAuthAttrs;
    boost::shared_ptr<CPPCadesCPBlobsObject> m_pCRLs;
    boost::shared_ptr<CPPCadesCPBlobsObject> m_pOCSPResponses;
    boost::shared_ptr<CPPCadesSignatureStatusObject> m_SignatureStatus;
    boost::shared_ptr<CPPCadesCPCertificateObject> m_pCertificate;

    CDateTime m_dSignatureTimeStampTime;
    CDateTime m_dSigningTime;

    bool m_bIsSigningTimePresent;
    bool m_bIsAfterVerify;
    bool m_isKeyPinSetted;
    bool m_bIsSignatureTimeStampTimePresent;

    CAtlString m_TSAAddress;
    CProtectedPin m_pin;
    DWORD m_dwSignerIndex;
    CAPICOM_CERTIFICATE_INCLUDE_OPTION m_options;
    CAtlStringA m_hashAlg;
    bool m_CheckCertificate;
#ifndef UNIX
#pragma warning(push)
#pragma warning(disable: 4251)
#endif
    CMSG_SIGNER_ENCODE_INFO m_signer;
    ATL::CCryptProv m_hProv;
    ATL2::CCryptMsg m_msg;
#ifndef UNIX
#pragma warning(pop)
#endif
};
} /* namespace CAdES */
} /* namespace PKI */
} /* namespace CryptoPro */
#endif //CPPCADESCPSIGNER_H_
