#include <QtGui>

#include "fcan_view.h"

#include "initfile.h"
#include "hardware.h"
#include "rxdata.h"
#include "txdata.h"
#include "rxdataformat.h"
#include "rxdatafilter.h"
#include "graph.h"
#include "plotter.h"
#include "information.h"
#include "SysConfig.h"
#include "CanData.h"
#include "CanFrame.h"

class Ui_Information;

////////////////////////////////////////
// For Startup
////////////////////////////////////////
FCAN_View::FCAN_View(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	ui.setupUi(this);

	pSysConfig = NULL;
	pFcanView = NULL;
	pInitFile = NULL;
	pHardware = NULL;
	pRxData = NULL;
	pTxData = NULL;
	pRxDataFormat = NULL;
	pRxDataFilter = NULL;
	for( int i=0; i<10; ++i ){
		pGraph[i] = NULL;
		pPlotter[i] = NULL;
		pPlotSettings[i] = NULL;
	}
	pInformation = NULL;
	pCanData = NULL;
	pCanDataMng = NULL;
	pCanFrame = NULL;

	StdCobIDBitOffset = 8;
	StdCobIDBitLength = 4;
	StdCobIDMask = 0x00000780;
	StdNodeIDBitOffset = 0;
	StdNodeIDBitLength = 7;
	StdNodeIDMask = 0x0000007F;
	ExtCobIDBitOffset = 26;
	ExtCobIDBitLength = 4;
	ExtCobIDMask = 0x1E000000;
	ExtNodeIDBitOffset = 0;
	ExtNodeIDBitLength = 25;
	ExtNodeIDMask = 0x01FFFFFF;


}
FCAN_View::~FCAN_View()
{
}
////////////////////////////////////////
// Pointer Setting
////////////////////////////////////////
void FCAN_View::SysConfigSet( SysConfig * sysconfig )
{
	pSysConfig = sysconfig;
}
void FCAN_View::FcanViewSet( FCAN_View * fcanview )
{
	pFcanView = fcanview;
}
void FCAN_View::InitFileSet( InitFile * initfile )
{
	pInitFile = initfile;
}
void FCAN_View::HardwareSet( Hardware * hardware )
{
	pHardware = hardware;
}
void FCAN_View::RxDataSet( RxData * rxdata )
{
	pRxData = rxdata;
}
void FCAN_View::TxDataSet( TxData * txdata )
{
	pTxData = txdata;
}
void FCAN_View::RxDataFormatSet( RxDataFormat * rxdataformat )
{
	pRxDataFormat = rxdataformat;
}
void FCAN_View::RxDataFilterSet( RxDataFilter * rxdatafilter )
{
	pRxDataFilter = rxdatafilter;
}
void FCAN_View::GraphSet( Graph * graph )
{
	pGraph[GraphNumber] = graph;
}
void FCAN_View::PlotterSet( Plotter * plotter )
{
	pPlotter[GraphNumber] = plotter;
}
void FCAN_View::PlotSettingsSet( PlotSettings * plotsettings )
{
	pPlotSettings[GraphNumber] = plotsettings;
}
void FCAN_View::InformationSet( Information * information )
{
	pInformation = information;
}
void FCAN_View::CanDataSet( CanData * candata )
{
	pCanData = candata;
}
void FCAN_View::CanDataMngSet( CanDataMng * candatamng )
{
	pCanDataMng = candatamng;
}
void FCAN_View::CanFrameSet( CanFrame * canframe )
{
	pCanFrame = canframe;
}
////////////////////////////////////////
// Close
////////////////////////////////////////
void FCAN_View::closeEvent(QCloseEvent * pEvent)
{
	// All Window Closed
    workspace->closeAllWindows();

	close();
}
////////////////////////////////////////
// Plotter View
////////////////////////////////////////
void FCAN_View::HardwareView(int mode)
{
	if( ViewWindow[1] == false ){
		ViewWindow[1] = true;
		Hardware * wHardware = new Hardware();
		workspace->addWindow(wHardware);
		if( mode == 1 ){
			wHardware->setWindowState(windowState() ^ Qt::WindowMinimized); 
		}
		HardwareSet(wHardware);
		ViewAdd();
	}
	pHardware->show();
	if( mode == 0 ){
		workspace->setActiveWindow(pHardware);
	}
}
void FCAN_View::RxDataFilterView(int mode)
{
	if( ViewWindow[5] == false ){
		ViewWindow[5] = true;
		RxDataFilter * wRxDataFilter = new RxDataFilter();
		workspace->addWindow(wRxDataFilter);
		if( mode == 1 ){
			wRxDataFilter->setWindowState(windowState() ^ Qt::WindowMinimized); 
		}
		RxDataFilterSet(wRxDataFilter);
		ViewAdd();
	}
	pRxDataFilter->show();
	if( mode == 0 ){
		workspace->setActiveWindow(pRxDataFilter);
	}
}
void FCAN_View::RxDataFormatView(int mode)
{
	if( ViewWindow[4] == false ){
		ViewWindow[4] = true;
		RxDataFormat * wRxDataFormat = new RxDataFormat();
		workspace->addWindow(wRxDataFormat);
		if( mode == 1 ){
			wRxDataFormat->setWindowState(windowState() ^ Qt::WindowMinimized); 
		}
		RxDataFormatSet(wRxDataFormat);
		ViewAdd();
	}
	pRxDataFormat->show();
	if( mode == 0 ){
		workspace->setActiveWindow(pRxDataFormat);
	}
	pRxDataFormat->ViewFormat();
}
void FCAN_View::RxDataView(int mode)
{
	if( ViewWindow[2] == false ){
		ViewWindow[2] = true;
		RxData * wRxData = new RxData();
		workspace->addWindow(wRxData);
		if( mode == 1 ){
			wRxData->setWindowState(windowState() ^ Qt::WindowMinimized); 
		}
		RxDataSet(wRxData);
		ViewAdd();
	}
	pRxData->show();
	if( mode == 0 ){
		workspace->setActiveWindow(pRxData);
	}
}
void FCAN_View::TxDataView(int mode)
{
	if( ViewWindow[3] == false ){
		ViewWindow[3] = true;
		TxData * wTxData = new TxData();
		workspace->addWindow(wTxData);
		if( mode == 1 ){
			wTxData->setWindowState(windowState() ^ Qt::WindowMinimized); 
		}
		TxDataSet(wTxData);
		ViewAdd();
	}
	pTxData->show();
	if( mode == 0 ){
		workspace->setActiveWindow(pTxData);
	}
}
void FCAN_View::GraphView(int mode)
{
	if( ViewGraphCount < 10 ){
		for(int i = 0; i < 10; ++i ){
			if( ViewGraph[i] == false ){
				GraphNumber = i;
				ViewGraph[i] = true;
				break;
			}
		}
		Graph * wGraph = new Graph();
		workspace->addWindow(wGraph);
//		if( mode == 1 ){
//			wGraph->setWindowState(windowState() ^ Qt::WindowMinimized); 
//		}
		GraphSet(wGraph);
		pGraph[GraphNumber]->GraphNumberSet(GraphNumber);
		PlotterView(mode);
		ViewGraphCount = ViewGraphCount + 1;
	}
}
void FCAN_View::GraphViewShow(int no)
{
	pGraph[no]->show();
	workspace->setActiveWindow(pGraph[no]);
}
void FCAN_View::GraphViewClose(int no)
{
//	pGraph[no] = NULL;
	ViewGraph[no] = false;
	ViewGraphCount = ViewGraphCount - 1;
}
void FCAN_View::PlotterView(int mode)
{
	if( ViewGraphCount < 10 ){
		Plotter * wPlotter = new Plotter();
		PlotSettings * wPlotSettings = new PlotSettings();
		workspace->addWindow(wPlotter);
		if( mode == 1 ){
			wPlotter->setWindowState(windowState() ^ Qt::WindowMinimized); 
		}
		wPlotter->show();
		PlotterSet(wPlotter);
		PlotSettingsSet(wPlotSettings);
		ViewAdd();
	}
}
////////////////////////////////////////
// Function
////////////////////////////////////////
void FCAN_View::Start( )
{
	// Window Flag Init
	int i;
	for(i=0; i<10; ++i){
		ViewWindow[i] = false;
		ViewGraph[i] = false;
	}
	ViewGraphCount = 0;
	GraphNumber = 0;

	// Window Init
	workspace = new QWorkspace;
	setCentralWidget(workspace);
	setWindowTitle(tr("FCAN-View"));

	// Menu Init
	createMenus();

	// StatusBar Init
	statusBarLabel = new QLabel("FCAN_View");
	statusBarLabel->setMinimumSize(statusBarLabel->sizeHint());
	ui.statusBar->addWidget(statusBarLabel);

	// Information Widget Open
	Information * wInformation = new Information();
	workspace->addWindow(wInformation);
	wInformation->show();
	InformationSet(wInformation);
	ViewAdd();
	ViewWindow[6] = true;

	update();
	show();

}
////////////////////////////////////////
// Menu Action
////////////////////////////////////////
void FCAN_View::menu_triggered()
{
	createMenuActions();
}
void FCAN_View::menu_initfile()
{
	if( ViewWindow[0] == false ){
		ViewWindow[0] = true;
		InitFile * wInitFile = new InitFile();
		workspace->addWindow(wInitFile);
		InitFileSet(wInitFile);
		ViewAdd();
	}
	pInitFile->show();
	workspace->setActiveWindow(pInitFile);
}
void FCAN_View::menu_hardware()
{
	HardwareView(0);
}
void FCAN_View::menu_rxdata()
{
	RxDataView(0);
}
void FCAN_View::menu_txdata()
{
	TxDataView(0);
}
void FCAN_View::menu_rxdataformat()
{
	RxDataFormatView(0);
}
void FCAN_View::menu_rxdatafilter()
{
	RxDataFilterView(0);
}
void FCAN_View::menu_graph0()
{
	pPlotter[0]->show();
	workspace->setActiveWindow(pPlotter[0]);
}
void FCAN_View::menu_graph1()
{
	pPlotter[1]->show();
	workspace->setActiveWindow(pPlotter[1]);
}
void FCAN_View::menu_graph2()
{
	pPlotter[2]->show();
	workspace->setActiveWindow(pPlotter[2]);
}
void FCAN_View::menu_graph3()
{
	pPlotter[3]->show();
	workspace->setActiveWindow(pPlotter[3]);
}
void FCAN_View::menu_graph4()
{
	pPlotter[4]->show();
	workspace->setActiveWindow(pPlotter[4]);
}
void FCAN_View::menu_graph5()
{
	pPlotter[5]->show();
	workspace->setActiveWindow(pPlotter[5]);
}
void FCAN_View::menu_graph6()
{
	pPlotter[6]->show();
	workspace->setActiveWindow(pPlotter[6]);
}
void FCAN_View::menu_graph7()
{
	pPlotter[7]->show();
	workspace->setActiveWindow(pPlotter[7]);
}
void FCAN_View::menu_graph8()
{
	pPlotter[8]->show();
	workspace->setActiveWindow(pPlotter[8]);
}
void FCAN_View::menu_graph9()
{
	pPlotter[9]->show();
	workspace->setActiveWindow(pPlotter[9]);
}
void FCAN_View::menu_newgraph()
{
	GraphView(0);
}
void FCAN_View::menu_information()
{
	if( ViewWindow[6] == false ){
		ViewWindow[6] = true;
		Information * wInformation = new Information();
		workspace->addWindow(wInformation);
		InformationSet(wInformation);
		ViewAdd();
	}
	pInformation->show();
	workspace->setActiveWindow(pInformation);

}
void FCAN_View::menu_close()
{
	// All Window Closed
    workspace->closeAllWindows();

	close();
}
////////////////////////////////////////
// View Add
////////////////////////////////////////
void FCAN_View::ViewAdd()
{
	// Information
	pInformation->FcanViewSet(this);
	// InitFile
	pInitFile->HardwareSet(pHardware);
	pInitFile->RxDataFilterSet(pRxDataFilter);
	pInitFile->RxDataFormatSet(pRxDataFormat);
	pInitFile->TxDataSet(pTxData);
	pInitFile->InformationSet(pInformation);
	pInitFile->FcanViewSet(this);
	// Hardware
	pHardware->InformationSet(pInformation);
	pHardware->FcanViewSet(this);
	// RxData
	pRxData->SysConfigSet(pSysConfig);
	pRxData->HardwareSet(pHardware);
	pRxData->RxDataFilterSet(pRxDataFilter);
	pRxData->InformationSet(pInformation);
	pRxData->CanDataSet(pCanData);
	pRxData->CanDataMngSet(pCanDataMng);
	pRxData->FcanViewSet(this);
	// TxData
	pTxData->HardwareSet(pHardware);
	pTxData->InformationSet(pInformation);
	pTxData->FcanViewSet(this);
	// RxDataFormat
	pRxDataFormat->CanFrameSet(pCanFrame);
	pRxDataFormat->InformationSet(pInformation);
	pRxDataFormat->FcanViewSet(this);
	// RxDataFilter
	pRxDataFilter->HardwareSet(pHardware);
	pRxDataFilter->InformationSet(pInformation);
	pRxDataFilter->FcanViewSet(this);
	// Graph
	pGraph[GraphNumber]->SysConfigSet(pSysConfig);
	pGraph[GraphNumber]->RxDataFormatSet(pRxDataFormat);
	pGraph[GraphNumber]->CanFrameSet(pCanFrame);
	pGraph[GraphNumber]->CanDataSet(pCanData);
	pGraph[GraphNumber]->CanDataMngSet(pCanDataMng);
	pGraph[GraphNumber]->PlotterSet(pPlotter[GraphNumber]);
	pGraph[GraphNumber]->PlotSettingsSet(pPlotSettings[GraphNumber]);
	pGraph[GraphNumber]->InformationSet(pInformation);
	pGraph[GraphNumber]->FcanViewSet(this);
	// Plotter
	pPlotter[GraphNumber]->FcanViewSet(this);
	pPlotter[GraphNumber]->GraphSet(pGraph[GraphNumber]);
	pPlotter[GraphNumber]->PlotSettingsSet(pPlotSettings[GraphNumber]);
}

