/*
  ==============================================================================

  This is an automatically generated GUI class created by the Introjucer!

  Be careful when adding custom code to these files, as only the code within
  the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
  and re-saved.

  Created with Introjucer version: 3.1.0

  ------------------------------------------------------------------------------

  The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions"
  Copyright 2004-13 by Raw Material Software Ltd.

  ==============================================================================
*/

//[Headers] You can add your own extra header files here...
#include "noise.h"
void mylog(const char* format, ...);
//[/Headers]

#include "DrawComponent.hpp"


//[MiscUserDefs] You can add your own user definitions and misc code here...
//[/MiscUserDefs]

//==============================================================================
DrawComponent::DrawComponent (int width, int height, float offset, float scale)
    : m_pListener(nullptr)
{

    //[UserPreSize]
    m_width = width;
    m_height = height;
	m_offset = offset;
	m_scale = scale;
    m_scaleX = 1.0;
    m_scaleY = 1.0;
	m_pG = nullptr;

    //[/UserPreSize]

    setSize (80, 80);


    //[Constructor] You can add your own custom stuff here..
    m_pG->setImageResamplingQuality(Graphics::lowResamplingQuality);
    clear();
    //[/Constructor]
}

DrawComponent::~DrawComponent()
{
    //[Destructor_pre]. You can add your own custom destruction code here..
    //[/Destructor_pre]



    //[Destructor]. You can add your own custom destruction code here..
	m_pG = nullptr;
	m_pListener = nullptr;
	m_data.resize(0);
    //[/Destructor]
}

//==============================================================================
void DrawComponent::paint (Graphics& g)
{
    //[UserPrePaint] Add your own custom painting code here..
	AffineTransform t;

	g.drawImage(m_image, 0, 0, getWidth(), getHeight(), 0, 0, getWidth(), getHeight(), false);
//	g.drawImageTransformed(*m_pImage, t.rotated(8), false);
	return;
    //[/UserPrePaint]

    g.fillAll (Colours::grey);

    //[UserPaint] Add your own custom painting code here..
    //[/UserPaint]
}

void DrawComponent::resized()
{
    //[UserResized] Add your own custom resize handling here..
//	mylog("%s (%d,%d)\n", __func__, getWidth(), getHeight());
	m_scaleX = (float)getWidth()/m_width;
	m_scaleY = (float)getHeight()/m_height;
	m_image = Image(Image::RGB , getWidth(), getHeight(), true);
	m_pG = nullptr;
    m_pG = new Graphics(m_image);

	repaint();
    //[/UserResized]
}

void DrawComponent::mouseMove (const MouseEvent& e)
{
    //[UserCode_mouseMove] -- Add your code here...
//	mylogMessage(String("MouseMove"));
    //[/UserCode_mouseMove]
}

void DrawComponent::mouseEnter (const MouseEvent& e)
{
    //[UserCode_mouseEnter] -- Add your code here...
//	mylog("%s\n", __func__);
    //[/UserCode_mouseEnter]
}

void DrawComponent::mouseExit (const MouseEvent& e)
{
    //[UserCode_mouseExit] -- Add your code here...
//	mylog("%s\n", __func__);
    //[/UserCode_mouseExit]
}

void DrawComponent::mouseDown (const MouseEvent& e)
{
    //[UserCode_mouseDown] -- Add your code here...
//	mylog("%s x:%d, y:%d\n", __func__, e.x, e.y);
	if (e.mods.isRightButtonDown())
	{
		clear();
	}
	else
	{
		drawAt(e.x, e.y, true);
	}
	if (m_pListener)
		m_pListener->onDraw(*this);
    //[/UserCode_mouseDown]
}

void DrawComponent::mouseDrag (const MouseEvent& e)
{
    //[UserCode_mouseDrag] -- Add your code here...
//	mylog("%s x:%d, y:%d\n", __func__, e.x, e.y);
	if (e.mods.isLeftButtonDown())
	{
		drawAt(e.x, e.y, false);
		if (m_pListener)
			m_pListener->onDraw(*this);
	}
    //[/UserCode_mouseDrag]
}

