/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2012 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

/* This is the BeOS version of SDL YUV video overlays */

#include "SDL_video.h"
#include "SDL_sysyuv.h"
#include "../SDL_yuvfuncs.h"

extern "C" {

/* The functions used to manipulate software video overlays */
static struct private_yuvhwfuncs be_yuvfuncs =
{
    BE_LockYUVOverlay,
    BE_UnlockYUVOverlay,
    BE_DisplayYUVOverlay,
    BE_FreeYUVOverlay
};

BBitmap * BE_GetOverlayBitmap(BRect bounds, color_space cs) {
	BBitmap *bbitmap;
	bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs);
	if (!bbitmap || bbitmap->InitCheck() != B_OK) {
		delete bbitmap;
		return 0;
	}
	overlay_restrictions r;
	bbitmap->GetOverlayRestrictions(&r);
	uint32 width = bounds.IntegerWidth() + 1;
	uint32 height = bounds.IntegerHeight() + 1;
	uint32 width_padding = 0;
	uint32 height_padding = 0;
	if ((r.source.horizontal_alignment != 0) ||
	    (r.source.vertical_alignment != 0)) {
		delete bbitmap;
		return 0;
	}
	if (r.source.width_alignment != 0) {
		uint32 aligned_width = r.source.width_alignment + 1;
		if (width % aligned_width > 0) {
			width_padding = aligned_width - width % aligned_width;
		}
	}
	if (r.source.height_alignment != 0) {
		uint32 aligned_height = r.source.height_alignment + 1;
		if (height % aligned_height > 0) {
			fprintf(stderr,"GetOverlayBitmap failed height alignment\n");
			fprintf(stderr,"- height = %lu, aligned_height = %lu\n",height,aligned_height);
			delete bbitmap;
			return 0;
		}
	}
	if ((r.source.min_width > width) ||
	    (r.source.min_height > height) ||
	    (r.source.max_width < width) ||
	    (r.source.max_height < height)) {
		fprintf(stderr,"GetOverlayBitmap failed bounds tests\n");
	    delete bbitmap;
	    return 0;
	}
	if ((width_padding != 0) || (height_padding != 0)) {
		delete bbitmap;
		bounds.Set(bounds.left,bounds.top,bounds.right+width_padding,bounds.bottom+height_padding);
		bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs);
		if (!bbitmap || bbitmap->InitCheck() != B_OK) {
			fprintf(stderr,"GetOverlayBitmap failed late\n");
			delete bbitmap;
			return 0;
		}
	}		
	return bbitmap;	    
}

// See <GraphicsDefs.h> [btw: Cb=U, Cr=V]
// See also http://www.fourcc.org/indexyuv.htm
color_space convert_color_space(Uint32 format) {
	switch (format) {
	case SDL_YV12_OVERLAY:
		return B_YUV9;
	case SDL_IYUV_OVERLAY:
		return B_YUV12;
	case SDL_YUY2_OVERLAY:
		return B_YCbCr422;
	case SDL_UYVY_OVERLAY:
		return B_YUV422;
	case SDL_YVYU_OVERLAY: // not supported on beos?
		return B_NO_COLOR_SPACE;
	default:
		return B_NO_COLOR_SPACE;
	}
}

// See SDL_video.h
int count_planes(Uint32 format) {
	switch (format) {
	case SDL_YV12_OVERLAY:
	case SDL_IYUV_OVERLAY:
		return 3;
	case SDL_YUY2_OVERLAY:
	case SDL_UYVY_OVERLAY:
	case SDL_YVYU_OVERLAY:
		return 1;
	default:
		return 0;
	}
}		

SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) {
	SDL_Overlay* overlay;
	struct private_yuvhwdata* hwdata;
	BBitmap *bbitmap;
	int planes;
	BRect bounds;
	color_space cs;
	
	/* find the appropriate BeOS colorspace descriptor */
	cs = convert_color_space(format);
	if (cs == B_NO_COLOR_SPACE)
	{
		return NULL;
	}
	
	/* count planes */
	planes = count_planes(format);
	if (planes == 0)
	{
		return NULL;
	}
	/* TODO: figure out planar modes, if anyone cares */
	if (planes == 3)
	{
		return NULL;
	}

    /* Create the overlay structure */
    overlay = (SDL_Overlay*)SDL_calloc(1, sizeof(SDL_Overlay));

    if (overlay == NULL)
    {
        SDL_OutOfMemory();
        return NULL;
    }

    /* Fill in the basic members */
    overlay->format = format;
    overlay->w = width;
    overlay->h = height;
    overlay->hwdata = NULL;
	
    /* Set up the YUV surface function structure */
    overlay->hwfuncs = &be_yuvfuncs;

    /* Create the pixel data and lookup tables */
    hwdata = (struct private_yuvhwdata*)SDL_calloc(1, sizeof(struct private_yuvhwdata));

    if (hwdata == NULL)
    {
        SDL_OutOfMemory();
        SDL_FreeYUVOverlay(overlay);
        return NULL;
    }

    overlay->hwdata = hwdata;
	overlay->hwdata->display = display;
	overlay->hwdata->bview = NULL;
	overlay->hwdata->bbitmap = NULL;
	overlay->hwdata->locked = 0;

	/* Create the BBitmap framebuffer */
	bounds.top = 0;	bounds.left = 0;
	bounds.right = width-1;
	bounds.bottom = height-1;
	
	BView * bview = new BView(bounds,"overlay",B_FOLLOW_NONE,B_WILL_DRAW); 
	if (!bview) {
		SDL_OutOfMemory();
        SDL_FreeYUVOverlay(overlay);
        return NULL;
	}
	overlay->hwdata->bview = bview;
	overlay->hwdata->first_display = true;
	bview->Hide();
	
	bbitmap = BE_GetOverlayBitmap(bounds,cs);
	if (!bbitmap) {
		overlay->hwdata->bbitmap = NULL;
		SDL_FreeYUVOverlay(overlay);
		return NULL;
	}
	overlay->hwdata->bbitmap = bbitmap;
	
	overlay->planes = planes;
	overlay->pitches = (Uint16*)SDL_calloc(overlay->planes, sizeof(Uint16));
	overlay->pixels  = (Uint8**)SDL_calloc(overlay->planes, sizeof(Uint8*));
	if (!overlay->pitches || !overlay->pixels)
	{
        SDL_OutOfMemory();
        SDL_FreeYUVOverlay(overlay);
        return(NULL);
    }

   	overlay->pitches[0] = bbitmap->BytesPerRow();
   	overlay->pixels[0]  = (Uint8 *)bbitmap->Bits();
	overlay->hw_overlay = 1;
	
	if (SDL_Win->LockWithTimeout(1000000) != B_OK) {
        SDL_FreeYUVOverlay(overlay);
        return(NULL);
    }
	BView * view = SDL_Win->View();
    view->AddChild(bview);
    rgb_color key;
    bview->SetViewOverlay(bbitmap,bounds,bview->Bounds(),&key,B_FOLLOW_ALL,
                         B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL);
    bview->SetViewColor(key);
    bview->Flush();
	SDL_Win->Unlock();
	
	current_overlay=overlay;
        
	return overlay;
}

int BE_LockYUVOverlay(_THIS, SDL_Overlay* overlay)
{
    if (overlay == NULL)
    {
        return 0;
    }

    overlay->hwdata->locked = 1;
    return 0;
}

void BE_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay)
{
    if (overlay == NULL)
    {
         return;
    }

    overlay->hwdata->locked = 0;
}

int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect *dst)
{
    if ((overlay == NULL) || (overlay->hwdata==NULL)
        || (overlay->hwdata->bview==NULL) || (SDL_Win->View() == NULL))
    {
        return -1;
    }
    if (SDL_Win->LockWithTimeout(50000) != B_OK) {
        return 0;
    }
    BView * bview = overlay->hwdata->bview;
    if (SDL_Win->IsFullScreen()) {
    	int left,top;
    	SDL_Win->GetXYOffset(left,top);
	    bview->MoveTo(left+dst->x,top+dst->y);
    } else {
	    bview->MoveTo(dst->x,dst->y);
    }
    bview->ResizeTo(dst->w,dst->h);
    bview->Flush();
	if (overlay->hwdata->first_display) {
		bview->Show();
		overlay->hwdata->first_display = false;
	}
    SDL_Win->Unlock();
    
	return 0;
}

void BE_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
{
    if (overlay == NULL)
    {
        return;
    }

    if (overlay->hwdata == NULL)
    {
        return;
    }

    current_overlay=NULL;

	delete overlay->hwdata->bbitmap;

    SDL_free(overlay->hwdata);
}

}; // extern "C"
