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

  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 "MainComponent.h"

#ifdef WIN32
#include <Windows.h>
#endif

//[/Headers]

#include "GameListPanel.h"
#include "EXCOSCSettingsComponent.h"
#include "CommandLineSettingsComponent.h"


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

//==============================================================================
GameListPanel::GameListPanel (MainContentComponent& mainComp)
    : mainComponent(mainComp),
      screenshot(nullptr)
{
    addAndMakeVisible (gameList = new TableListBox ("gameList", this));
    gameList->setName ("gameList");

    addAndMakeVisible (gameNameLabel = new Label ("gameNameLabel",
                                                  "Game Name"));
    gameNameLabel->setFont (Font (15.00f, Font::bold));
    gameNameLabel->setJustificationType (Justification::centred);
    gameNameLabel->setEditable (false, false, false);
    gameNameLabel->setColour (TextEditor::textColourId, Colours::black);
    gameNameLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000));

    addAndMakeVisible (gameAuthorLabel = new Label ("gameAuthorLabel",
                                                    "Game Author(s)"));
    gameAuthorLabel->setFont (Font (15.00f, Font::italic));
    gameAuthorLabel->setJustificationType (Justification::centred);
    gameAuthorLabel->setEditable (false, false, false);
    gameAuthorLabel->setColour (TextEditor::textColourId, Colours::black);
    gameAuthorLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000));

    addAndMakeVisible (gameDescLabel = new Label ("gameDescLabel",
                                                  "Game Description"));
    gameDescLabel->setFont (Font (15.00f, Font::plain));
    gameDescLabel->setJustificationType (Justification::topLeft);
    gameDescLabel->setEditable (false, false, false);
    gameDescLabel->setColour (TextEditor::textColourId, Colours::black);
    gameDescLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000));

    addAndMakeVisible (launchGameButton = new TextButton ("launchGameButton"));
    launchGameButton->setButtonText ("Launch Game");
    launchGameButton->addListener (this);

    addAndMakeVisible (optionsTabs = new TabbedComponent (TabbedButtonBar::TabsAtTop));
    optionsTabs->setTabBarDepth (30);
    optionsTabs->addTab ("OSC Settings", Colour (0xffeeece1), new EXCOSCSettingsComponent(), true);
    optionsTabs->addTab ("Command Line", Colour (0xffeeece1), new CommandLineSettingsComponent(), true);
    optionsTabs->setCurrentTabIndex (0);


    //[UserPreSize]

	selectedGame = 0;

    gameList->setHeader(new TableHeaderComponent());
    gameList->getHeader().addColumn("Game", 1, 256);
    gameList->getHeader().addColumn("Author(s)", 2, 192);
    gameList->getHeader().setStretchToFitActive(true);

	for(int i=0;i<mainComponent.getGames().size();++i)
		settings.add(new SavedSettings());

	{
		EXCOSCSettingsComponent *oscSettings(dynamic_cast<EXCOSCSettingsComponent *>(optionsTabs->getTabContentComponent(0)));
		CommandLineSettingsComponent *commandLine(dynamic_cast<CommandLineSettingsComponent *>(optionsTabs->getTabContentComponent(1)));

		if(oscSettings)
			oscSettings->addChangeListener(this);
		if(commandLine)
			commandLine->addChangeListener(this);
	}

    //[/UserPreSize]

    setSize (600, 400);


    //[Constructor] You can add your own custom stuff here..
    //[/Constructor]
}

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

    gameList = nullptr;
    gameNameLabel = nullptr;
    gameAuthorLabel = nullptr;
    gameDescLabel = nullptr;
    launchGameButton = nullptr;
    optionsTabs = nullptr;


    //[Destructor]. You can add your own custom destruction code here..
    //[/Destructor]
}

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

    g.fillAll (Colour (0xffeeece1));

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

    //Draw a border round gameList.
    g.setColour(Colour(0x60000000));
    g.fillRect(7, 7, (getWidth() - 152)+2, (getHeight() - 126+2));

    if(screenshot != nullptr)
    {
        //Draw the screenshot.
		g.setColour(Colours::white);
        g.drawImageWithin(*screenshot,
                          getWidth() - 136,
                          0,
                          128,
                          128,
                          RectanglePlacement(RectanglePlacement::centred));
    }

    //[/UserPaint]
}

void GameListPanel::resized()
{
    gameList->setBounds (8, 8, getWidth() - 152, getHeight() - 126);
    gameNameLabel->setBounds (getWidth() - 136, 120, 128, 24);
    gameAuthorLabel->setBounds (getWidth() - 136, 144, 128, 24);
    gameDescLabel->setBounds (getWidth() - 136, 168, 128, getHeight() - 286);
    launchGameButton->setBounds (getWidth() - 136, getHeight() - 110, 128, 102);
    optionsTabs->setBounds (8, getHeight() - 110, getWidth() - 152, 102);
    //[UserResized] Add your own custom resize handling here..
    //[/UserResized]
}