void DrawComponent::mouseUp (const MouseEvent& e)
{
    //[UserCode_mouseUp] -- Add your code here...
//	mylog("%s\n", __func__);
    //[/UserCode_mouseUp]
}

void DrawComponent::mouseDoubleClick (const MouseEvent& e)
{
    //[UserCode_mouseDoubleClick] -- Add your code here...
//	mylog("%s\n", __func__);
    //[/UserCode_mouseDoubleClick]
}

void DrawComponent::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel)
{
    //[UserCode_mouseWheelMove] -- Add your code here...
//	mylog("%s\n", __func__);
    //[/UserCode_mouseWheelMove]
}



//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
void DrawComponent::setListener(DrawListener *pListener)
{
	m_pListener = pListener;
}

void DrawComponent::drawAt(int x, int y, bool setColor)
{
	int index;
	double fx = (double)x / m_scaleX;
	double fy = (double)y / m_scaleY;

	index = (int)(x/m_scaleX) + m_width*(int)(y/m_scaleY);

	if (index >= 0)
	{
		if (index < m_width*m_height)
		{
			if (setColor)
			{
				if (m_data[index] > 0.0)
				{
					m_currData = 0.0;
					m_currColor = (Colours::black);
				}
				else
				{
					m_currData = 1.0;
					m_currColor = (Colours::white);
				}
			}
			m_data[index] = m_currData;
			m_pG->setColour (m_currColor);
		}
	}

	x = (int)fx * m_scaleX;
	y = (int)fy * m_scaleY;
	m_pG->fillRect((float)x, (float)y, m_scaleX, m_scaleY);
	repaint();
}

void DrawComponent::clear()
{
    m_data = arma::zeros(1, m_width*m_height);
	DrawData();
}

arma::mat& DrawComponent::getData ()
{
	return m_data;
}

void DrawComponent::DrawData ()
{
	double max = arma::abs(m_data).max();
	
	if (max < 1.0)
	{
		max = 1.0;
	}
	double scale = m_scale/max;
	
	for (int i=0; i < m_height; i++)
	{
		for (int j=0; j < m_width; j++)
		{
			m_pG->setColour(Colour(Colours::white).greyLevel(m_offset + scale*m_data(i*m_width + j)));
			m_pG->fillRect(m_scaleX*j, m_scaleY*i, m_scaleX, m_scaleY);
		}
	}
	
    repaint();

}

//[/MiscUserCode]


//==============================================================================
#if 0
/*  -- Introjucer information section --

    This is where the Introjucer stores the metadata that describe this GUI layout, so
    make changes in here at your peril!

BEGIN_JUCER_METADATA

<JUCER_COMPONENT documentType="Component" className="DrawComponent" componentName=""
                 parentClasses="public Component" constructorParams="int width, int height"
                 variableInitialisers="m_pListener(nullptr)" snapPixels="8" snapActive="1"
                 snapShown="1" overlayOpacity="0.330" fixedSize="0" initialWidth="80"
                 initialHeight="80">
  <METHODS>
    <METHOD name="mouseUp (const MouseEvent&amp; e)"/>
    <METHOD name="mouseMove (const MouseEvent&amp; e)"/>
    <METHOD name="mouseEnter (const MouseEvent&amp; e)"/>
    <METHOD name="mouseExit (const MouseEvent&amp; e)"/>
    <METHOD name="mouseDown (const MouseEvent&amp; e)"/>
    <METHOD name="mouseDrag (const MouseEvent&amp; e)"/>
    <METHOD name="mouseDoubleClick (const MouseEvent&amp; e)"/>
    <METHOD name="mouseWheelMove (const MouseEvent&amp; e, const MouseWheelDetails&amp; wheel)"/>
  </METHODS>
  <BACKGROUND backgroundColour="ff808080"/>
</JUCER_COMPONENT>

END_JUCER_METADATA
*/
#endif


//[EndFile] You can add extra defines here...
//[/EndFile]
