/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 *
 * Copyright (C) 2007 Stefan Saftescu
 *
 * All files in this archive are subject to the GNU General Public License.
 * See the file COPYING in the source tree root for full license agreement.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/

#include "plugin.h"
#include "xlcd.h"

bool xlcd_drawpixel_alpha(short int x, short int y, short int r2, short int g2, short int b2, unsigned char alpha)
{
	short int r1, g1, b1;
	unsigned tmp = _xlcd_rb->lcd_get_foreground();
	
	if(x<0 || x >= LCD_WIDTH) return false;
	if(y<0 || y >= LCD_HEIGHT) return false;
	
	r1 = RGB_UNPACK_RED_LCD  (_xlcd_rb->lcd_framebuffer[y*LCD_WIDTH+x]); 
	g1 = RGB_UNPACK_GREEN_LCD(_xlcd_rb->lcd_framebuffer[y*LCD_WIDTH+x]); 
	b1 = RGB_UNPACK_BLUE_LCD (_xlcd_rb->lcd_framebuffer[y*LCD_WIDTH+x]);
	r1 = ((255-alpha)*r1 + alpha*r2) / 255;
	g1 = ((255-alpha)*g1 + alpha*g2) / 255;
	b1 = ((255-alpha)*b1 + alpha*b2) / 255;
	_xlcd_rb->lcd_set_foreground(LCD_RGBPACK_LCD(r1, g1, b1));
	_xlcd_rb->lcd_drawpixel(x,y);
	_xlcd_rb->lcd_set_foreground(tmp);
	return true;
}

bool xlcd_fillrect_alpha(short int x1, short int y1, short int x2, short int y2, short int r2, short int g2, short int b2, unsigned char alpha)
{
	short int r1, g1, b1;
	short int i, j;
	unsigned tmp = _xlcd_rb->lcd_get_foreground();
	
	x1 = MIN(MAX(x1, 0), LCD_WIDTH-1); x2 = MAX(0, MIN(x2, LCD_WIDTH-1));
	y1 = MIN(MAX(y1, 0), LCD_HEIGHT-1); y2 = MAX(0, MIN(y2, LCD_HEIGHT-1));
	
	for(i=x1;i<x2;++i)
	{
		for(j=y1;j<y2;++j)
		{
			r1 = RGB_UNPACK_RED_LCD  (_xlcd_rb->lcd_framebuffer[j*LCD_WIDTH+i]); 
			g1 = RGB_UNPACK_GREEN_LCD(_xlcd_rb->lcd_framebuffer[j*LCD_WIDTH+i]); 
			b1 = RGB_UNPACK_BLUE_LCD (_xlcd_rb->lcd_framebuffer[j*LCD_WIDTH+i]);
			r1 = ((255-alpha)*r1 + alpha*r2) / 255;
			g1 = ((255-alpha)*g1 + alpha*g2) / 255;
			b1 = ((255-alpha)*b1 + alpha*b2) / 255;
			_xlcd_rb->lcd_set_foreground(LCD_RGBPACK_LCD(r1, g1, b1));
			_xlcd_rb->lcd_drawpixel(i, j);
		}
	}
	_xlcd_rb->lcd_set_foreground(tmp);
	return true;
}

