/*
 *      iowin.cpp
 *
 *      Copyright 2009 salvi <salvi@asus>
 *
 *      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 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., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */
#include <curses.h>
#include "displaylcd.h"
#include "hc08gpioport.h"
#include "iowin.h"
/*
 *  DISPLAY:
 *  DB4       15          PTB0
 *  DB5       14          PTB1
 *  DB6       11          PTB2
 *  DB7       10          PTB3
 *
 *  EN_LCD    3           PTB6                LED Verde
 *  RS_LCD    5           PTA4/OSC2/AD2/KBI4  LED Giallo
 * 
 *  PTB7        S5
 * 
 * 
 */

// Indirizzi dei registri
#define CONFIG2 0x1e
#define CONFIG1 0x1f


class PTALCDout: public OutputConnector {
  private:
	DisplayLCD *display;
  public:
	PTALCDout (DisplayLCD *disp): OutputConnector(YELLOWLED) { display = disp; };
	virtual void out(unsigned char v) { /* Log::printf("PTALCDout::OutputConnector - out %x", v & YELLOWLED); */ display->setRs(v & YELLOWLED); value = v; };
};


class PTBLCDout: public OutputConnector {
  private:
	DisplayLCD *display;
  public:
	PTBLCDout (DisplayLCD *disp): OutputConnector(GREENLED | BUSLEDS) { display = disp; };
	virtual void out(unsigned char v) { /* Log::printf("PTBLCDout::OutputConnector - out %x", v & (GREENLED | BUSLEDS)); */ display->setBus((v << 4) & 0xf0); display->setEn(v & GREENLED); value = v; };
};


IoWin::IoWin (int x, int y, int w, int h, const char *titolo, Debug *dbg) :HcWindow(x, y, w, h, titolo, dbg) {
	display = new DisplayLCD();
	ptaLED = new PTALEDout();
	GpIoPort *ptb = new GpIoPort (PTB);
	ptbKey = new InputConnector(0, S5PIN);
	ptbLED = new PTBLEDout(ptbKey, ptb);
	GpIoPort *pta = new GpIoPort (PTA);
	pta->addOutput (ptaLED);
	pta->addOutput (new PTALCDout(display));
	// 	PTAport(display);
	ptb->addOutput (ptbLED);
	ptb->addOutput (new PTBLCDout(display));
	ptb->addInput (ptbKey);
	// PTBport(display);
	dbg->addPort (pta);
	dbg->addPort (ptb);
	dbg->addPort (new IoPort(CONFIG2));
	dbg->addPort (new IoPort(CONFIG1));
	refresh (); 
}

void IoWin::KeyToggle() {
	// Log::printf("IoWin::KeyToggle(): old %02x mask %02x new %02x", ptbKey->getValue (), S5PIN, ptbKey->getValue () ^ S5PIN);
	ptbKey->setValue (ptbKey->getValue () ^ S5PIN);
	ptbLED->refresh(win);
	wrefresh (win);
}

#define LINELEN   8
#define LINMASK   0xfff8
void IoWin::refresh () {
	ptaLED->refresh(win);
	ptbLED->refresh(win);
	display->refresh(win);
	wrefresh (win);
}

void PTALEDout::refresh (WINDOW *win) {
	wcolor_set(win, COLOR_YELLOWLED, NULL);
	mvwprintw (win, 1, 5, "%c", (value & YELLOWLED) ? '*' : 'O');	
	wcolor_set(win, COLOR_NORMAL, NULL);
}

void PTBLEDout::refresh (WINDOW *win) {
	char leds[]="OOOOOOOO";
	int i;
	int ledMask;
	// unsigned char v = value & ddr;
	unsigned char v = value;
	for (i = 4, ledMask = 0x8; i < 8; i++, ledMask /= 2) {
		leds[i] = (v & ledMask) ? '*' : 'O';
	}
	wcolor_set(win, COLOR_GREENLED, NULL);
	mvwprintw (win, 1, 3, "%c", (v & GREENLED) ? '*' : 'O');
	wcolor_set(win, COLOR_REDLED, NULL);
	mvwprintw (win, 1, 7, leds);
	wcolor_set(win, COLOR_NORMAL, NULL);
	// v |= pue;

	// char key = (keyState) ? (!(ddr & S5PIN) ? ((pue & S5PIN) ? '*' : '-') : '_') : ' ';
	mvwprintw (win, 2, 4, "Tasto: [%c]", 
	           (port->getDDR() & S5PIN) ? 
	       			((in->getValue() & S5PIN) ? 
				        ((port->getVal() & S5PIN) ? 'H' : 'L') : ((port->getVal() & S5PIN) ? 'X' : 'L'))
	       			: (((in->getValue() & S5PIN) ? ((port->getPUE() & S5PIN) ? '*' : '-') : ' ')));
}


