#ifndef PLUGIN_HEXLANG_H
#define PLUGIN_HEXLANG_H

#include "SH_plugins_loader.h"
#include "SH_plugin_widgets.h"
#include "SH_plugins.h"
#include <QLineEdit>

namespace HexLang {
	enum CommandArgumentType {
		UChar,
		Char,
		UShort,
		Short,
		UInt,
		Int,
		ULLong,
		LLong,
		Float,
		Double
	};
	struct CommandArgument {
		CommandArgument(const QString & n = QString(), int i = 0, CommandArgumentType t = UChar,
						int ba = 1, int b = 0, bool be = false, bool av = false) {
			name = n;
			index = i;
			type = t;
			bytes = ba;
			byte = b;
			bigEndian = be;
			any_value = av;
		}
		QString name;
		int index;
		CommandArgumentType type;
		int bytes;
		int byte;
		bool bigEndian;
		bool any_value;
	};
	HexLang::CommandArgument getArgument(QString a);
	QVector<CommandArgument> parseArgument(QString a);
	QVector<CommandArgument> compileCommand(QString cmd);
	QStringList getUserArguments(QString cmd);
	QByteArray prepareCommand(const QVector<HexLang::CommandArgument> & cmd, const QVector<QVariant> & args);
	bool parseCommand(const QByteArray & rec, const QVector<HexLang::CommandArgument> & cmd_args, QVariantMap & extracted_args);
};

inline QDataStream & operator <<(QDataStream & s, const HexLang::CommandArgument & p) {
	s << p.index << (int)p.type << p.bytes << p.byte << p.bigEndian << p.name << p.any_value;
	return s;
}
inline QDataStream & operator >>(QDataStream & s, HexLang::CommandArgument & p) {
	int t = 0;
	s >> p.index >> t >> p.bytes >> p.byte >> p.bigEndian >> p.name >> p.any_value;
	p.type = (HexLang::CommandArgumentType)t;
	return s;
}


class HexLangWidget: public SHPacketWidgetBase {
	Q_OBJECT
public:
	HexLangWidget(QWidget * parent = 0);

	virtual SHS::Command saveCommand() override;
	virtual bool loadCommand(const SHS::Command & cmd) override;
	virtual QString commandToString(const SHS::Command & command) override;

private:
	QLineEdit * line;

};


class PluginHexLang: public SHPluginBasePacket {
	Q_OBJECT
public:
	explicit PluginHexLang() {}
	virtual ~PluginHexLang() {}

	virtual QString name() const override {return "HexLang";}
	virtual QString description() const override {return "Hexadecimal language";}
	virtual QString version() const override {return "0.1";}

	virtual SHPacketWidgetBase * createEditor() override {return new HexLangWidget();}

	virtual void prepareCommand(SHS::Object & root, SHS::Object & object, SHS::Command & command) override;
	virtual QByteArray sendPacket(SHS::Object & root, SHS::Object & object, SHS::Command & command) override;
	virtual ReceiveResults receivePacket(SHS::Object & root, SHS::Object & object, SHS::Command & command, QByteArray packet, QVariantMap & args) override;

};


SHS_BUILTIN_PLUGIN(PluginHexLang)


#endif
