/** \file IFStatus.cc
 * \author Gabriel Montenegro <gmontenegro@users.sourceforge.net>
 * \date 10-14-04
 * \brief IFStatus class implementation
 *
 * Class implementation
 */

/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "Main.h"
#include "IFStatus.h"
#include "Graph.h"
#include "Config.h"
#include "Curses.h"
#include "Window.h"
#include "Display.h"
#include "Interfaces.h"
#include "InfoDisplay.h"
#include "GraphDecorator.h"
#include "BorderDecorator.h"

IFStatus::IFStatus()
{
	m_pConfig = Config::Instance();
	m_pDisplay = new BorderDecorator(new GraphDecorator(new InfoDisplay));

	m_iLastHeight = Window::ScreenLines();
	m_iLastWidth = Window::ScreenColumns();
}

IFStatus::~IFStatus()
{
	Finalize();
}

void IFStatus::Initialize(void)
{
	m_pConfig->Load();

	m_cInterfaces.Load();
}

void IFStatus::Finalize(void)
{
	m_pConfig->Save();
}

bool IFStatus::KeyboardOptions(void)
{
	int iWidth = Window::ScreenColumns();
	int iHeight = Window::ScreenLines();
	bool bChanged = false;
	bool bReturn = true;
	char cKey = getch();

	if(iWidth != m_iLastWidth || iHeight != m_iLastHeight)
	{
		bChanged = true;

		m_iLastHeight = iHeight;
		m_iLastWidth = iWidth;
	}

	if(cKey != ERR)
	{
		switch(cKey)
		{
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
			case '0':
			{
				int iTurnActive = (cKey > 48) ? cKey -  48 : 0;

				if(m_cInterfaces.setActive(iTurnActive))
					bChanged = true;
			}


				break;

			case 'i':
			case 'I':

				if(m_pConfig->getValue("Information") == "On")
					m_pConfig->setValue("Information", "Off");
				else
					m_pConfig->setValue("Information", "On");

				bChanged = true;

				break;

			case 's':
			case 'S':

				if(m_pConfig->getValue("GraphScale") == "On")
					m_pConfig->setValue("GraphScale", "Off");
				else
					m_pConfig->setValue("GraphScale", "On");

				bChanged = true;

				break;

			case 'g':
			case 'G':
			{
				string strType = m_pConfig->getValue("GraphSource");

				if(strType == "In")
					m_pConfig->setValue("GraphSource", "Out");
				else if(strType == "Out")
					m_pConfig->setValue("GraphSource", "In/Out");
				else
					m_pConfig->setValue("GraphSource", "In");

			}
				bChanged = true;

				break;

			case '+':
			{
				char cPeriod[8];
				unsigned int uiGraphPeriod = atoi((m_pConfig->getValue("GraphPeriod")).c_str());

				if(uiGraphPeriod < 60)
				{
					if( uiGraphPeriod >= 30)
						uiGraphPeriod += 30;
					else if( uiGraphPeriod >= 15)
						uiGraphPeriod += 15;
					else if( uiGraphPeriod >= 5)
						uiGraphPeriod += 5;
					else
						uiGraphPeriod++;

					sprintf(cPeriod, "%d", uiGraphPeriod);

					m_pConfig->setValue("GraphPeriod", cPeriod);

					bChanged = true;
				}
			}

				break;

			case '-':
			{
				char cPeriod[8];
				unsigned int uiGraphPeriod = atoi((m_pConfig->getValue("GraphPeriod")).c_str());

				if(uiGraphPeriod > 1)
				{
					if( uiGraphPeriod >= 60)
						uiGraphPeriod -= 30;
					else if( uiGraphPeriod >= 30)
						uiGraphPeriod -= 15;
					else if( uiGraphPeriod >= 10)
						uiGraphPeriod -= 5;
					else
						uiGraphPeriod--;

					sprintf(cPeriod, "%d", uiGraphPeriod);

					m_pConfig->setValue("GraphPeriod", cPeriod);

					bChanged = true;
				}
			}

				break;

			case 'h':
			case 'H':

				if(m_pConfig->getValue("Help") == "On")
					m_pConfig->setValue("Help", "Off");
				else
					m_pConfig->setValue("Help", "On");

				bChanged = true;

				break;

			case 'r':
			case 'R':

				bChanged = true;

				break;

			case 'q':
			case 'Q':

				bReturn = false;

				break;

			default:

				break;
		}
	}

	if(bChanged)
	{
		m_cInterfaces.getActive().getWindow()->Clear();
		m_pDisplay->Draw(m_cInterfaces, true);
	}

	return bReturn;
}

void IFStatus::Start(void)
{
	Config * pConfig = Config::Instance();
	bool bLoop = true;
	time_t tLast = 0, tNow;
	int iGraphPeriod;

	m_cInterfaces.Load();

	if(!m_cInterfaces.getCount())
		return;

	while(bLoop)
	{
		time(&tNow);

		if(tLast + 1 <= tNow)
		{
			m_cInterfaces.CheckState();
		  m_cInterfaces.UpdateData();
			m_cInterfaces.CompileData();

			tLast = tNow;
		}

		m_pDisplay->Draw(m_cInterfaces);

		bLoop = KeyboardOptions();

		usleep(100000L);
	}
}