////////////////////////////////////////
// Setting Menu
////////////////////////////////////////
void FCAN_View::createMenus()
{
	QMenu   * pMenu;

	//File Menu
	pMenu = menuBar()->addMenu( tr("Setting") );
	SettingMenu.pMenu = pMenu;
    connect(pMenu, SIGNAL(aboutToShow()), this, SLOT(menu_triggered()));

	createMenuActions();

}
void FCAN_View::createMenuActions()
{
	QMenu   * pMenuGraphSub;
	QAction * pAction;
	QString qt_str;

	/* Clear */
	SettingMenu.pMenu->clear( );
	
	/* File */
	pAction = new QAction( tr("File"), this );
	pAction->setShortcut(tr("Ctrl+F"));
	SettingMenu.pFileAction = pAction;
	SettingMenu.pMenu->addAction( pAction );
    connect(pAction, SIGNAL(triggered()), this, SLOT(menu_initfile()));

	/* Hardware */
	pAction = new QAction( tr("Hardware"), this );
	pAction->setShortcut(tr("Ctrl+H"));
	SettingMenu.pHardwareAction = pAction;
	SettingMenu.pMenu->addAction( pAction );
    connect(pAction, SIGNAL(triggered()), this, SLOT(menu_hardware()));

	/* Read Messages */
	pAction = new QAction( tr("Read Messages"), this );
	pAction->setShortcut(tr("Ctrl+R"));
	SettingMenu.pRxDataAction = pAction;
	SettingMenu.pMenu->addAction( pAction );
    connect(pAction, SIGNAL(triggered()), this, SLOT(menu_rxdata()));

	/* Write Messages */
	pAction = new QAction( tr("Write Messages"), this );
	pAction->setShortcut(tr("Ctrl+T"));
	SettingMenu.pTxDataAction = pAction;
	SettingMenu.pMenu->addAction( pAction );
    connect(pAction, SIGNAL(triggered()), this, SLOT(menu_txdata()));

	/* Read Data Format */
	pAction = new QAction( tr("Read Message Format"), this );
	pAction->setShortcut(tr("Ctrl+M"));
	SettingMenu.pRxDataFormatAction = pAction;
	SettingMenu.pMenu->addAction( pAction );
    connect(pAction, SIGNAL(triggered()), this, SLOT(menu_rxdataformat()));

	/* Read Data Filter */
	pAction = new QAction( tr("Read Message Filter"), this );
	pAction->setShortcut(tr("Ctrl+L"));
	SettingMenu.pRxDataFilterAction = pAction;
	SettingMenu.pMenu->addAction( pAction );
    connect(pAction, SIGNAL(triggered()), this, SLOT(menu_rxdatafilter()));

	/* GraphNew */
	pAction = new QAction( tr("NewGraph"), this );
	pAction->setShortcut(tr("Ctrl+N"));
	SettingMenu.pNewGraphAction = pAction;
	SettingMenu.pMenu->addAction( pAction );
    connect(pAction, SIGNAL(triggered()), this, SLOT(menu_newgraph()));

	/* Graph */
	if( ViewGraphCount > 0 ){
		pMenuGraphSub = SettingMenu.pMenu->addMenu( tr("Graph") );
		for(int i = 0; i < 10; ++i ){
			if( ViewGraph[i] == true ){
				qt_str.sprintf("%d ", i+1);
				qt_str = qt_str + pGraph[i]->GraphName;
				pAction = new QAction( qt_str, this );
				pMenuGraphSub->addAction( pAction );
				if( i == 0 ){ connect(pAction, SIGNAL(triggered()), this, SLOT(menu_graph0())); }
				if( i == 1 ){ connect(pAction, SIGNAL(triggered()), this, SLOT(menu_graph1())); }
				if( i == 2 ){ connect(pAction, SIGNAL(triggered()), this, SLOT(menu_graph2())); }
				if( i == 3 ){ connect(pAction, SIGNAL(triggered()), this, SLOT(menu_graph3())); }
				if( i == 4 ){ connect(pAction, SIGNAL(triggered()), this, SLOT(menu_graph4())); }
				if( i == 5 ){ connect(pAction, SIGNAL(triggered()), this, SLOT(menu_graph5())); }
				if( i == 6 ){ connect(pAction, SIGNAL(triggered()), this, SLOT(menu_graph6())); }
				if( i == 7 ){ connect(pAction, SIGNAL(triggered()), this, SLOT(menu_graph7())); }
				if( i == 8 ){ connect(pAction, SIGNAL(triggered()), this, SLOT(menu_graph8())); }
				if( i == 9 ){ connect(pAction, SIGNAL(triggered()), this, SLOT(menu_graph9())); }
			}
		}
	}

	/* Information */
	pAction = new QAction( tr("Information"), this );
	pAction->setShortcut(tr("Ctrl+I"));
	SettingMenu.pInformation = pAction;
	SettingMenu.pMenu->addAction( pAction );
    connect(pAction, SIGNAL(triggered()), this, SLOT(menu_information()));

	/* Exit */
	pAction = new QAction( tr("Exit"), this );
	pAction->setShortcut(tr("Ctrl+E"));
	SettingMenu.pExitAction = pAction;
	SettingMenu.pMenu->addAction( pAction );
    connect(pAction, SIGNAL(triggered()), this, SLOT(menu_close()));

}

////////////////////////////////////////
// HardwareSetting Info
////////////////////////////////////////
void FCAN_View::HardwareSetting(QString qstr)
{
	HardwareInfo = qstr;
}
////////////////////////////////////////
// Graph Init
////////////////////////////////////////
QString FCAN_View::GraphInit(int no, int mode, QString line)
{
	QString qt_ret;

	if( pGraph[no] == NULL || ViewGraph[no] == false ){
		qt_ret = "#### Not Open Graph Window ####\n";
	} else {
		qt_ret = pGraph[no]->GraphInit(mode,line);
	}

	return qt_ret;

}
////////////////////////////////////////
// StatusBar Setting
////////////////////////////////////////
void FCAN_View::statusBar_message(QString info)
{
	QString qstr;
	qstr = HardwareInfo + info;
	statusBarLabel->setText(qstr);
	statusBarLabel->setMinimumSize(statusBarLabel->sizeHint());

}
void FCAN_View::statusBar_clear( )
{
	statusBarLabel->setText("");
	statusBarLabel->setMinimumSize(statusBarLabel->sizeHint());
}

