//-------------------------------------------------------------------------------------------------------
// VST Plug-Ins SDK
// Version 2.4		$Date: 2006/11/13 09:08:28 $
//
// Category     : VST 2.x SDK Samples
// Filename     : Editor.cpp
// Created by   : Steinberg Media Technologies
// Description  : Simple Surround Delay plugin with Editor using VSTGUI
//
// © 2006, Steinberg Media Technologies, All Rights Reserved
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// Date: 2008/05/10 
//
// Category     : VST 2.x SDK Samples
// Filename     : my_editor.cpp
// Created by   : David Henzl
// Description  : GUI Editor for AWtm(Echo Hiding) (Mono->Stereo)
//-------------------------------------------------------------------------------------------------------

#ifndef __my_editor__
#include "my_editor.h"
#endif

#include <stdio.h>
#include <math.h>
#include <vstcontrols.h>

//-----------------------------------------------------------------------------
// resource id's
enum
{
	kDelay0Txt=20,
	kDelay1Txt,
	kAlfaTxt,
	kVSTblokTxt,
	kWatermarkTxt,
	kWatermark2Txt,
	kBlocksizeinfoTxt, //Alternativní velikost bloku
	kModeTxt,
	kText,

};
enum {
	// bitmaps
	kBackgroundId = 128,
	kPowerBodyId,
	kFaderHandleId,
	kMaster,
	kPowerPixmapId,
	kButtonPixmapId,
	kBigKnobId,
	kWaveWinID,
	kMinMax,

	// positions

	kModeX = 20, //Tablex. 34.8pix)
	kModeY = 100, //(Tabley. 85.8pix)
	kDelay0X =33,
	kDelay0Y =100,

	kInfoTxtX = 350,
	kInfoTxtY = 80,

	kDisplayX = 157,
	kDisplayY = 30,
	kDisplayXWidth = 30,
	kDisplayHeight = 14,
	kWaveDisplayX = 364,
	kWaveDisplayY = 13,
	kDispParamsX = 157,
	kDispParamsY = 20,
};
enum {
	//button on,off
	kOff=0,
	kOn=1,
	kButt1=10,
	kButt2=11,

};

