/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2009  Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#include "header.h"
#include "fft.h"
#include "qsodb.h"
#include "scope.h"
#include "tsdl.h"
#include "ssbd.h"
#include "subwin.h"
#include "terminal.h"

#ifdef Z_HAVE_SDL

/* only EV_KBD */
int sw_scope_kbd_func(struct subwin *sw, struct event *ev, int fw){
	SDL_Rect area;

    if (!sdl) return 0;
	switch (ev->x){
		case ' ':
 			sw->scope_mode++;
			if (sw->scope_mode == 4) sw->scope_mode = 0;

            area.x = 0;
            area.y = 0;
            area.w = sw->screen->w;
            area.h = sw->screen->h;
            SDL_FillRect(sw->screen, &area, z_makecol(0, 0, 0));
			break;
	}
    return 0;
}


int sw_scope_mouse_func(struct subwin *sw, struct event *ev, int fw){
    if (!sdl) return 0;
    return 0;
}


void sw_scope_redraw(struct subwin *sw, struct band *band, int flags){
	SDL_Rect area;
	int i, y, y0, a, c, x;
	int oy0=0, oy1=0;
	//static int ssr = 0;

    if (!sdl) return;
	
	fill_area(sw->x, sw->y, sw->w, sw->h, 0);

	//dbg("sw_scope_redraw(gdirty=%d)  scope_show=%d   pixel=%d\n", sw->gdirty, gssbd->scope_show, z_getpixel(sw->screen, 0, 0)); 
	if (!sw->gdirty) return;
	sw->gdirty=0;
	
#ifdef USE_FFT
	if (sw->scope_mode == 3){
		//fill_area(sw->x, sw->y, sw->w, sw->h, 0);
        sw_fft_redraw(sw, flags);
        return;
    }
#endif

#ifdef HAVE_SNDFILE
	if (!gssbd->scope_show) {
		//fill_area(sw->x, sw->y, sw->w, sw->h, 0);
		return;
	}
#endif
    

	area.x = 0;
	area.y = 0;
	area.w = sw->screen->w;
	area.h = sw->screen->h;
    SDL_FillRect(sw->screen, &area, z_makecol(0, 0, 0));

#ifdef HAVE_SNDFILE

    if (gssbd->channels == 1){
		int avg = 0;
        c = gssbd->recording ? sdl->red : sdl->green;
        y0 = sw->screen->h / 2;
        a = sw->screen->h / 2 - 1;
		for (i=0; i<gssbd->scope_samples; i++){
			avg += gssbd->scope_buf[i];
		}
		avg /= gssbd->scope_samples;
        for (i=0; i<gssbd->scope_samples; i++){
            if (i==sw->screen->w) break;
            y = ((int)(gssbd->scope_buf[i] - avg) * (int)a) / 32768; 
            //y = (int)(log((double)(fabs(gssbd->scope_buf[i] - avg))) * a / log(32768.0)); 

			switch(sw->scope_mode){
            	case 0:
					z_line(sw->screen, i, y0+y, i, y0-y, c); 
					break;
            	case 1:
					z_putpixel(sw->screen, i, y0-y, c); 
					break;
				case 2:
					if (i==0){
                     	oy0 = y0-y;
						break;
					}
					z_line(sw->screen, i-1, oy0, i, y0-y, c);
					z_putpixel(sw->screen, i-1, y0, sdl->gr[10]); 
                    oy0 = y0-y;
					break;
			}
     		z_putpixel(sw->screen, i, y0, sdl->gr[10]); 
        }
		//zsdl_printf(sw->screen, 20, 0, sdl->gr[15], 0, 0, "%d", ssr++);
        //z_putpixel(sw->screen, 0, 0, z_makecol(255, 255, 255));

    }

    if (gssbd->channels == 2){
        c = gssbd->recording ? sdl->red : sdl->green;
        y0 = sw->screen->h / 4;
        a = sw->screen->h / 4 - 1;
        for (i=0, x=0; i<gssbd->scope_samples; i+=2, x++){
            if (x==sw->screen->w) break;
            y = ((int)gssbd->scope_buf[i] * (int)a) / 32768; 
			switch(sw->scope_mode){
            	case 0:
					z_line(sw->screen, x, y0+y, x, y0-y, c); 
					break;
            	case 1:
					z_putpixel(sw->screen, x, y0-y, c); 
					break;
				case 2:
					if (x==0){
                     	oy0 = y0-y;
						break;
					}
					z_line(sw->screen, x-1, oy0, x, y0-y, c);
		    		z_putpixel(sw->screen, x-1, y0, sdl->gr[10]); 
                    oy0 = y0-y;
					break;
			}
			z_putpixel(sw->screen, x, y0, sdl->gr[10]); 
		}
        y0 = (sw->screen->h * 3)/ 4;
        for (i=1, x=0; i<gssbd->scope_samples; i+=2, x++){
            if (x==sw->screen->w) break;
            y = ((int)gssbd->scope_buf[i] * (int)a) / 32768; 
			switch(sw->scope_mode){
            	case 0:
					z_line(sw->screen, x, y0+y, x, y0-y, c); 
					break;
            	case 1:
					z_putpixel(sw->screen, x, y0-y, c); 
					break;
				case 2:
					if (x==0){
                     	oy1 = y0-y;
						break;
					}
					z_line(sw->screen, x-1, oy1, x, y0-y, c);
					z_putpixel(sw->screen, x-1, y0, sdl->gr[10]); 
                    oy1 = y0-y;
					break;
			}
			z_putpixel(sw->screen, x, y0, sdl->gr[10]); 
        }
        //z_putpixel(sw->screen, 0, 0, z_makecol(255, 255, 255));
    }
	gssbd->scope_show = 0;
#endif

}

void sw_scope_check_bounds(struct subwin *sw){

    if (!sdl) return;
    if (!aband) return;
}

void sw_scope_raise(struct subwin *sw){
    sw->gdirty=1;      
}

void sw_scope_clear_scopes(){
    int i;
    for (i = 0; i < gses->subwins->len; i++){
        struct subwin *sw = (struct subwin*)g_ptr_array_index(gses->subwins, i);
        if (sw->type != SWT_SCOPE) continue;
	if (!sw->screen) continue;
        SDL_FillRect(sw->screen, NULL, z_makecol(0, 0, 0));
    }
#ifdef USE_FFT
	if (gfft && gfft->screen && sdl){
	    MUTEX_LOCK(gfft->screen);
            SDL_FillRect(gfft->screen, NULL, z_makecol(0, 0, 0));
	    MUTEX_UNLOCK(gfft->screen);
	}
#endif
}

#else
int sw_scope_kbd_func(struct subwin *sw, struct event *ev, int fw){
    return 0;
}

int sw_scope_mouse_func(struct subwin *sw, struct event *ev, int fw){
    return 0;
}

void sw_scope_redraw(struct subwin *sw, struct band *band, int flags){
}

void sw_scope_check_bounds(struct subwin *sw){
}

void sw_scope_raise(struct subwin *sw){
}

void sw_scope_clear_scopes(){
}

#endif