bool xlcd_fillrect_alpha_uniform(short int x1, short int y1, short int x2, short int y2, short int r2, short int g2, short int b2, unsigned char alpha)
{
	short int r1, g1, b1;
	unsigned tmp = _xlcd_rb->lcd_get_foreground();
	
	x1 = MIN(MAX(x1, 0), LCD_WIDTH-1); x2 = MAX(0, MIN(x2, LCD_WIDTH-1));
	y1 = MIN(MAX(y1, 0), LCD_HEIGHT-1); y2 = MAX(0, MIN(y2, LCD_HEIGHT-1));
	
	r1 = RGB_UNPACK_RED_LCD  (_xlcd_rb->lcd_framebuffer[y1*LCD_WIDTH+x1]); 
	g1 = RGB_UNPACK_GREEN_LCD(_xlcd_rb->lcd_framebuffer[y1*LCD_WIDTH+x1]); 
	b1 = RGB_UNPACK_BLUE_LCD (_xlcd_rb->lcd_framebuffer[y1*LCD_WIDTH+x1]);
	r1 = ((255-alpha)*r1 + alpha*r2) / 255;
	g1 = ((255-alpha)*g1 + alpha*g2) / 255;
	b1 = ((255-alpha)*b1 + alpha*b2) / 255;
	_xlcd_rb->lcd_set_foreground(LCD_RGBPACK_LCD(r1, g1, b1));
	_xlcd_rb->lcd_fillrect(x1,y1,x2-x1,y2-y1);
	_xlcd_rb->lcd_set_foreground(tmp);
	return true;
}

bool xlcd_fillrect_halpha(short int x1, short int y1, short int x2, short int y2, short int r2, short int g2, short int b2, unsigned char alpha)
{
	short int r1, g1, b1;
	short int i;
	unsigned tmp = _xlcd_rb->lcd_get_foreground();
	
	x1 = MIN(MAX(x1, 0), LCD_WIDTH-1); x2 = MAX(0, MIN(x2, LCD_WIDTH-1));
	y1 = MIN(MAX(y1, 0), LCD_HEIGHT-1); y2 = MAX(0, MIN(y2, LCD_HEIGHT-1));
	
	for(i=MAX(y1, 0);i<=y2 && (i < LCD_HEIGHT);++i)
	{		
		r1 = RGB_UNPACK_RED_LCD  (_xlcd_rb->lcd_framebuffer[i*LCD_WIDTH+x1]); 
		g1 = RGB_UNPACK_GREEN_LCD(_xlcd_rb->lcd_framebuffer[i*LCD_WIDTH+x1]); 
		b1 = RGB_UNPACK_BLUE_LCD (_xlcd_rb->lcd_framebuffer[i*LCD_WIDTH+x1]);
		r1 = ((255-alpha)*r1 + alpha*r2) / 255;
		g1 = ((255-alpha)*g1 + alpha*g2) / 255;
		b1 = ((255-alpha)*b1 + alpha*b2) / 255;
		_xlcd_rb->lcd_set_foreground(LCD_RGBPACK_LCD(r1, g1, b1));
		_xlcd_rb->lcd_hline(x1, x2, i);
	}
	_xlcd_rb->lcd_set_foreground(tmp);
	return true;
}

bool xlcd_fillrect_valpha(short int x1, short int y1, short int x2, short int y2, short int r2, short int g2, short int b2, unsigned char alpha)
{
	short int r1, g1, b1;
	short int i;
	unsigned tmp = _xlcd_rb->lcd_get_foreground();
	
	x1 = MIN(MAX(x1, 0), LCD_WIDTH-1); x2 = MAX(0, MIN(x2, LCD_WIDTH-1));
	y1 = MIN(MAX(y1, 0), LCD_HEIGHT-1); y2 = MAX(0, MIN(y2, LCD_HEIGHT-1));
	
	for(i=x1;i<=x2;++i)
	{		
		r1 = RGB_UNPACK_RED_LCD  (_xlcd_rb->lcd_framebuffer[y1*LCD_WIDTH+i]); 
		g1 = RGB_UNPACK_GREEN_LCD(_xlcd_rb->lcd_framebuffer[y1*LCD_WIDTH+i]); 
		b1 = RGB_UNPACK_BLUE_LCD (_xlcd_rb->lcd_framebuffer[y1*LCD_WIDTH+i]);
		r1 = ((255-alpha)*r1 + alpha*r2) / 255;
		g1 = ((255-alpha)*g1 + alpha*g2) / 255;
		b1 = ((255-alpha)*b1 + alpha*b2) / 255;
		_xlcd_rb->lcd_set_foreground(LCD_RGBPACK_LCD(r1, g1, b1));
		_xlcd_rb->lcd_vline(i, y1, y2);
	}
	_xlcd_rb->lcd_set_foreground(tmp);
	return true;
}