//-----------------------------------------------------------------------------
// prototype string convert float -> percent
void percentStringConvert (float value, char* string);
void percentStringConvert (float value, char* string)
{
	sprintf (string, "%d%%", (int)(100 * value + 0.5f));

}
//-----------------------------------------------------------------------------
// Editor class implementation
//-----------------------------------------------------------------------------
Editor::Editor (AudioEffect *effect,int pSizeWaveDisp, char* Wtm)
: AEffGUIEditor (effect) 
{

	Delay0Display = 0;
	Delay1Display = 0;
	AlfaDisplay = 0;
	Delay0Val = 0;
	Delay1Val = 0;
	AlfaVal = 0;
	WaveDisplay = 0;
	Wtmblok=0;
	CharCounter=0;
	Wtmlength=10;
	Delay0 = "Delay0";
	Delay1 = "Delay1";
	Alfa   = "Alfa";
	VSTblok = "VST Blok";
	Mode = "MODE";
	Inserting = "Inserting";
	Decoding = "Decoding";
	InsertWtm = "Insert Watermark Here";
	DecodedWtm = "Decoded Watermark";

	Watermark2 = "xxxxxxxxxx";
	WtmInfo="Insert Alternative Block Size!";
	strcpy(Info,"xxxx");	
	//pBuff = new float[100];
	Wavesize = pSizeWaveDisp;
	_index = 0;
	buffer = new float[Wavesize];
	Wtm2Insert=Wtm;
	Watermark=Wtm2Insert;
	strcpy(ReceivedString,"x");

	// load the background bitmap
	// we don't need to load all bitmaps, this could be done when open is called
	hBackground = new CBitmap (kBackgroundId);

	// init the size of the plugin
	rect.left   = 0;
	rect.top    = 0;
	rect.right  = (short)hBackground->getWidth ();
	rect.bottom = (short)hBackground->getHeight ();
}
//-----------------------------------------------------------------------------
Editor::~Editor ()
{
	// free the background bitmap
	if (hBackground)
		hBackground->forget ();
	hBackground = 0;
}
//-----------------------------------------------------------------------------
bool Editor::open (void *ptr)
{
	// !!! always call this !!!
	AEffGUIEditor::open (ptr);

	//--load some bitmaps
	CBitmap* hPowerPixmap   = new CBitmap (kPowerPixmapId);
	CBitmap* hButtonPixmap   = new CBitmap (kButtonPixmapId);
	CBitmap* hBigKnob   = new CBitmap (kBigKnobId);
	CBitmap* hWaveWindow   = new CBitmap (kWaveWinID);

	//--init background frame-----------------------------------------------
	// We use a local CFrame object so that calls to setParameter won't call into objects which may not exist yet. 
	// If all GUI objects are created we assign our class member to this one. See bottom of this method.
	CRect size (0, 0, hBackground->getWidth (), hBackground->getHeight ());
	CFrame* lFrame = new CFrame (size, ptr, this);
	lFrame->setBackground (hBackground);

	//--init the faders------------------------------------------------

	CPoint point (0, 0);
	CPoint offset (1,0);
	//text
	size (kDispParamsX,kDispParamsY,kDispParamsX + 30,kDispParamsY + 10);
	Delay0Txt = new CTextEdit (size,this,kDelay0Txt,Delay0,0,0);
	Delay0Txt->setFont(kNormalFontVerySmall);
	Delay0Txt->setFontColor(kYellowCColor);
	Delay0Txt->setTxtFace(kNormalFace);
	Delay0Txt->setMouseEnabled(false);
	Delay0Txt->setTransparency(true);
	lFrame->addView (Delay0Txt);

	size.offset (40, 0);
	Delay1Txt = new CTextEdit (size,this,kDelay1Txt,Delay1,0,0);
	Delay1Txt->setFont(kNormalFontVerySmall);
	Delay1Txt->setFontColor(kYellowCColor);
	Delay1Txt->setTxtFace(kNormalFace);
	Delay1Txt->setTransparency(true);
	Delay1Txt->setMouseEnabled(false);
	lFrame->addView (Delay1Txt);

	size.offset (40, 0);
	AlfaTxt = new CTextEdit (size,this,kAlfaTxt,Alfa,0,0);
	AlfaTxt->setFont(kNormalFontVerySmall);
	AlfaTxt->setFontColor(kYellowCColor);
	AlfaTxt->setTxtFace(kNormalFace);
	AlfaTxt->setMouseEnabled(false);
	AlfaTxt->setTransparency(true);
	lFrame->addView (AlfaTxt);

	size.setWidth(kDisplayXWidth + 8);
	size.offset (40, 0);
	VSTBlokTxt = new CTextEdit (size,this,kVSTblokTxt,VSTblok,0,0);
	VSTBlokTxt->setFont(kNormalFontVerySmall);
	VSTBlokTxt->setFontColor(kYellowCColor);
	VSTBlokTxt->setTxtFace(kNormalFace);
	VSTBlokTxt->setMouseEnabled(false);
	VSTBlokTxt->setTransparency(true);
	lFrame->addView (VSTBlokTxt);

	size (kInfoTxtX, kInfoTxtY,kInfoTxtX + 100, kInfoTxtY + 10);
	InsertWtmTxt = new CTextEdit (size,this,kText,InsertWtm,0,0);
	InsertWtmTxt->setFont(kNormalFontVerySmall);
	InsertWtmTxt->setFontColor(kYellowCColor);
	InsertWtmTxt->setTxtFace(kNormalFace);
	InsertWtmTxt->setTransparency(true);
	InsertWtmTxt->setMouseEnabled(false);
	lFrame->addView (InsertWtmTxt);

	size.offset (0, 10);
	WatermarkTxt = new CTextEdit (size,this,kWatermarkTxt,Watermark,0,0);
	WatermarkTxt->setFont(kNormalFontVerySmall);
	WatermarkTxt->setFontColor(kYellowCColor);
	WatermarkTxt->setTxtFace(kNormalFace);
	WatermarkTxt->setTransparency(true);
	lFrame->addView (WatermarkTxt);

	size.offset (0, 15);
	DecodedWtmTxt = new CTextEdit (size,this,kText,DecodedWtm,0,0);
	DecodedWtmTxt->setFont(kNormalFontVerySmall);
	DecodedWtmTxt->setFontColor(kYellowCColor);
	DecodedWtmTxt->setTxtFace(kNormalFace);
	DecodedWtmTxt->setMouseEnabled(false);
	DecodedWtmTxt->setTransparency(true);
	lFrame->addView (DecodedWtmTxt);

	size.offset (0, 10);
	Watermark2Txt = new CTextEdit (size,this,kWatermark2Txt,Watermark2,0,0);
	Watermark2Txt->setFont(kNormalFontVerySmall);
	Watermark2Txt->setFontColor(kYellowCColor);
	Watermark2Txt->setTxtFace(kNormalFace);
	Watermark2Txt->setTransparency(true);
	lFrame->addView (Watermark2Txt);

	size.setWidth(150);
	size.offset(0,15);
	BlocksizeinfoTxt = new CTextEdit (size,this,kBlocksizeinfoTxt,WtmInfo,0,0);
	BlocksizeinfoTxt->setFont(kNormalFontSmall);
	BlocksizeinfoTxt->setFontColor(kYellowCColor);
	BlocksizeinfoTxt->setTxtFace(kNormalFace);
	//BlocksizeinfoTxt->setMouseEnabled(false);
	BlocksizeinfoTxt->setTransparency(true);
	lFrame->addView (BlocksizeinfoTxt);

	size(kDispParamsX+17,kDispParamsY+78,kDispParamsX+20 + hBigKnob->getWidth(), kDispParamsY+78 + hBigKnob->getHeight()/58);

	Delay0Val = new CAnimKnob(size, this, AEcho_Hiding_Wtm::kDelay0, 57, 35 , hBigKnob, point);
	Delay0Val->setValue(effect->getParameter(AEcho_Hiding_Wtm::kDelay0)/512);
	Delay0Val->setTransparency(false);
	lFrame->addView(Delay0Val);

	size.offset(hBigKnob->getWidth()+22,0);
	Delay1Val = new CAnimKnob(size, this, AEcho_Hiding_Wtm::kDelay1, 57, 35 , hBigKnob, point);
	Delay1Val->setValue(effect->getParameter(AEcho_Hiding_Wtm::kDelay1)/512);
	Delay1Val->setTransparency(false);
	lFrame->addView(Delay1Val);

	size.offset(hBigKnob->getWidth()+22,0);
	AlfaVal = new CAnimKnob(size, this, AEcho_Hiding_Wtm::kAlfa, 57, 35 , hBigKnob, point);
	AlfaVal->setValue(effect->getParameter(AEcho_Hiding_Wtm::kAlfa));
	AlfaVal->setTransparency(false);
	lFrame->addView(AlfaVal);

	//--init the display------------------------------------------------
	// Delay1
	size (kDisplayX, kDisplayY,kDisplayX + kDisplayXWidth, kDisplayY + kDisplayHeight);
	Delay0Display = new CParamDisplay (size, 0, kCenterText);
	Delay0Display->setFont (kNormalFontSmall);
	Delay0Display->setFontColor (kWhiteCColor);
	Delay0Display->setBackColor (kBlackCColor);
	Delay0Display->setFrameColor (kBlueCColor);
	Delay0Display->setValue (effect->getParameter (AEcho_Hiding_Wtm::kDelay0));
	lFrame->addView (Delay0Display);
	// Delay1
	size.offset (40,0);
	Delay1Display = new CParamDisplay (size, 0, kCenterText);
	Delay1Display->setFont (kNormalFontSmall);
	Delay1Display->setFontColor (kWhiteCColor);
	Delay1Display->setBackColor (kBlackCColor);
	Delay1Display->setFrameColor (kBlueCColor);
	Delay1Display->setValue (effect->getParameter (AEcho_Hiding_Wtm::kDelay1));
	lFrame->addView (Delay1Display);
	// Alfa
	size.setWidth(kDisplayXWidth + 3);
	size.offset (40,0);
	AlfaDisplay = new CParamDisplay (size, 0, kRightText);
	AlfaDisplay->setFont (kNormalFontSmall);
	AlfaDisplay->setFontColor (kWhiteCColor);
	AlfaDisplay->setBackColor (kBlackCColor);
	AlfaDisplay->setFrameColor (kBlueCColor);
	AlfaDisplay->setValue (effect->getParameter (AEcho_Hiding_Wtm::kAlfa));
	lFrame->addView (AlfaDisplay);
	// Sizo of VST blok
	size.setWidth(kDisplayXWidth + 3);
	size.offset (40,0);
	VSTBlokDisplay = new CParamDisplay (size, 0, kRightText);
	VSTBlokDisplay->setFont (kNormalFontSmall);
	VSTBlokDisplay->setFontColor (kWhiteCColor);
	VSTBlokDisplay->setBackColor (kBlackCColor);
	VSTBlokDisplay->setFrameColor (kBlueCColor);
	VSTBlokDisplay->setValue (effect->getParameter (AEcho_Hiding_Wtm::kVSTblok));
	lFrame->addView (VSTBlokDisplay);
	//Mode Area
	size (kModeX, kModeY,kModeX + 30, kModeY + 15);
	ModeTxt = new CTextEdit (size,this,kModeTxt,Mode,0,0);
	ModeTxt->setFont(kNormalFontSmall);
	ModeTxt->setFontColor(kYellowCColor);
	ModeTxt->setTxtFace(kNormalFace);
	ModeTxt->setMouseEnabled(false);
	ModeTxt->setTransparency(true);
	lFrame->addView (ModeTxt);
	//Buttons and labels
	size (kModeX, kModeY+15 ,kModeX + hButtonPixmap->getWidth(), kModeY + 15 + hButtonPixmap->getHeight()/2);
	button1 = new COnOffButton (size,this,kButt1,hButtonPixmap);
	button1->setValue (1.0f-effect->getParameter (AEcho_Hiding_Wtm::kMode));
	button1->setTransparency(false);
	lFrame->addView (button1);

	size.offset(15,-2);
	size.setWidth(50);
	size.setHeight(12);
	InsertingTxt = new CTextEdit (size,this,kModeTxt,Inserting,0,0);
	InsertingTxt->setFont(kNormalFontSmall);
	InsertingTxt->setFontColor(kYellowCColor);
	InsertingTxt->setTxtFace(kNormalFace);
	InsertingTxt->setMouseEnabled(false);
	InsertingTxt->setTransparency(true);
	lFrame->addView (InsertingTxt);

	size (kModeX, kModeY+30 ,kModeX + hButtonPixmap->getWidth(), kModeY + 30 + hButtonPixmap->getHeight()/2);
	button2 = new COnOffButton (size,this,kButt2,hButtonPixmap);
	button2->setValue (effect->getParameter (AEcho_Hiding_Wtm::kMode));
	button2->setTransparency(false);
	lFrame->addView (button2);

	size.offset(15,-2);
	size.setWidth(50);
	size.setHeight(12);
	DecodingTxt = new CTextEdit (size,this,kModeTxt,Decoding,0,0);
	DecodingTxt->setFont(kNormalFontSmall);
	DecodingTxt->setFontColor(kYellowCColor);
	DecodingTxt->setTxtFace(kNormalFace);
	DecodingTxt->setMouseEnabled(false);
	DecodingTxt->setTransparency(true);
	lFrame->addView (DecodingTxt);

	//Wavedisp Area for Cepstral Display
	size (kWaveDisplayX, kWaveDisplayY,kWaveDisplayX +120,kWaveDisplayY + 60);
	WaveDisplay = new CWaveform (size,this,AEcho_Hiding_Wtm::kWavDisp,hWaveWindow);
	my_context = new CDrawContext(lFrame,NULL,systemWindow);
	WaveDisplay->setValue (buffer,Wavesize);
	WaveDisplay->setMin(0.0f);
	WaveDisplay->setWheelInc(10.0f);
	WaveDisplay->setMax(1.0f);
	WaveDisplay->setColor (kYellowCColor);
	WaveDisplay->setTransparency(true);
	WaveDisplay->setWantsFocus(true);
	lFrame->addView (WaveDisplay);

	frame = lFrame;
	return true;
}
//-----------------------------------------------------------------------------
void Editor::close ()
{
	delete frame;
	frame = 0;

}
//-----------------------------------------------------------------------------
void Editor::setParameter (VstInt32 index, float value)
{	
	if (frame == 0)
		return;

	switch (index)
	{
	case AEcho_Hiding_Wtm::kDelay0:
		Delay0Val->setValue (effect->getParameter (index)/512);
		if (Delay0Display)
			Delay0Display->setValue (effect->getParameter (index));
		break;
	case AEcho_Hiding_Wtm::kDelay1:
		Delay1Val->setValue (effect->getParameter (index)/512);
		if (Delay1Display)
			Delay1Display->setValue (effect->getParameter (index));	break;
	case AEcho_Hiding_Wtm::kAlfa: 
		if (AlfaDisplay)
			AlfaVal->setValue (effect->getParameter (index));
		AlfaDisplay->setValue(effect->getParameter (index));	break;
	case AEcho_Hiding_Wtm::kVSTblok:

		//sprintf(info,"Block size is %d%",(int)value);
		VSTBlokDisplay->setValue(value);							break;

	case AEcho_Hiding_Wtm::kWavDisp:
		if(_index > Wavesize)
		{
			_index = 0;
			WaveDisplay->setValue(buffer,Wavesize);				
			WaveDisplay->draw(my_context);
		}
		buffer[_index++] =value;									break;

	case AEcho_Hiding_Wtm::kWavDispSize:
		Wavesize=(int)value;
		memset (buffer, 0, Wavesize * sizeof (float));
		WaveDisplay->setValue(buffer,(int)value);					
		_index = 0;													break;
	case AEcho_Hiding_Wtm::kCharCounter:
		ReceivedString[CharCounter]=(int)value;
		Watermark2Txt->setText(ReceivedString);	
		if(++CharCounter > Wtmlength){
			CharCounter=0; 
		}
		break;
	}
}
//-----------------------------------------------------------------------------
void Editor::valueChanged (CDrawContext* context, CControl* control)  //rewritte display parameters
{	
	long tag = control->getTag ();

	switch (tag)
	{
	case AEcho_Hiding_Wtm::kDelay0:
		Delay0Display->setValue (floor(control->getValue ()*512));
		effect->setParameterAutomated(AEcho_Hiding_Wtm::kDelay0,(float)(control->getValue ())*512);	break;
	case AEcho_Hiding_Wtm::kDelay1:
		Delay1Display->setValue (floor(control->getValue ()*512));
		effect->setParameterAutomated(AEcho_Hiding_Wtm::kDelay1,(float)(control->getValue ())*512);	break;
	case AEcho_Hiding_Wtm::kAlfa:
		AlfaDisplay->setValue (control->getValue ());			
		effect->setParameterAutomated(AEcho_Hiding_Wtm::kAlfa,control->getValue ());				break;

	case kWatermarkTxt:	
		WatermarkTxt->getText(Wtm2Insert);
		effect->setParameterAutomated(AEcho_Hiding_Wtm::kWatermark,1.0f);							break;

	case kBlocksizeinfoTxt:	
		BlocksizeinfoTxt->getText(Info);
		Wtmblok = 100*((int)Info[0]-48)+10*((int)Info[1]-48)+((int)Info[2]-48);
		effect->setParameterAutomated(AEcho_Hiding_Wtm::kWtmblok,(float)Wtmblok);
		effect->setParameterAutomated(AEcho_Hiding_Wtm::kWitchBlok,1.0f);//Změna velikosti bloku
		effect->setParameterAutomated(AEcho_Hiding_Wtm::kWatermark,1.0f);//opakovana inicializace algoritmu
		//sprintf(Info,"Alternative Block size is %d%",(int)Wtmblok);
		//BlocksizeinfoTxt->setText(Info);break;

	case kButt1:		
		if(button1->getValue() == kOn)	
		{
			button2->setValue(kOff);
			effect->setParameterAutomated(AEcho_Hiding_Wtm::kMode, 0.0f);
			effect->setParameterAutomated(AEcho_Hiding_Wtm::kWatermark,1.0f);//opakovana inicializace algoritmu
		}else button1->setValue(kOn);	break;

	case kButt2:
		if(button2->getValue() == kOn)	
		{
			button1->setValue(kOff);
			effect->setParameterAutomated(AEcho_Hiding_Wtm::kMode, 1.0f);
			effect->setParameterAutomated(AEcho_Hiding_Wtm::kWatermark,1.0f);//opakovana inicializace algoritmu
		}button2->setValue(kOn);	break;	

	}

	control->setDirty ();
}
//-----------------------------------------------------------------------------
char* Editor::getwatermark ()
{
	return Wtm2Insert;
}
//-----------------------------------------------------------------------------