//
//  s95160_t2.c		Touch screen part, layer 2 (LCM Coordinate convert)
//  Graphic LCD module "SUCCESS ELECTRONIC S95160" I/O library
//  Copyright(C)2013-2018 Toyohiko Togashi tog001@nifty.com
//
//
//  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 3
//  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, see <http://www.gnu.org/licenses/>
//
//
//    Update history
//    ---------- ----- -------------------------------------------
//    2013.01.24 v0.0  First cording
//    2014.03.15 v0.2  Rename source file: s95160_t2.c -> s95160_t2.c + lcd_touch.c
//    2018.01.19 v0.3  Supported a LCD_UPSIDE_DOWN_MODE
//

#include <stddef.h>
#include "lcd_touch.h"					// API
#include "lcd_draw.h"					// LCM info
#include "s95160_t1.h"

//
//	Configuration parameter
//
#define LCD_TOUCH_CALIBRATE		20			// [%]

//
// Global area
//
struct {
	unsigned char	openFlag;				// 1:open
	short			offsetX;				// [ADC count]
	short			offsetY;				// [ADC count]
	short			convRateX;				// [ADC count/Pixel] x10
	short			convRateY;				// [ADC count/Pixel] x10
	short			forceEffectRateX;		// x1000
	short			forceEffectRateY;		// x1000
	short			leftUpForce;			// [ADC count]
}	lcd_touch = {
//		0,
//		0,
//		0,
//		ADC_RESOLUTION * 10 / LCD_SCREEN_WIDTH,
//		ADC_RESOLUTION * 10 / LCD_SCREEN_HEIGHT,
//		0,
//		0,
//		0
//		Sample default
		0,
		 452, 226,
		 134, 107,
		-290, 354,
		0
};

//
// Open
//
void lcd_touchOpen(void) {
	lcd_tpStart();
	lcd_touch.openFlag = 1;
	return;
}

//
// Get touch point
//
short lcd_touchPoint(short *px, short *py) {
	short	p[3];
	int		x,y;
	short	f;

	// Hide open
	if (lcd_touch.openFlag == 0) {
		lcd_tpStart();
		lcd_touch.openFlag = 1;
	}

	// Get touch screen point
	lcd_tpGetXYZ(p);

	// Push force adjust
	f = (p[2] - (p[0] * lcd_touch.forceEffectRateX / 1000) - (p[1] * lcd_touch.forceEffectRateY / 1000)) * 100 / ADC_RESOLUTION;

	// Coordinate convert and adjust
	if ((px != NULL) && (py != NULL)) {
		x = (p[0] - lcd_touch.offsetX) * 10 / lcd_touch.convRateX;
		y = (p[1] - lcd_touch.offsetY) * 10 / lcd_touch.convRateY;

#ifdef LCD_LANDSCAPE_MODE
		{
			int	s;

			s = x;
			x = y;
			y = LCD_SCREEN_HEIGHT - s - 1;
		}
#endif
#ifdef LCD_UPSIDE_DOWN_MODE				// ADD START 2018.01.19
		x = LCD_SCREEN_WIDTH  - x;		// ADD START 2018.01.19
		y = LCD_SCREEN_HEIGHT - y;		// ADD START 2018.01.19
#endif									// ADD START 2018.01.19

		// Limit check
		if (x < 0) {
			x = 0;
		}
		if (x > (LCD_SCREEN_WIDTH - 1)) {
			x = (LCD_SCREEN_WIDTH - 1);
		}
		if (y < 0) {
			y = 0;
		}
		if (y > (LCD_SCREEN_HEIGHT - 1)) {
			y = (LCD_SCREEN_HEIGHT - 1);
		}

		*px = x;
		*py = y;
	}

	return(f);
}

//
// Calibrate		(Need push the corner point)
//
void lcd_touchCalibrate(void) {
	short	p[3];

	// Hide open
	if (lcd_touch.openFlag == 0) {
		lcd_tpStart();
		lcd_touch.openFlag = 1;
	}

	// Get touch screen point
	lcd_tpGetXYZ(p);
	if (p[2] > 0) {

#define C0	(short)((long)ADC_RESOLUTION * (long)LCD_TOUCH_CALIBRATE / 100L)
#define C1	(ADC_RESOLUTION - C0)

		// Left side
		if (p[0] < C0) {
			lcd_touch.offsetX = p[0];
		}

		// Up side
		if (p[1] < C0) {
			lcd_touch.offsetY = p[1];
		}

		// Right side
		if (p[0] > C1) {					// Pixel size X
			lcd_touch.convRateX = (p[0] - lcd_touch.offsetX) * 10 / LCD_SCREEN_WIDTH;
		}

		// Right side
		if (p[1] > C1) {					// Pixel size Y
			lcd_touch.convRateY = (p[1] - lcd_touch.offsetY) * 10 / LCD_SCREEN_HEIGHT;
		}

		// Touch force		(touch 3point by equate force, left-up, right-up, left-down)
		if ((p[0] < C0) && (p[1] < C0)) {
			lcd_touch.leftUpForce = p[2];
		}
		if ((p[0] < C0) && (p[1] > C1)) {
			if (lcd_touch.leftUpForce != 0) {
				lcd_touch.forceEffectRateY = (p[2] - lcd_touch.leftUpForce) * 1000 / (p[1] - lcd_touch.offsetY);
			}
		}
		if ((p[0] > C1) && (p[1] < C0)) {
			if (lcd_touch.leftUpForce != 0) {
				lcd_touch.forceEffectRateX = (p[2] - lcd_touch.leftUpForce) * 1000 / (p[0] - lcd_touch.offsetX);
			}
		}
	}

//	printf("point=%d,%d,%d\n", p[0], p[1], p[2]);
//	printf("off=%d,%d size=%d,%d\n", lcd_touch.offsetX, lcd_touch.offsetY, lcd_touch.convRateX, lcd_touch.convRateY);
//	printf("force=%d,%d\n", lcd_touch.forceEffectRateX, lcd_touch.forceEffectRateY);

	return;
}
