#ifndef Key_H
#define Key_H

#include "OperatingSystem.h"
#include "ReferenceCounter.h"

namespace Framework
{
    namespace Encryption
    {
        //! Stores an array of bytes
        class Bytes : public virtual ReferenceCounter
        {
        private:
            char* bytes;
            bool del;
            int length;

        public:
            //! Creates an empty byte array
            DLLEXPORT Bytes();
            //! Creates a new byte array with a specific length
            //! \param length The length of the array
            DLLEXPORT Bytes(int length);
            //! Creates a new byte array by copying the bytes
            //! \param daten The bytes to copy
            //! \param length The number of bytes to copy
            DLLEXPORT Bytes(const char* daten, int length);
            //! Deletes the array
            DLLEXPORT ~Bytes();
            //! Fills the byte array by copying the bytes
            //! \param daten The bytes to copy
            DLLEXPORT void setBytes(const char* daten);
            //! Deletes the array and creates a new one
            //! \param daten The bytes to copy
            //! \param length The length of the array
            DLLEXPORT void setBytes(const char* daten, int length);
            //! Deletes the array and takes ownership of the given one without
            //! copying
            //! \param daten The new byte array
            //! \param length The length of the array
            DLLEXPORT void setBytesZ(char* daten, int length);
            //! Sets all bytes of the array to a specific value
            //! \param c The value to set the bytes to
            DLLEXPORT void fill(const char c);
            //! Sets a specific number of bytes of the array to a specific value
            //! \param c The value to set the bytes to
            //! \param len The number of bytes to set
            DLLEXPORT void fill(const char c, int len);
            //! Sets a specific section of bytes of the array to a specific
            //! value
            //! \param c The value to set the bytes to
            //! \param beg The start position of the section to set
            //! \param end The end position of the section to set (exclusive)
            DLLEXPORT void fill(const char c, int beg, int end);
            //! Copies specific bytes into the array
            //! \param c The bytes to copy
            //! \param cLength The number of bytes to set
            DLLEXPORT void fill(const char* c, int cLength);
            //! Sets a specific byte to a value
            //! \param c The value to set the byte to
            //! \param pos The position of the byte in the array
            DLLEXPORT void set(const char c, int pos);
            //! Returns the length of the array
            DLLEXPORT int getLength() const;
            //! Returns the array of bytes
            DLLEXPORT char* getBytes() const;
        };

        //! Can encrypt and decrypt byte sequences with specific keys
        class Key : public virtual ReferenceCounter
        {
        private:
            unsigned char* key;
            int length;
            int pos;

        public:
            //! Creates an empty object
            DLLEXPORT Key();
            //! Creates a new object with a key
            //! \param s The key to use for encryption and decryption
            //! \param length The length of the key
            DLLEXPORT Key(const char* s, int length);
            //! Deletes the object
            DLLEXPORT ~Key();
            //! Sets the position in the key where encryption and decryption
            //! should begin \param p The position in the key
            DLLEXPORT void setPos(__int64 p);
            //! Sets the key to use for encryption and decryption
            //! \param s The key \param length The length of the key
            DLLEXPORT void setKey(const char* s, int length);
            //! Encrypts a byte array with the set key
            //! \param daten The byte array to encrypt. Modified by the function
            DLLEXPORT void encode(Bytes* daten);
            //! Decrypts a byte array with the set key
            //! \param daten The byte array to decrypt. Modified by the function
            DLLEXPORT void decode(Bytes* daten);
        };
    } // namespace Encryption
} // namespace Framework

#endif