void GameListPanel::buttonClicked (Button* buttonThatWasClicked)
{
    //[UserbuttonClicked_Pre]
    //[/UserbuttonClicked_Pre]

    if (buttonThatWasClicked == launchGameButton)
    {
        //[UserButtonCode_launchGameButton] -- add your button handler code here..

        if(gameList->getSelectedRow() > -1)
			launchSelectedGame();

        //[/UserButtonCode_launchGameButton]
    }

    //[UserbuttonClicked_Post]
    //[/UserbuttonClicked_Post]
}



//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...

//------------------------------------------------------------------------------
void GameListPanel::changeListenerCallback(ChangeBroadcaster *source)
{
	EXCOSCSettingsComponent *oscSettings(dynamic_cast<EXCOSCSettingsComponent *>(optionsTabs->getTabContentComponent(0)));
	CommandLineSettingsComponent *commandLine(dynamic_cast<CommandLineSettingsComponent *>(optionsTabs->getTabContentComponent(1)));

	if(source == oscSettings)
	{
		settings[selectedGame]->listenPort = oscSettings->getListenPort();
		settings[selectedGame]->sendAddress = oscSettings->getSendAddress();
		settings[selectedGame]->sendPort = oscSettings->getSendPort();
		settings[selectedGame]->addPortsToPatcher = oscSettings->getAddPortsToPatcher();
	}
	else if(source == commandLine)
		settings[selectedGame]->commandLine = commandLine->getCommandLineArgs();
}

//------------------------------------------------------------------------------
void GameListPanel::paintRowBackground(Graphics &g,
                                       int rowNumber,
                                       int width,
                                       int height,
                                       bool rowIsSelected)
{
    if(rowIsSelected)
    {
        ColourGradient basil(Colour(0xFFB0B0FF).brighter(0.4f),
							 0.0f,
							 0.0f,
							 Colour(0xFFB0B0FF).darker(0.125f),
							 0.0f,
							 (float)height,
							 false);

		g.setGradientFill(basil);

		g.fillAll();
    }
    else
    {
        if(rowNumber%2)
            g.setColour(Colour(0xFFE8E8E8));
        else
            g.setColour(Colours::white);

        g.fillRect(0, 0, width, height);
    }
}

//------------------------------------------------------------------------------
void GameListPanel::paintCell(Graphics &g,
                              int rowNumber,
                              int columnId,
                              int width,
                              int height,
                              bool rowIsSelected)
{
    const OwnedArray<MainContentComponent::GameDetails>& games(mainComponent.getGames());

	if(rowIsSelected)
	{
		g.setColour(Colours::white);
		g.setFont(Font(14.0f, Font::bold));
	}
	else
		g.setColour(Colours::black);

    switch(columnId)
    {
        //Game name.
        case 1:
            g.drawFittedText(games[rowNumber]->name,
                             2,
                             0,
                             width-4,
                             height,
                             Justification(Justification::centredLeft),
                             1);
            break;
        //Game author(s).
        case 2:
            g.drawFittedText(games[rowNumber]->authors,
                             2,
                             0,
                             width-4,
                             height,
                             Justification(Justification::centredLeft),
                             1);
            break;
    }
}

//------------------------------------------------------------------------------
void GameListPanel::cellClicked(int rowNumber,
                                int columnId,
                                const MouseEvent &e)
{
    const OwnedArray<MainContentComponent::GameDetails>& games(mainComponent.getGames());

    gameNameLabel->setText(games[rowNumber]->name,
                           dontSendNotification);
    gameAuthorLabel->setText(games[rowNumber]->authors,
                             dontSendNotification);
    gameDescLabel->setText(games[rowNumber]->description,
                           dontSendNotification);

    screenshot = &(games[rowNumber]->screenshot);

	selectedGame = rowNumber;

	//Update the settings tabs accordingly.
	{
		EXCOSCSettingsComponent *oscSettings(dynamic_cast<EXCOSCSettingsComponent *>(optionsTabs->getTabContentComponent(0)));
		CommandLineSettingsComponent *commandLine(dynamic_cast<CommandLineSettingsComponent *>(optionsTabs->getTabContentComponent(1)));

		if(oscSettings)
		{
			oscSettings->setListenPort(settings[selectedGame]->listenPort);
			oscSettings->setSendAddress(settings[selectedGame]->sendAddress);
			oscSettings->setSendPort(settings[selectedGame]->sendPort);
			oscSettings->setAddPortsToPatcher(settings[selectedGame]->addPortsToPatcher);
		}
		if(commandLine)
			commandLine->setCommandLineArgs(settings[selectedGame]->commandLine);
	}

	repaint();
}