bool xlcd_semitransparent_bitmap(const fb_data* image, const fb_data* alpha, short int x, short int y, short int width, short int height)
{
	short int i, j, r1, r2, g1, g2, b1, b2, alphac;
	unsigned tmp = _xlcd_rb->lcd_get_foreground();
	for(i=0;i<width;++i)
	{
		for(j=0;j<height;j++)
		{
			alphac = RGB_UNPACK_GREEN(alpha[j*width+i]);
			if(alphac == 255)
			{
				_xlcd_rb->lcd_set_foreground(image[j*width+i]);
				_xlcd_rb->lcd_drawpixel(i, j);
			}
			else if(alphac)
			{
				r1 = RGB_UNPACK_RED_LCD  (_xlcd_rb->lcd_framebuffer[(j+y)*LCD_WIDTH+i+x]);
				g1 = RGB_UNPACK_GREEN_LCD(_xlcd_rb->lcd_framebuffer[(j+y)*LCD_WIDTH+i+x]);
				b1 = RGB_UNPACK_BLUE_LCD (_xlcd_rb->lcd_framebuffer[(j+y)*LCD_WIDTH+i+x]);
				r2 = RGB_UNPACK_RED_LCD  (image[j*width+i]);
				g2 = RGB_UNPACK_GREEN_LCD(image[j*width+i]);
				b2 = RGB_UNPACK_BLUE_LCD (image[j*width+i]);
				_xlcd_rb->lcd_set_foreground(LCD_RGBPACK_LCD((r1-(r1*alphac)/255) + r2, (g1-(g1*alphac)/255) + g2, (b1-(b1*alphac)/255) + b2));
				_xlcd_rb->lcd_drawpixel(i, j);
			}
		}
	}
	_xlcd_rb->lcd_set_foreground(tmp);
	return true;
}

bool xlcd_semitransparent_bitmap_part(const fb_data* image, const fb_data* alpha, short int x, short int y, short int stride, short int width, short int height)
{
	short int i, j, r1, r2, g1, g2, b1, b2, alphac;
	unsigned tmp = _xlcd_rb->lcd_get_foreground();
	for(i=0;i<width;++i)
	{
		for(j=0;j<height;j++)
		{
			alphac = RGB_UNPACK_GREEN(alpha[j*stride+i]);
			if(alphac == 255)
			{
				_xlcd_rb->lcd_set_foreground(image[j*stride+i]);
				_xlcd_rb->lcd_drawpixel(i, j);
			}
			else if(alphac)
			{
				r1 = RGB_UNPACK_RED_LCD  (_xlcd_rb->lcd_framebuffer[(j+y)*LCD_WIDTH+i+x]);
				g1 = RGB_UNPACK_GREEN_LCD(_xlcd_rb->lcd_framebuffer[(j+y)*LCD_WIDTH+i+x]);
				b1 = RGB_UNPACK_BLUE_LCD (_xlcd_rb->lcd_framebuffer[(j+y)*LCD_WIDTH+i+x]);
				r2 = RGB_UNPACK_RED_LCD  (image[j*stride+i]);
				g2 = RGB_UNPACK_GREEN_LCD(image[j*stride+i]);
				b2 = RGB_UNPACK_BLUE_LCD (image[j*stride+i]);
				_xlcd_rb->lcd_set_foreground(LCD_RGBPACK_LCD((r1-(r1*alphac)/255) + r2, (g1-(g1*alphac)/255) + g2, (b1-(b1*alphac)/255) + b2));
				_xlcd_rb->lcd_drawpixel(i, j);
			}
		}
	}
	_xlcd_rb->lcd_set_foreground(tmp);
	return true;
}