//------------------------------------------------------------------------------
void GameListPanel::cellDoubleClicked(int rowNumber,
                                      int columnId,
                                      const MouseEvent &e)
{
    if(gameList->getSelectedRow() > -1)
        launchSelectedGame();
}

//------------------------------------------------------------------------------
void GameListPanel::launchSelectedGame()
{
    int selected(gameList->getSelectedRow());
    const OwnedArray<MainContentComponent::GameDetails>& games(mainComponent.getGames());

    if(selected > -1)
    {
        String args;

        if(optionsTabs->getCurrentTabIndex() == 0)
        {
            EXCOSCSettingsComponent *settings(dynamic_cast<EXCOSCSettingsComponent *>(optionsTabs->getTabContentComponent(0)));

            if(settings)
            {
                args << "-lp " << settings->getListenPort();
                args << " -sa " << settings->getSendAddress();
                args << " -sp " << settings->getSendPort();

				if(settings->getAddPortsToPatcher())
				{
					mainComponent.addGameToPatcher(games[selected]->name,
												   settings->getListenPort(),
												   settings->getSendAddress(),
												   settings->getSendPort());
				}
            }
        }
        else
        {
			CommandLineSettingsComponent *settings(dynamic_cast<CommandLineSettingsComponent *>(optionsTabs->getTabContentComponent(1)));

			if(settings)
				args << settings->getCommandLineArgs();
        }

        games[selected]->executable.startAsProcess(args);
    }
}

//[/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="GameListPanel" componentName=""
                 parentClasses="public Component, public TableListBoxModel, public ChangeListener"
                 constructorParams="MainContentComponent&amp; mainComp" variableInitialisers="mainComponent(mainComp),&#10;screenshot(nullptr)"
                 snapPixels="8" snapActive="1" snapShown="1" overlayOpacity="0.330000013"
                 fixedSize="0" initialWidth="600" initialHeight="400">
  <BACKGROUND backgroundColour="ffeeece1"/>
  <GENERICCOMPONENT name="gameList" id="d1f74c8f872f3f38" memberName="gameList" virtualName=""
                    explicitFocusOrder="0" pos="8 8 152M 126M" class="TableListBox"
                    params="&quot;gameList&quot;, this"/>
  <LABEL name="gameNameLabel" id="576a176a82505ddb" memberName="gameNameLabel"
         virtualName="" explicitFocusOrder="0" pos="136R 120 128 24" edTextCol="ff000000"
         edBkgCol="0" labelText="Game Name" editableSingleClick="0" editableDoubleClick="0"
         focusDiscardsChanges="0" fontname="Default font" fontsize="15"
         bold="1" italic="0" justification="36"/>
  <LABEL name="gameAuthorLabel" id="882b73f9ae77445b" memberName="gameAuthorLabel"
         virtualName="" explicitFocusOrder="0" pos="136R 144 128 24" edTextCol="ff000000"
         edBkgCol="0" labelText="Game Author(s)" editableSingleClick="0"
         editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font"
         fontsize="15" bold="0" italic="1" justification="36"/>
  <LABEL name="gameDescLabel" id="26cc33d8ef6de53f" memberName="gameDescLabel"
         virtualName="" explicitFocusOrder="0" pos="136R 168 128 286M"
         edTextCol="ff000000" edBkgCol="0" labelText="Game Description"
         editableSingleClick="0" editableDoubleClick="0" focusDiscardsChanges="0"
         fontname="Default font" fontsize="15" bold="0" italic="0" justification="9"/>
  <TEXTBUTTON name="launchGameButton" id="e4cdb48d7dcffa86" memberName="launchGameButton"
              virtualName="" explicitFocusOrder="0" pos="136R 110R 128 102"
              buttonText="Launch Game" connectedEdges="0" needsCallback="1"
              radioGroupId="0"/>
  <TABBEDCOMPONENT name="optionsTabs" id="6ceb5593907e0503" memberName="optionsTabs"
                   virtualName="" explicitFocusOrder="0" pos="8 110R 152M 102" orientation="top"
                   tabBarDepth="30" initialTab="0">
    <TAB name="OSC Settings" colour="ffeeece1" useJucerComp="1" contentClassName=""
         constructorParams="" jucerComponentFile="EXCOSCSettingsComponent.cpp"/>
    <TAB name="Command Line" colour="ffeeece1" useJucerComp="1" contentClassName=""
         constructorParams="" jucerComponentFile="CommandLineSettingsComponent.cpp"/>
  </TABBEDCOMPONENT>
</JUCER_COMPONENT>

END_JUCER_METADATA
*/
#endif


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