/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2016  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 "ac.h"
#include "bfu.h"
#ifdef Z_HAVE_SDL
#include "cordata.h"
#endif
#include "fifo.h"
#include "html.h"
#include "icons.h"
#include "kbdbind.h"
#include "kbd.h"
#include "main.h"
#include "map.h"
#include "qrvdb.h"
#include "rain.h"
#include "rotar.h"
#include "tsdl.h"
#include "session.h"
#include "stats.h"
#include "subwin.h"
#include "terminal.h"
#include "zpng.h"

#define sqr(x) ((x)*(x))       

#ifdef Z_HAVE_SDL

#define INFO_W (20 * zsdl->font_w)

//double rotace = 0;



/* only EV_KBD */
int sw_map_kbd_func(struct subwin* sw, struct event* ev, int fw) {
    int lmx, lmy, step;
    double stepd;

    if (!sdl) return 0;
    step = (SDL_GetModState() & KMOD_SHIFT) != 0 ? 1 : 10;
    /*dbg("\nsw_map_kbd_func [%d,%d,%d,%d]\n",ev->ev,ev->x,ev->y,ev->b);*/
    switch (kbd_action(KM_MAIN, ev)) {
    case ACT_ESC:
        return 0;
        break;
    case ACT_LEFT:
        sw->ox += 10;
        move_map(sw, aband, +step, 0);
        return 1;
    case ACT_RIGHT:
        sw->ox -= 10;
        move_map(sw, aband, -step, 0);
        return 1;
    case ACT_UP:
        sw->oy += 10;
        move_map(sw, aband, 0, +step);
        return 1;
    case ACT_DOWN:
        sw->oy -= 10;
        move_map(sw, aband, 0, -step);
        return 1;

    }
    /* dbg("sw_map_kbd_func: %c %d\n", ev->x, ev->y);*/
    int mod = SDL_GetModState();
    if ((mod & (KMOD_CTRL | KMOD_ALT | KMOD_SHIFT)) == 0)
    {
        stepd = (mod & KMOD_SHIFT) != 0 ? 1.05 : 1.3;
        switch (ev->x) {
        case '+':
        case '=':
            lmx = sw->x * FONT_W + sw->screen->w / 2;
            lmy = sw->y * FONT_H + sw->screen->h / 2;
            zoom(sw, stepd, lmx, lmy);
            break;
        case '-':
            lmx = sw->x * FONT_W + sw->screen->w / 2;
            lmy = sw->y * FONT_H + sw->screen->h / 2;
            zoom(sw, 1 / stepd, lmx, lmy);
            break;
            /*        case '1':
                        sw->ox+=20;
                        sw->oy+=20;
                        move_map(sw, +20, +20);
                        break;*/
        case 'r':
            sw->gdirty = 1;
            qrv_recalc_wkd(qrv);
            qrv_recalc_qrbqtf(qrv);
            qrv_recalc_gst(qrv);
            map_recalc_gst(sw, aband);
            sw_map_redraw(sw, aband, 0);
            break;
        case 'p':
            map_for_photo(sw, aband, 0);
            break;
        case 'c':
            sw->ox = sw->map.w / 2;
            sw->oy = sw->map.h / 2;
            sw->gdirty = 1;
            redraw_later();
            break;
        case 'l':
            sw->showlines = !sw->showlines;
            sw->gdirty = 1;
            redraw_later();
            break;
        case 'w':
            sw->showwwls = !sw->showwwls;
            sw->gdirty = 1;
            redraw_later();
            break;
        }
    }
    return 0;
}

void zoom(struct subwin *sw, double factor, int centerx, int centery){
    int oldzoom;    
    int kx, ky;
    
    px2km(sw, centerx, centery, &kx, &ky);
    
    oldzoom=sw->zoom;
    sw->zoom =(int)(sw->zoom * factor);
    if (sw->zoom>40000-2) sw->zoom=40000;
    if (sw->zoom<80) sw->zoom=80;
    if (sw->zoom!=oldzoom){
		pxkm2o(sw, centerx, centery, kx, ky, &sw->ox, &sw->oy);
	}
	sw->gdirty=1;
    redraw_later();
    //dbg("zoom=%d\n", sw->zoom);
}

void map_turn_rot(void *itdata, void *menudata){
	struct subwin *sw = (struct subwin *)menudata;
	int nr = GPOINTER_TO_INT(itdata);
	struct rotar *rot = get_rotar(nr);
	ac_track(gacs, NULL, -10);
	rot_seek(rot, sw->uhel, -90);
}

void map_track(void *itdata, void *menudata){
	struct subwin *sw = (struct subwin *)menudata;
	int nr = GPOINTER_TO_INT(itdata);
	ac_track(gacs, sw->acunder, nr);
}


int sw_map_mouse_func(struct subwin *sw, struct event *ev, int fw){
    int dx,dy, lmx = -1, lmy = -1;
    double stepd;
    
    if (!sdl) return 0;
    /*dbg("sw_map_mouse_func\n");*/
	/*rotace = ev->mx * M_PI / 180.0;
	sw->gdirty = 1;
	redraw_later();*/
    
    sw->mx = ev->mx - sw->x * FONT_W;
    sw->my = ev->my - sw->y * FONT_H;

    stepd = (SDL_GetModState() & KMOD_SHIFT)!=0 ? 1.05 : 1.3;
    if ((ev->b & BM_ACT) == B_DOWN){
        lmx = ev->mx - sw->x * FONT_W;
        lmy = ev->my - sw->y * FONT_H;

		if (lmx >= 0 && 
			lmy > 0 && 
			lmx < sdl->home->w && 
			lmy < sdl->home->h)
		{
            map_for_photo(sw, aband, 0);
			return 1;
		}

		if (lmx >= sw->map.w - sdl->zoomin->w && 
			lmy >= 0 &&
			lmx < sw->map.w &&
			lmy < sdl->zoomin->h)
		{
            lmx = sw->x * FONT_W + sw->screen->w/2;
            lmy = sw->y * FONT_H + sw->screen->h/2;
            zoom(sw, stepd, sw->map.w / 2, sw->map.y / 2);
			return 1;
		}

		if (lmx >= sw->map.w - sdl->zoomout->w && 
			lmy >= sw->map.h - sdl->zoomout->h &&
			lmx < sw->map.w &&
			lmy < sw->map.h)
		{
            lmx = sw->x * FONT_W + sw->screen->w/2;
            lmy = sw->y * FONT_H + sw->screen->h/2;
            zoom(sw, 1 / stepd, sw->map.w / 2, sw->map.y / 2);   
			return 1;
		}
    }
	if (ev->b & B_MOVE){
        if (!gacs) plot_nearest_qso(sw, aband);
        //plot_nearest_qrv(sw, aband);
        plot_qrb_qth(sw, sw->screen, sdl->mouse_x, sdl->mouse_y);
        return 1;
    }
    if (ev->b & B_DRAG){
        switch (ev->b & BM_EBUTT){
            case B_LEFT:
         /*   dbg("drag %d %d\n", ev->mx, ev->my);*/
            dx=ev->mx - sw->olddragx;
            dy=ev->my - sw->olddragy;
            if (dx==0 && dy==0) break;
            sw->olddragx=ev->mx;
            sw->olddragy=ev->my;
            sw->ox+=dx;
            sw->oy+=dy;
            /*redraw_later(); */
            move_map(sw, aband, dx, dy);
            return 1;
        }
        return 1;
    }
    
    switch (ev->b & BM_EBUTT){
		struct menu_item *mi;

        case B_LEFT:
    /*        dbg("left %d %d\n", ev->mx, ev->my);*/
            sw->olddragx=ev->mx;
            sw->olddragy=ev->my;
            return 1;
        case B_MIDDLE:
        /*    dbg("middle\n");*/
            break;
        case B_RIGHT:
			/*dbg("right\n");*/
			if (lmx < 0) break;
			mi = new_menu(1);
			mi->rtext = TRANSLATE("Turn antenna");
			MUTEX_LOCK(rotars);
			int i = 0;
			for (i = 0; i<rotars->len; i++){
				struct rotar *rot = (struct rotar *) g_ptr_array_index(rotars, i);
				add_to_menu(&mi, rot->desc, "", "", MENU_FUNC map_turn_rot, GINT_TO_POINTER(i), 0);
			}
			struct ac *ac = ac_under(gacs, sw);
			g_free(sw->acunder);
			sw->acunder = NULL;
			if (ac){
				sw->acunder = g_strdup(ac->id);
				for (i = 0; i<rotars->len; i++){
					struct rotar *rot = (struct rotar *) g_ptr_array_index(rotars, i);
					add_to_menu(&mi, "Track airplane", rot->rotstr, rot->rotstr, MENU_FUNC map_track, GINT_TO_POINTER(i), 0);
				}
			}

			MUTEX_UNLOCK(rotars);
			if (i == 0) break;
			set_window_ptr(gses->win, ev->x - 3, ev->y + 1);

			int kx, ky;
			double qrb, qtf;
			px2km(sw, lmx, lmy, &kx, &ky);
			km2qrbqtf(kx, ky, &qrb, &qtf);
			int uhel = (int)round(qtf * 180 / M_PI);
			sw->uhel = uhel;
			do_menu(mi, sw);

            break;
        case B_WHUP:
            /*dbg("wheel up\n");*/
            lmx = ev->mx - sw->x * FONT_W;
            lmy = ev->my - sw->y * FONT_H;
            zoom(sw, stepd, lmx, lmy);
            return 1;
        case B_WHDOWN:
            /*dbg("wheel down\n");*/
            lmx = ev->mx - sw->x * FONT_W;
            lmy = ev->my - sw->y * FONT_H;
            zoom(sw, 1/stepd, lmx, lmy);
            return 1;
    }
    return 0;
}

void move_map(struct subwin *sw, struct band *band, int dx, int dy){
    SDL_Rect dst, r;
    
//    dbg("\nmove_map(%d, %d)\n", dx, dy);
    dst.x=dx;
    dst.y=dy;
    dst.w=sw->map.w;
    dst.h=sw->map.h;
    
    //SDL_SetAlpha(sw->l2rot, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
    
    SDL_SetClipRect(sw->l1map, &sw->map);
    memcpy(&r, &dst, sizeof(r));
    SDL_BlitSurface(sw->l1map, &sw->map, sw->l1map, &r); 
    
/*    SDL_SetClipRect(sw->l2rot, &sw->map);
    memcpy(&r, &dst, sizeof(r));
    SDL_BlitSurface(sw->l2rot, &sw->map, sw->l2rot, &r); 
*/    
    SDL_SetClipRect(sw->screen, &sw->map);
    memcpy(&r, &dst, sizeof(r));
    SDL_BlitSurface(sw->screen, &sw->map, sw->screen, &r); 

    if (dx>0){
        dst.x=0;
        dst.w=dx;
        dst.y=0;
        dst.h=sw->map.h;
        sw_map_redraw_rect(sw, &dst, band, 0);
    }
    if (dx<0){
        dst.x=sw->map.w+dx;
        dst.w=-dx;
        dst.y=0;
        dst.h=sw->map.h;
        sw_map_redraw_rect(sw, &dst, band, 0);
    }
    if (dy>0){
        dst.x=0;
        dst.w=sw->map.w;
        dst.y=0;
        dst.h=dy;
        sw_map_redraw_rect(sw, &dst, band, 0);
    }
    if (dy<0){
        dst.x=0;
        dst.w=sw->map.w;
        dst.y=sw->map.h+dy;
        dst.h=-dy;
        sw_map_redraw_rect(sw, &dst, band, 0);
    }

    if (!gacs) plot_nearest_qso(sw, band); 
   // plot_nearest_qrv(sw, band); 
//    dbg("move_map ox=%d oy=%d\n", sw->ox, sw->oy);
}


void sw_map_redraw_rect(struct subwin *sw, SDL_Rect *area, struct band *band, int flags){
    int fp = flags & HTML_FOR_PHOTO;

	if (!sw->l1map) return;

//    dbg("sw_map_redraw_rect: %dx%d%+d%+d\n", area->x, area->y, area->w, area->h);
    SDL_SetClipRect(sw->l1map, area);
    SDL_FillRect(sw->l1map, area, z_makecol(0, 35, 35));
   /* col%=16; */
   /* rect(sw->screen, area->x, area->y, area->x+area->w-1, area->y+area->h-1, 0x4000); */
    /*SDL_FillRect(sw->screen, &sw->map, sdl->termcol[1]);
    SDL_FillRect(sw->screen, &sw->info, sdl->termcol[2]);*/
    
	if (sw->showwwls) plot_wkd_wwls(sw, sw->l1map, area);
    plot_cor(sw, sw->l1map, area, flags);
	//z_dumpbitmap(NULL, sw->l1map);
	//plot_qth(sw, area);
//        dumpbitmap(sw->l1map);
    if (ctest && qrv && !fp) {
        plot_qrvs(sw, sw->l1map, band, area);
        plot_gst(sw, sw->l1map, area, qrv->gst, z_makecol(13, 121, 66));
    }
    if (ctest && ctest->wwlused && sw->type == SWT_MAP) {
        plot_qsos(sw, sw->l1map, band, area);
		/*if (!fp)*/ plot_gst(sw, sw->l1map, area, sw->gst, z_makecol(250, 180, 52));
    }
    
//    sw_map_update_rotar(sw, area);
//  dbg("                    %dx%d%+d%+d\n", area->x, area->y, area->w, area->h);
  
    sw_map_redraw_rotar(sw, area, flags);
	if (band && band->tmplocqso.locator && *band->tmplocqso.locator){
		plot_qso(sw, sw->screen, band, &band->tmplocqso);
		if (gacs) plot_path(sw, sw->screen, band, &band->tmplocqso, &gacs->tmpqso);
	}
	plot_qth(sw, area);
}					  


void sw_map_redraw_rotar(struct subwin *sw, SDL_Rect *area, int flags){
    SDL_Rect rotarea;
    SDL_Rect r;
    
    
    SDL_SetClipRect(sw->screen, area);
    memcpy(&r, area, sizeof(r));
    SDL_BlitSurface(sw->l1map, &r, sw->screen, &r);
	if (sw->type == SWT_MAP){ // no rain for KST A/C info
	    sw_map_redraw_rain(sw, area, flags);
	}
    if ((flags & HTML_FOR_PHOTO) == 0) plot_rotars(sw, sw->screen, area, &rotarea);
    
}

void sw_map_update_rotar(struct subwin *sw){
    SDL_Rect r;

//    dbg("\nsw_map_update_rotar)\n");
    r.x = 0;
    r.y = 0;
    r.w = sw->screen->w;
    r.h = sw->screen->h;

    sw->gdirty=1;
    sw_map_redraw_rotar(sw, &r, 0);
} 

void sw_map_redraw_icons(struct subwin *sw, SDL_Rect *area, int flags){
    //SDL_Rect rotarea;
    SDL_Rect r;
    
    //SDL_SetClipRect(sw->screen, );
    memcpy(&r, area, sizeof(r));
    SDL_BlitSurface(sdl->home, NULL, sdl->screen, &r);

    memcpy(&r, area, sizeof(r));
	r.x += sw->map.w - sdl->zoomin->w;
    SDL_BlitSurface(sdl->zoomin, NULL, sdl->screen, &r);

    memcpy(&r, area, sizeof(r));
	r.x += sw->map.w - sdl->zoomout->w;
	r.y += sw->map.h - sdl->zoomout->h;
    SDL_BlitSurface(sdl->zoomout, NULL, sdl->screen, &r);

    memcpy(&r, area, sizeof(r));
	plot_rain_titles(sdl->screen, &r, flags);

    if (gacs && gacs->plot_info) gacs->plot_info(sw, area, gacs);

//    if ((flags & HTML_FOR_PHOTO) == 0) plot_rotars(sw, sw->screen, area, &rotarea);
}


void sw_map_redraw_rain(struct subwin *sw, SDL_Rect *aarea, int flags){
	int ci;
	if (grain == NULL) return;
	if ((flags & HTML_FOR_PHOTO) != 0) return;

	/*{
		SDL_BlitSurface(grain->weatheronline->img, NULL, sw->screen, &sw->map);
        return;
	}*/ 
	for (ci = 0; ci < RAIN_COLORS; ci++){
		if (grain->weatheronline != NULL) plot_rain_provider(sw, aarea, grain->weatheronline, ci);
		if (grain->wetteronline != NULL) plot_rain_provider(sw, aarea, grain->wetteronline, ci);
		if (grain->meteox != NULL) plot_rain_provider(sw, aarea, grain->meteox, ci);
		if (grain->chmi != NULL) plot_rain_provider(sw, aarea, grain->chmi, ci);
		if (grain->rainviewer != NULL) plot_rain_provider(sw, aarea, grain->rainviewer, ci);
		if (grain->debug) break; 
	} 

	int i, px1, px2, py1, py2;
	for (i = 0; i < grain->scps->len; i++){
		struct rain_scp *scp = (struct rain_scp *)g_ptr_array_index(grain->scps, i);

		km2px_d(sw, scp->kx, scp->ky, &px1, &py1);
		km2px_d(sw, scp->kx + grain->minscpdist, scp->ky, &px2, &py2);
		int r = (int)sqrt((px1 - px2)*(px1 - px2) + (py1 - py2)*(py1 - py2));
		int c = scp->qrb <= grain->maxqrb ? sdl->gr[15] : sdl->gr[5];
		z_circle(sw->screen, px1, py1, r, c);
		if (r > 3) z_circle(sw->screen, px1, py1, r - 2, c);
	}
}

void plot_rain_provider(struct subwin *sw, SDL_Rect *aarea, struct rain_provider *provider, int ci)
{
	SDL_Rect area;
    int ix, iy, c, i;
	int minkx, minky, maxkx, maxky;
	//double hmult, wmult;
    double hh1, hh2, ww1, ww2;
	int kx, ky;
    int px1, px2, px3 = 0, px4 = 0, py1, py2, py3 = 0, py4 = 0;

    if (provider->img == NULL) return;
	if (provider->w <= 0) return;
    

	area.x = aarea->x - 16; // maximal "pixel" size is about 16x16
	area.y = aarea->y - 16;
	area.w = aarea->w + 32;
	area.h = aarea->h + 32;

    //hmult = (provider->h2 - provider->h1) / (provider->hpx2 - provider->hpx1);
    //wmult = (provider->w2 - provider->w1) / (provider->wpx2 - provider->wpx1);


	if (provider->rain->debug){
		// debug mode - only pixels
		for (iy = 0; iy < provider->img->h; iy++){
			for (ix = 0; ix < provider->img->w; ix++){
				c = z_getpixel_fmt(provider->img, ix, iy, sdl->screen->format);
				//if (c == 0x00aad3df) continue;

				
				provider->img2hw(provider, provider->rv_px0 + ix, provider->rv_py0 + iy, &hh1, &ww1);

				hw2km(gses->myh, gses->myw, hh1, ww1, &kx, &ky);
				km2px(sw, kx, ky, &px1, &py1);
        
				if (!z_overlapped_pixel(aarea, px1, py1)) continue;
				z_putpixel(sw->screen, px1, py1, c);
			}
		}
	}else{
		// not debug
		SDL_SetClipRect(sw->screen, aarea); // not area

		px2km(sw, area.x, area.y, &minkx, &minky);
		px2km(sw, area.x + area.w - 1, area.y + area.h - 1, &maxkx, &maxky);
    
		minkx &= provider->mask;
		minky &= provider->mask;
		maxkx &= provider->mask;
		maxky &= provider->mask;
		if (minkx < -32768) minkx = -32768;
		if (maxkx > 32767) maxkx = 32767;
		if (minky < -32768) minky = -32768;
		if (maxky > 32767) maxky = 32767;

		c = provider->pal[ci];
		for (ky = minky; ky <= maxky; ky += provider->step){
			for (kx = minkx; kx <= maxkx; kx += provider->step){

				gpointer key = provider->hash_func(kx, ky, ci);
				GHashTable *hash = provider->hashes[ci];
				struct zbinbuf *zbb = (struct zbinbuf *)g_hash_table_lookup(hash, key);
				//dbg("kx=%d   \tky=%d\n", kx, ky);
				if (zbb == NULL) continue;

				for (i = 0; i <= zbb->len - (int)sizeof(struct rain_km); i += sizeof(struct rain_km)){
					struct rain_km *km = (struct rain_km *)(zbb->buf + i);
					km2px_d(sw, km->kx1, km->ky1, &px1, &py1);
					km2px_d(sw, km->kx2, km->ky2, &px2, &py2);
					km2px_d(sw, km->kx3, km->ky3, &px3, &py3);
					km2px_d(sw, km->kx4, km->ky4, &px4, &py4);

					z_triangle(sw->screen, px1, py1, px3, py3, px2, py2, c);
					z_triangle(sw->screen, px3, py3, px2, py2, px4, py4, c);
				}
			}
		}

		if (ci == 0){
			// borders
			for (iy = provider->top; iy <= provider->img->h && iy <= provider->bottom + 1; iy++){
				ww1 = provider->w1 + (iy - provider->wpx1) * provider->wmult;

				hh1 = provider->h1 + (provider->left - provider->hpx1) * provider->hmult;
				hh2 = provider->h1 + (provider->right + 1 - provider->hpx1) * provider->hmult;

				hw2km(gses->myh, gses->myw, hh1, ww1, &kx, &ky);
				km2px(sw, kx, ky, &px1, &py1);

				hw2km(gses->myh, gses->myw, hh2, ww1, &kx, &ky);
				km2px(sw, kx, ky, &px2, &py2);

				if (iy > provider->top){
					z_line(sw->screen, px3, py3, px1, py1, provider->pal[2]);
					z_line(sw->screen, px4, py4, px2, py2, provider->pal[2]);
				}
				px3 = px1;
				py3 = py1;
				px4 = px2;
				py4 = py2;
			} 

			for (ix = provider->left; ix <= provider->img->w && ix <= provider->right + 1; ix++){
				hh1 = provider->h1 + (ix - provider->hpx1) * provider->hmult;

				ww1 = provider->w1 + (provider->top - provider->wpx1) * provider->wmult;
				ww2 = provider->w1 + (provider->bottom + 1 - provider->wpx1) * provider->wmult;

				hw2km(gses->myh, gses->myw, hh1, ww1, &kx, &ky);
				km2px(sw, kx, ky, &px1, &py1);

				hw2km(gses->myh, gses->myw, hh1, ww2, &kx, &ky);
				km2px(sw, kx, ky, &px2, &py2);

				if (ix > provider->left){
					z_line(sw->screen, px3, py3, px1, py1, provider->pal[2]);
					z_line(sw->screen, px4, py4, px2, py2, provider->pal[2]);
				}
				px3 = px1;
				py3 = py1;
				px4 = px2;
				py4 = py2;
			}
		}
	}

}

void plot_rain_title(SDL_Surface *surface, SDL_Rect *area, int flags, struct rain_provider *provider, int *y){
	int x = area->x + 2, c;

	if (!provider || !provider->title) return;

    if (provider->pal == provider->rain->colors)
       c = sdl->gr[11];
    else
       c = z_makecol(252, 0, 0);

	zsdl_printf(surface, x, *y, c, 0, ZFONT_TRANSP | ZFONT_OUTLINE, provider->title);
	*y -= zsdl->font_h;
}

void plot_rain_titles(SDL_Surface *surface, SDL_Rect *area, int flags){
	int y = area->y + area->h - zsdl->font_h - 2;
	if (!grain) return;

    plot_rain_title(surface, area, flags, grain->chmi, &y);
    plot_rain_title(surface, area, flags, grain->wetteronline, &y);
    plot_rain_title(surface, area, flags, grain->meteox, &y);
	plot_rain_title(surface, area, flags, grain->weatheronline, &y);
	plot_rain_title(surface, area, flags, grain->rainviewer, &y);
}

void sw_map_redraw(struct subwin *sw, struct band *band, int flags){
    struct qso *odx;
	if (!sdl || !sw->screen) return;
	//dbg("sw_map_redraw(gdirty=%d)\n", sw->gdirty);

	//SDL_FillRect(sw->screen, NULL, 0);
	//z_linea(sw->screen, 0, 0, 10, 13, z_makecol(255, 255, 255));


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

    //ST_START; 

    sw_map_redraw_rect(sw, &sw->map, band, flags);

    if ((flags & HTML_FOR_PHOTO) && (odx = band->stats->odx) != NULL){
        struct qso *oldminqso = sw->minqso;
        sw->minqso = odx;
        plot_qso(sw, sw->screen, band, odx);
        plot_info_qso(sw, sw->screen, odx);
        //plot_info_qrv(sw, sw->screen, band, NULL);
		//plot_info_ac(sw, sw->screen, NULL);
        plot_qrb_qth(sw, sw->screen, -1, -1);
        sw->minqso = oldminqso;
        return;
    }

    acs_redraw(sw, gacs);

//    plot_info_qrv(sw, sw->screen, band, qrv_get(qrv, sw->minqrvcall));
    plot_qrb_qth(sw, sw->screen, sdl->mouse_x, sdl->mouse_y);
//	ST_STOP; 
	//plot_hgts(sw, &sw->map);
}

void sw_map_check_bounds(struct subwin *sw){

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

void sw_map_raise(struct subwin *sw){
    sw->gdirty=1;
    map_recalc_gst(sw, aband);
    if (aband){
        ac_update_tmpctp(aband->tmpqsos[0].locator);
    }
}

/* km -> pixels */
void km2px(struct subwin *sw, int kx, int ky, int *px, int *py){
    /*double qrb = sqrt((double)kx*kx + ky*ky);
	double qtf = atan2((double)ky, (double)kx);
	qtf += rotace;
	kx = qrb * cos(qtf);
	ky = qrb * sin(qtf);*/

	*px = sw->ox + (kx * sw->zoom)/10000;    
    *py = sw->oy + (ky * sw->zoom)/10000;    
}

void km2px_d(struct subwin *sw, double kx, double ky, int *px, int *py){
	/*double qrb = sqrt(kx*kx + ky*ky);
	double qtf = atan2(ky, kx);
	qtf += rotace;
	kx = qrb * cos(qtf);
	ky = qrb * sin(qtf);*/

    *px = sw->ox + (kx * sw->zoom)/10000;    
    *py = sw->oy + (ky * sw->zoom)/10000;    
}

/* pixels -> km */
void px2km(struct subwin *sw, int px, int py, int *kx, int *ky){
    *kx = ((px - sw->ox) * 10000)/sw->zoom;
    *ky = ((py - sw->oy) * 10000)/sw->zoom;
}

void pxkm2o(struct subwin *sw, int px, int py, int kx, int ky, int *ox, int *oy){
    *ox = px - (kx * sw->zoom)/10000;    
    *oy = py - (ky * sw->zoom)/10000;    
}





void plot_cor(struct subwin *sw, SDL_Surface *surface, SDL_Rect *area, int flags){
    gpointer key;
    int ikx, iky, px, py, kx, ky, oldpx=0, oldpy=0, c, color=0, i;
    struct kmarray *kma;
    struct kmpoint *kmp;
    int minkx, minky, maxkx, maxky;  
	if (sw->zoom == 0) zinternal("sw->zoom==0! sw->title='%s'", sw->title);
   /* ST_START; */
	//	rect2(surface,area, 0x000080);
    px2km(sw, area->x, area->y, &minkx, &minky);
    px2km(sw, area->x+area->w-1, area->y+area->h-1, &maxkx, &maxky);
    /*px2km(sw, 0, 0, &minkx, &minky);
    px2km(sw, sw->screen->w, sw->screen->h, &maxkx, &maxky);*/
    //   dbg("\nplot_cor: area=%dx%x+%d+%d kx=%d..%d ky=%d..%d  \n", area->x, area->y, area->w, area->h, minkx, maxkx, minky, maxky);
    minkx &= COR_KM_MASK;
    minky &= COR_KM_MASK;
    maxkx &= COR_KM_MASK;
    maxky &= COR_KM_MASK;
    if (minkx<COR_KM_MIN) minkx=COR_KM_MIN;
    if (maxkx>COR_KM_MAX) maxkx=COR_KM_MAX;
    if (minky<COR_KM_MIN) minky=COR_KM_MIN;
    if (maxky>COR_KM_MAX) maxky=COR_KM_MAX;
 /*   dbg("kx=%d-%d ky=%d-%d\n", minkx, maxkx, minky, maxky);*/
    
    
    /* big wwls (JN69) */
    for (iky=minky; iky<=maxky; iky+=COR_KM_STEP)
        for (ikx=minkx; ikx<=maxkx; ikx+=COR_KM_STEP){
            km2px(sw, ikx, iky, &px, &py);
            key=k2key(ikx, iky);
            if (sw->zoom<1000){ 
                kma=(struct kmarray*)g_hash_table_lookup(gcor->wwl2, key);
            }else{
                kma=(struct kmarray*)g_hash_table_lookup(gcor->wwl4, key);
            }
            if (!kma) continue;
            for (i=0,kmp=kma->data;i<kma->len;i++,kmp++){
                kx=kmp->kx;
                ky=kmp->ky;
                km2px(sw, kx, ky, &px, &py);
                if ((signed char)kmp->c < 0) {
                    oldpx = px;
                    oldpy = py;
                    switch((int)(signed char)kmp->c){
                        case -128: color=z_makecol(184, 159, 255); break;
                        case -127: color=z_makecol(145, 125, 122); break;
                        default: color=z_makecol(255, 159, 255); break;
                    }
                    continue;
                }
                c = color;
                if (z_overlapped_line(area, oldpx, oldpy, px, py)) z_line(surface, oldpx, oldpy, px, py, c);
                oldpx = px;
                oldpy = py;
            }
        }
    /*ST_STOP; */
    /*ST_START; */
    /* azimuth star lines */
		if (!(flags & HTML_FOR_PHOTO) && sw->showlines){
		for (iky=minky; iky<=maxky; iky+=COR_KM_STEP){
			for (ikx=minkx; ikx<=maxkx; ikx+=COR_KM_STEP){
				km2px(sw, ikx, iky, &px, &py);
				key=k2key(ikx, iky);
				kma = (struct kmarray*)g_hash_table_lookup(gcor->az, key);
				if (!kma) continue;
				for (i=0,kmp=kma->data;i<kma->len;i++,kmp++){
					kx=kmp->kx;
					ky=kmp->ky;
					km2px(sw, kx, ky, &px, &py);
					if ((signed char)kmp->c < 0) {
						oldpx = px;
						oldpy = py;
						switch((int)(signed char)kmp->c){
							case -128: color=z_makecol(240, 128, 128); break;
							default:   color=z_makecol(180, 128, 128); break;
						}
						continue;
					}
					c = color;
					if (z_overlapped_line(area, oldpx, oldpy, px, py)) z_line(surface, oldpx, oldpy, px, py, c);
					oldpx = px;
					oldpy = py;
				}
			}
		}	
	}
    /* cor */
    for (iky=minky; iky<=maxky; iky+=COR_KM_STEP)
        for (ikx=minkx; ikx<=maxkx; ikx+=COR_KM_STEP){
            km2px(sw, ikx, iky, &px, &py);
            key=k2key(ikx, iky);
            kma=(struct kmarray*)g_hash_table_lookup(gcor->km, key);
            if (!kma) continue;
            for (i=0,kmp=kma->data;i<kma->len;i++,kmp++){
                kx=kmp->kx;
                ky=kmp->ky;
                km2px(sw, kx, ky, &px, &py);
                
                if ((signed char)kmp->c<0) {
                    oldpx = px;
                    oldpy = py;
                    switch((int)(signed char)kmp->c){
                        case -128: /* coast */
                            color=z_makecol(0, 255, 255);
                            break;
                        case -127: /* isle */
                            color=z_makecol(0, 255, 255);
                            break;
                        case -126: /* lake */
                            color=z_makecol(0, 95, 195);
                            break;
                        case -125: /* border */
                            color=z_makecol(0, 255, 255);
                            break;
                        case -100: 
                            color=z_makecol(255,0,0);
                            break;
                        case -101: 
                            color=z_makecol(0,255,0);
                            break;
                        default:
                            dbg("unknown char %d\n", (int)(signed char)kmp->c);    
                            return;
                            break;
                            
                    }
                    continue;
                }

                c = color;
/*                if (abs(oldpx-px) + abs(oldpy-py) < 100)  */
                if (oldpx!=px || oldpy!=py)               
                    z_line(surface, oldpx, oldpy, px, py, c);
               /* if (oldpx==px && oldpy==py) stejne++;
                else ruzne++;*/

                oldpx = px;
                oldpy = py;
            }
        }

  /*  dbg("stejne=%d ruzne=%d\n", stejne, ruzne);*/
    /*ST_STOP; */
//    zsdl_test_bars(surface, 0);
}


void plot_wkd_func(gpointer key, gpointer value, gpointer user_data){
	GPtrArray *arr = (GPtrArray *)user_data;
	g_ptr_array_add(arr, key);
}

void plot_wkd_wwls(struct subwin *sw, SDL_Surface *surface, SDL_Rect *area){

	int i;
	GPtrArray *arr;
	int c = z_makecol(140, 0, 0);

	if (!aband) return;
	
	arr = g_ptr_array_new();
	g_hash_table_foreach(aband->stats->wwls, plot_wkd_func, arr);
	
	for (i = 0; i < arr->len; i++){
		double h0, w0, h, w;
		int kx, ky, j;
		//SDL_Rect r;
		int px[6], py[6];
		char *wwl = (char*)g_ptr_array_index(arr, i);

		h0 = qth(wwl, 0);
		w0 = qth(wwl, 1);

		for (j = 0; j < 6; j++){
			h = h0 + (j / 2) * M_PI/180.0;
			w = w0 + (j % 2) * M_PI/180.0;
			
			hw2km(gses->myh, gses->myw, h, w, &kx, &ky);
			km2px(sw, kx, ky, &px[j], &py[j]);
		}

		z_triangle_net(surface, c, 6, px[0], py[0], px[1], py[1], px[2], py[2], px[3], py[3], px[4], py[4], px[5], py[5]);
	}

	
	g_ptr_array_free(arr, TRUE);

}

void plot_qth(struct subwin *sw, SDL_Rect *area){
	int px, py;
	SDL_Rect r;
	           
	km2px(sw, 0, 0, &px, &py);
	r.x = px - 5;
	r.y = py - 3;
	r.w = sdl->mast->w;
	r.h = sdl->mast->h;
	/*z_line(sw->l1map, px - 100, py, px + 100, py, sdl->gr[15]);
	z_line(sw->l1map, px, py - 100, px, py + 100, sdl->gr[15]);*/
	SDL_BlitSurface(sdl->mast, NULL, sw->screen, &r);
}


void plot_qrv(struct subwin *sw, SDL_Surface *surface, struct band *band, struct qrv_item *qi){
    int kx, ky, px, py, color1, color2;
    SDL_Rect outline;

    outline.w=3;
    outline.h=3;
    kx =   qi->kx;
    ky =   qi->ky;
    km2px(sw, kx, ky, &px, &py);
    outline.x = px - 1; 
    outline.y = py - 1; 
    if (!z_overlapped_rect(&surface->clip_rect, &outline)) {
           // dbg("clipped qi\n"); 
        return;
    }
    //dbg("kreslim qi %s [%d,%d]\n", qi->call, qi->kx, qi->ky); 
    //dbg("q->call=%s sw->minqrvcall=%s\n", qi->call, sw->minqrvcall);
    /*if (sw->minqrvcall && strcmp(qi->call, sw->minqrvcall) == 0){
        color1=z_makecol(193, 21, 107);
        color2=z_makecol(121, 13, 67);
    }else*/{
        if (qi->wkd[band->bi] > 0){
            color1=z_makecol(21, 193, 106);
            color2=z_makecol(13, 121, 66);
        }else{
            color1=z_makecol(107, 107, 107);
            color2=z_makecol(67, 67, 67);
        }
    }

    z_pip(surface, px, py, color1, color2, sw->zoom);
}

void plot_qrvs(struct subwin *sw, SDL_Surface *surface, struct band *band, SDL_Rect *area){
    int skip;
    int i;

    if (!qrv) return;
    if (!band) return;

    for (i = 0; i < qrv->qrvs->len; i++){
        struct qrv_item *qi = (struct qrv_item*)g_ptr_array_index(qrv->qrvs, i);
        
        skip = qrv_skip(qi, band->bi, 1);
//        dbg("plot_qrvs('%s') skip=%d, bands=%d, wkd=%d\n", qi->call, skip, qi->bands_qrv, qi->bands_wkd);
        if (skip) continue;
        plot_qrv(sw, surface, band, qi);
    }
}

void plot_gst(struct subwin *sw, SDL_Surface *surface, SDL_Rect *area, double gst[360], int c){
    int i,ii, x, y, oldx=0,oldy=0;
    double rad, r;
    

    if (sw->map.w > sw->map.h)
        r = sw->map.h / 2.3;
    else
        r = sw->map.w / 2.3;


    for (i=-1; i<360;i++) {
        ii = i>=0 ? i : 359;
        rad = M_PI * (double)(i - 90) / 180.0;
        x = (int)(sw->ox + r * gst[ii] * cos(rad));
        y = (int)(sw->oy + r * gst[ii] * sin(rad));
        if (i >= 0){
            //if (overlapped_line(area, oldx, oldy, x, y))
                z_line(surface, oldx, oldy, x, y, c);
        }
        oldx=x;
        oldy=y;
    }
}



void plot_qso(struct subwin *sw, SDL_Surface *surface, struct band *band, struct qso *qso){
    int kx, ky, px, py, color;
    SDL_Rect outline;

    outline.w=9;
    outline.h=9;
    kx =   qso->kx;
    ky =   qso->ky;
    km2px(sw, kx, ky, &px, &py);
    outline.x = px - 4; 
    outline.y = py - 4; 
    if (!z_overlapped_rect(&surface->clip_rect, &outline)) {
/*            dbg("clipped qso\n"); */
        return;
    }
/*       dbg("kreslim qso\n"); */
    color=qso==sw->minqso?sdl->red:sdl->yellow2;
    if (qso==&band->tmplocqso) {
		color=sdl->magenta;
	}
    z_cross(surface, px, py, color, sw->zoom);
}

void map_add_qso(struct qso *qso, struct band *band){
    if (ctest && !ctest->wwlused) return;
    if (gses->ontop->type!=SWT_MAP) return;
    SDL_SetClipRect(gses->ontop->screen, &gses->ontop->map);
    plot_qso(gses->ontop, gses->ontop->screen, band, qso);
}

void plot_qsos(struct subwin *sw, SDL_Surface *surface, struct band *band, SDL_Rect *area){
    int i;
    struct qso *qso;
    
    if (!band) return;
    
    for (i=0;i<band->qsos->len;i++){
        qso=(struct qso*)g_ptr_array_index(band->qsos, i);
        if (qso->error) continue;
        plot_qso(sw, surface, band, qso);
    }
}

void plot_rotars(struct subwin *sw, SDL_Surface *surface, SDL_Rect *area, SDL_Rect *outarea){
    struct rotar *rot;
    int i;
    double rad,r;
    int vx,vy,vx1,vy1,vx2,vy2,vxb,vyb;
    
    
    if (sw->map.w > sw->map.h)
        r = sw->map.h / 2.3;
    else
        r = sw->map.w / 2.3;

    outarea->x = (int)(sw->ox - r);
    outarea->y = (int)(sw->oy - r);
    outarea->w = (int)(2 * r + 1);
    outarea->h = (int)(2 * r + 1);

 /*   for (i=0; i<16; i++){
        SDL_Rect q;
        q.x = sw->ox-20;
        q.y = sw->oy-r+i*10;
        q.w = 20;
        q.h = 10;
        SDL_FillRect(surface, &q, sdl->termcol[i]);
    }*/

    MUTEX_LOCK(rotars);
    for (i=0; i<rotars->len; i++){
        rot = (struct rotar *)g_ptr_array_index(rotars, i);
        
        rad = M_PI * (double)(rot->qtf - 90) / 180.0;
        vx  = (int)(sw->ox + r * cos(rad)); 
        vy  = (int)(sw->oy + r * sin(rad));
        vx1 = (int)(sw->ox + 0.95 * r * cos(rad + 0.02));
        vy1 = (int)(sw->oy + 0.95 * r * sin(rad + 0.02));
        vx2 = (int)(sw->ox + 0.95 * r * cos(rad - 0.02));
        vy2 = (int)(sw->oy + 0.95 * r * sin(rad - 0.02));
    
        z_line(surface, sw->ox, sw->oy, vx, vy, rot->color);
        z_triangle(surface, vx, vy, vx1, vy1, vx2, vy2, rot->color);

		int kx = (ZLOC_R_EARTH * M_PI - 1) * cos(rad);
		int ky = (ZLOC_R_EARTH * M_PI - 1) * sin(rad);
		km2px(sw, kx, ky, &vxb, &vyb);
		z_do_line(surface, vx, vy,
			vxb, vyb, rot->color, z_dotfce);


        if (rot->beamwidth<=0) continue;
        
        rad = M_PI * (double)(rot->qtf - 90 + rot->beamwidth / 2) / 180.0;
        vx1 = (int)(sw->ox + 0.9 * r * cos(rad)); 
        vy1 = (int)(sw->oy + 0.9 * r * sin(rad));
        z_do_line(surface, sw->ox, sw->oy,  
                vx1, vy1, rot->color, z_dashfce);

        rad = M_PI * (double)(rot->qtf - 90 - rot->beamwidth / 2) / 180.0;
        vx2 = (int)(sw->ox + 0.9 * r * cos(rad)); 
        vy2 = (int)(sw->oy + 0.9 * r * sin(rad));
        z_do_line(surface, sw->ox, sw->oy,  
                vx2, vy2, rot->color, z_dashfce);

        z_do_line(surface, vx1, vy1, vx2, vy2, rot->color, z_dashfce);
    }
    MUTEX_UNLOCK(rotars);
}

void map_update_layout(struct subwin *sw){
/*    dbg("map_update_layout\n");*/

    sw->map.x = 0;
    sw->map.y = 0;
    sw->map.w = sw->w * FONT_W - INFO_W;
    sw->map.h = sw->h * FONT_H;

    sw->info.x = sw->w * FONT_W - INFO_W;
    sw->info.y = 0;
    sw->info.w = INFO_W;
    sw->info.h = sw->h * FONT_H;

}

int map_update_qth(struct subwin *sw){
    gchar *pwwlo;

//    dbg("map_update_qth\n");
    if (!sdl) return 0;

    
    if (ctest && ctest->pwwlo) {
        pwwlo=ctest->pwwlo;
    }else{
        pwwlo = cfg->pwwlo;
    }
    if (!pwwlo) zinternal("Undefined locator");
    
    if (sw->pwwlo && strcmp(sw->pwwlo, pwwlo)==0) {
        /*dbg("map_update_qth(%s (same) )\n", sw->pwwlo);*/
        return 0;
    }
    
    zg_free0(sw->pwwlo);
    sw->pwwlo = g_strdup(pwwlo);
    /*dbg("map_update_qth(%s)\n", sw->pwwlo);*/

    sw->ox=sw->map.w/2; 
    sw->oy=sw->map.h/2; 
	
    
	zcors_recalc(gses->myh, gses->myw, sw->pwwlo, zsel, map_cor_callback, cor_tucnakcor, COR_ITEMS);

	acs_update_qth(gacs);

    return 1;
}


int maps_reload(){
    int i;
    struct subwin *sw=NULL;
    
    if (!sdl) return 0;
    /*dbg("maps_reload\n");*/
    
    for (i=0;i<gses->subwins->len;i++){
        sw=(struct subwin *)g_ptr_array_index(gses->subwins, i);
        if (sw->type!=SWT_MAP && sw->type != SWT_KST) continue;
        sw->gdirty=1;
        sw->minqso=NULL;
//        zg_free0(sw->minqrvcall);
        map_update_qth(sw);
        map_recalc_gst(sw, aband); // added for band change

    }

	// next in map_cor_callback
    
    return 0;
}


int maps_update_showwwls(){
    int i;
    struct subwin *sw;
    
    if (!sdl) return 0;
    
    for (i=0;i<gses->subwins->len;i++){
        sw=(struct subwin *)g_ptr_array_index(gses->subwins, i);
        if (sw->type!=SWT_MAP && sw->type != SWT_KST) continue;
		sw->showwwls = ctest != NULL && ctest->wwlmult > 0;
        sw->gdirty=1;
    }
	return 0;
}

void map_clear_qso(struct qso *qso, struct band *band){
    int kx, ky, px, py;
    SDL_Rect outline;
    struct subwin *sw;
    
    if (!sdl) return;
    if (ctest && !ctest->wwlused) return;
    
    if (gses->ontop->type!=SWT_MAP) goto x;
    
    if (!qso->locator || !*qso->locator) goto x;
    sw = gses->ontop;
    kx =   qso->kx;
    ky =   qso->ky;
    km2px(sw, kx, ky, &px, &py);
    outline.x = px - 4; 
    outline.y = py - 4; 
    outline.w = 9;
    outline.h = 9;
    if (!z_overlapped_rect(&sw->map, &outline)) goto x;
    
    sw_map_redraw_rect(sw, &outline, band, 0);
x:;    
    if (qso==&band->tmplocqso) zg_free0(qso->locator);

}

void map_recalc_cors(){
    int i;
    struct subwin *sw;
	char *wwl = ctest ? ctest->pwwlo : cfg->pwwlo;
    
    for (i=0;i<gses->subwins->len;i++){
        sw=(struct subwin *)g_ptr_array_index(gses->subwins, i);
        if (sw->type!=SWT_MAP) continue;
		//zcors_recalc(sw->myh, sw->myw, wwl, zsel, map_cor_callback, cor_tucnakcor, COR_ITEMS);
		zcors_recalc(gses->myh, gses->myw, wwl, NULL, NULL, cor_tucnakcor, COR_ITEMS);
        break; /* more maps with different pwwlo. but why? */
    }
} 


struct qso *find_nearest_qso(struct band *b, int mouse_x, int mouse_y){
    int i;
    struct qso *minq, *q;
    gdouble d, min;
    int px, py, kx, ky;
    struct subwin *sw;

    if (!b) return NULL;
    sw=gses->ontop;
    if (sw->type!=SWT_MAP) return NULL;
    
    px=mouse_x-sw->x*FONT_W;
    py=mouse_y-sw->y*FONT_H;
    px2km(sw, px, py, &kx, &ky);
    

    min=G_MAXDOUBLE;
    minq=NULL;
    for (i=0; i<b->qsos->len; i++){
        q = (struct qso *)g_ptr_array_index(b->qsos, i);
        if (q->error) continue;
        
        /*compute_cache(q); */
        d = sqrt((double)(sqr(q->kx-kx)+sqr(q->ky-ky)));
/*        dbg("  %s %d %d %6.3f\n", q->callsign, q->gfx_x-mouse_x,  q->gfx_y-mouse_y, d);*/
        if (d<min){
            min=d;
            minq=q;
        }
    }
    /*if (minq) dbg("nearest: %s %s\n", minq->callsign, minq->locator);
    else dbg("nearest: NULL\n"); */
    return minq;
}

gchar *find_nearest_qrv(struct qrvdb *qrvdb, struct band *band, int mouse_x, int mouse_y){
    struct qrv_item *minqrv;
    gdouble d, min;
    int px, py, kx, ky;
    struct subwin *sw;
    int i;

    if (!qrvdb) return NULL;
    if (!band) return NULL;

    sw=gses->ontop;
    if (sw->type!=SWT_MAP) return NULL;
    
    px=mouse_x-sw->x*FONT_W;
    py=mouse_y-sw->y*FONT_H;
    px2km(sw, px, py, &kx, &ky);
    

    min=G_MAXDOUBLE;
    minqrv=NULL;

    for (i = 0; i < qrvdb->qrvs->len; i++){
        struct qrv_item *qi = (struct qrv_item*)g_ptr_array_index(qrvdb->qrvs, i);

        if (qrv_skip(qi, band->bi, 0)) continue;
        
        /*compute_cache(q); */
        d = sqrt((double)(sqr(qi->kx-kx)+sqr(qi->ky-ky)));
        //dbg("  %s %d %d %6.3f\n", q->call, q->kx-kx,  q->ky-ky, d);
        if (d<min){
            min=d;
            minqrv=qi;
        }
    }
   // if (minqrv) dbg("nearest_qrv: %s %s\n", minqrv->call, minqrv->wwl);
   // else dbg("nearest_qrv: NULL\n"); 
	if (!minqrv) return NULL;
    return minqrv->call;
}

void plot_nearest_qso(struct subwin *sw, struct band *band){
    struct qso *oldminqso;

    if (!sdl) return;
    oldminqso=sw->minqso;          
    sw->minqso=find_nearest_qso(band, sdl->mouse_x, sdl->mouse_y);
    /*dbg("sw->minq=%s  oldminq=%s\n", sw->minq->callsign, oldminq->callsign); */
    if (sw->minqso==oldminqso) return;
/*        dbg("minq changed %s->%s\n", oldminq->locator, sw->minq->locator); */
    SDL_SetClipRect(sw->screen, &sw->map);
/*       dbg("clip_rect %dx%d%+d%+d\n", surface->clip_rect.x, surface->clip_rect.y, surface->clip_rect.w, surface->clip_rect.h); */
    if (oldminqso) plot_qso(sw, sw->screen, band, oldminqso);
    if (sw->minqso) {
        plot_qso(sw, sw->screen, band, sw->minqso);
        plot_info_qso(sw, sw->screen, sw->minqso);
    }else{
        plot_info_qso(sw, sw->screen, NULL);
    }
}
    
/*void plot_nearest_qrv(struct subwin *sw, struct band *band){
    gchar *minqrvcall, *oldminqrvcall;

    if (!sdl) return;
    minqrvcall=find_nearest_qrv(qrv, band, sdl->mouse_x, sdl->mouse_y);
	if (!minqrvcall) return;
    //dbg("sw->minqrv=%s  oldminqrv=%s\n", sw->minqrv->call, oldminqrv->call); 
    if (sw->minqrvcall && strcmp(minqrvcall, sw->minqrvcall)==0) return;

    SDL_SetClipRect(sw->screen, &sw->map);

    oldminqrvcall = sw->minqrvcall;
    sw->minqrvcall = g_strdup(minqrvcall);
    if (oldminqrvcall) plot_qrv(sw, sw->screen, band, qrv_get(qrv, oldminqrvcall));
    zg_free0(oldminqrvcall);

    if (minqrvcall) {
        struct qrv_item *qi = qrv_get(qrv, minqrvcall);
        plot_qrv(sw, sw->screen, band, qi);
        plot_info_qrv(sw, sw->screen, band, qi);
    }else{
        plot_info_qrv(sw, sw->screen, band, NULL);
    }
} */

void plot_info_qso(struct subwin *sw, SDL_Surface *surface, struct qso *qso){
    char s[10];
    int x,y;
    SDL_Rect rect;
 
    //dbg("plot_info_qso('%s')\n", qso ? qso->callsign : "");
    rect.x=sw->info.x;  // same as plot_info_ac
    rect.y=sw->info.y;
    rect.w=sw->info.w;
    rect.h=sw->info.y+(11*FONT_H)+12;
    
    SDL_SetClipRect(surface, &rect);
    SDL_FillRect(surface, &rect, z_makecol(0,0,135)) ;
    if (!qso) return;

    x=sw->info.x+4;
    y=sw->info.y+4;
    zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GCALL), q0(qso->callsign)); y+=FONT_H+4;
    zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GWWL),  q0(qso->locator)); y+=FONT_H+4;
    zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GQRB),  (int)qso->qrb); y+=FONT_H+4;   
    zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GQTF),  qso->qtf); y+=FONT_H+4;
    zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GSEN),  q0(qso->rsts), q0(qso->qsonrs)); y+=FONT_H+4;
    zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GRCV),  q0(qso->rstr), q0(qso->qsonrr)); y+=FONT_H+4;
    strcpy(s,qso->time_str);
    s[5]=s[4];
    s[4]=s[3];
    s[3]=s[2];
    s[2]=':';
    zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GTIM),  s); y+=FONT_H+4;
    zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GOPE),  q0(qso->operator_)); y+=FONT_H+4;
    zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GREM),  q0(qso->remark)); y+=FONT_H+4;
    return;                      
}

/*void plot_info_qrv(struct subwin *sw, SDL_Surface *surface, struct band *band, struct qrv_item *qi){
    int x,y;
    SDL_Rect rect;
    int color;
    //char s[256];
 
   // dbg("plot_info_qrv(%s)\n", qrv?qrv->call:"-");

    x=sw->info.x+4;
    y=sw->info.y+4+18*FONT_H;

    rect.x=sw->info.x;
    rect.y=y;
    rect.w=sw->info.w;
    rect.h=sw->y - y;
    
    
    SDL_SetClipRect(surface, &rect);
    SDL_FillRect(surface, &rect, z_makecol(0,0,35)) ;
    if (!qi) return;

    color=z_makecol(21, 193, 106);

	zsdl_printf(surface, x, y, color, 0, ZFONT_TRANSP, VTEXT(T_GCALL), q0(qi->call)); y+=FONT_H+4;
    zsdl_printf(surface, x, y, color, 0, ZFONT_TRANSP, VTEXT(T_GWWL),  q0(qi->wwl)); y+=FONT_H+4;
    zsdl_printf(surface, x, y, color, 0, ZFONT_TRANSP, VTEXT(T_GREM),  q0(qi->text)); y+=FONT_H+4;
    if (!band) return;
    zsdl_printf(surface, x, y, color, 0, ZFONT_TRANSP, VTEXT(T_GWKD),  qi->wkd[band->bi]); y+=FONT_H+4;
    return;                      
}*/

int plot_qrb_qth(struct subwin *sw, SDL_Surface *surface, int mouse_x, int mouse_y){
    double qrb,qtf, h2, w2; 
    SDL_Rect rect;
    char buf[100];
    int x, y, kx, ky;
 	char *sss;

    x=sw->info.x+4;
    y=sw->info.y+(11*FONT_H)+12;
    
/*    dbg("plot_qtb_qtf\n");*/
    rect.x=sw->info.x;
    rect.y=y;
    rect.w=sw->info.w;
    rect.h=6 * FONT_H + 8 ;
    
    px2km(sw, mouse_x - sw->x*FONT_W, mouse_y - sw->y*FONT_H, &kx, &ky);
    km2qrbqtf(kx, ky, &qrb, &qtf);
    
    SDL_SetClipRect(surface, &rect);
/*    SDL_FillRect(surface, &sw->info, z_makecol(0,0,175)) ; */
    SDL_FillRect(surface, &rect, z_makecol(0,0,35)) ;
    if (mouse_x < 0) return 0;


    sss = VTEXT(T_GQRB);
    
    //dbg("plot_qtb_qtf sss='%s'\n", sss);
    zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, sss, (int)(qrb));
    y+=FONT_H+4;
    zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GQTF), (int)(qtf*180/M_PI)); y+=FONT_H+4;
   /* fontoutf(surface, x, y, sdl->green, FONT_TRANSP, VTEXT(T_GINC), (int) (gst[(int)(qtf*180/M_PI)%360]/400*100));y+=FONT_H+4; */
#if -1
	if (qrbqtf2hw(gses->myh, gses->myw, qrb, qtf, &h2, &w2) == 0){
        zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GLON), h2*180.0/M_PI, x2gramin(buf, sizeof(buf), h2*180/M_PI, "EW")); y+=FONT_H+4;
        zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GLAT), w2*180.0/M_PI, x2gramin(buf, sizeof(buf), w2*180/M_PI, "NS")); y+=FONT_H+4;
        zsdl_printf(surface, x, y, sdl->green, 0, ZFONT_TRANSP, VTEXT(T_GLOC), hw2loc(buf, h2*180/M_PI, w2*180/M_PI, 6)); y+=FONT_H+4;
    }
#else    
	{
		int mx = mouse_x - sw->x*FONT_W;
		int my = mouse_y - sw->y*FONT_H;

        double dx = mx - 234;
        double dy = my + 280;
        double d = sqrt(dx * dx + dy * dy) / 12.6 - 5;
        double a = atan2(dy, dx);
        double w = 90 - d;
        double h = 90 - (a * 180 / M_PI) + 12;
        h *= 27.5 / 22.0;

		zsdl_printf(surface, x, y, sdl->gr[15], 0, ZFONT_TRANSP, "mxy %d %d", mx, my); y += FONT_H;
	    zsdl_printf(surface, x, y, sdl->gr[15], 0, ZFONT_TRANSP, "dxy %4.2f %4.2f", dx, dy); y += FONT_H;
		zsdl_printf(surface, x, y, sdl->gr[15], 0, ZFONT_TRANSP, "da %4.2f %4.2f", d, a * 180 / M_PI); y += FONT_H;
		zsdl_printf(surface, x, y, sdl->gr[15], 0, ZFONT_TRANSP, "hw %4.2f %4.2f", h, w); y += FONT_H;
		//zsdl_printf(surface, x, y, sdl->gr[15], 0, ZFONT_TRANSP, "z     %d", sw->zoom); y += FONT_H;
	}
#endif
    return 0;
}
        

void map_for_photo(struct subwin *sw, struct band *band, int flags){
    int i, minkx, minky, maxkx, maxky, px, py, lmx, lmy;
    int dx, dy;
	double z, z1, z2;
	char *wwl;
    
    if (!sdl) return;

    minkx = minky = 0;
    maxkx = maxky = 0;

	if (ctest && band && (flags & MAP_AC_INFO) == 0){
		wwl = band->tmpqsos[0].locator;
		if (wwl && *wwl){
			double qrb, qtf, qtfrad;

			qrbqtf(ctest->pwwlo, wwl, &qrb, &qtf, NULL, 2);
			qtfrad = qtf * M_PI / 180.0;
			minkx = maxkx = (int)(  qrb * sin(qtfrad));
			minky = maxky = (int)(- qrb * cos(qtfrad));
		}
	}

	if (flags & MAP_AC_INFO){
		double qrb, qtf, qtfrad;
		struct qso *q = &gacs->infolocqso;

		qrbqtf(ctest ? ctest->pwwlo : cfg->pwwlo, q->locator, &qrb, &qtf, NULL, 2);
		qtfrad = qtf * M_PI / 180.0;
		qtfrad = qtf * M_PI / 180.0;
		q->kx = (int)(  qrb * sin(qtfrad));
		q->ky = (int)(- qrb * cos(qtfrad));

		if (q->kx < minkx) minkx = q->kx;
        if (q->ky < minky) minky = q->ky;
        if (q->kx > maxkx) maxkx = q->kx;
        if (q->ky > maxky) maxky = q->ky;
	}

	if (band && (flags & MAP_AC_INFO) == 0){
		for (i=0; i<band->qsos->len; i++){
			struct qso *q = (struct qso *)g_ptr_array_index(band->qsos, i);
			if (q->error) continue;

			if (q->kx < minkx) minkx = q->kx;
			if (q->ky < minky) minky = q->ky;
			if (q->kx > maxkx) maxkx = q->kx;
			if (q->ky > maxky) maxky = q->ky;
		}
	}

    if (minkx == maxkx || minky == maxky) {
        //dbg("minkx=%d maxkx=%d\n", minkx, maxkx);
        sw->ox = sw->map.w/2; 
        sw->oy = sw->map.h/2; 
        return;  // no qso
    }
 //   dbg("x=%d..%d y=%d..%d  prumer x=%d y=%d\n", minkx, maxkx, minky, maxky, (maxkx+minkx)/2, (maxky+minky)/2);
    km2px(sw, (maxkx+minkx)/2, (maxky+minky)/2, &px, &py);
    dx = sw->map.w/2 - px;
    dy = sw->map.h/2 - py;
 //   dbg("px=%d py=%d   map/2=%d %d   sw->ox=%d sw->oy=%d   dx=%d dy=%d\n", px, py, sw->map.w/2, sw->map.h/2, sw->ox, sw->oy, dx, dy);
    sw->ox += dx; 
    sw->oy += dy;
    move_map(sw, band, dx, dy);

    //px = sw->map.x + 10;
    //py = sw->map.y + 10;
//    px2km(sw, px, py, &kx, &ky);
    z1 = ((sw->map.w - 20) * 10000.0) / (maxkx - minkx); 
    z2 = ((sw->map.h - 20) * 10000.0) / (maxky - minky); 
    z = z1 < z2 ? z1 : z2;
//    dbg("kx=%d %d  px=%d %d    %d %d %d\n", kx, ky, px, py, (int)z1, (int)z2, (int)z);
    lmx = sw->map.w/2;//sw->x * FONT_W + sw->screen->w/2;
    lmy = sw->map.h/2;//sw->y * FONT_H + sw->screen->h/2;
    zoom(sw, z/sw->zoom, lmx, lmy);
}

void map_recalc_gst(struct subwin *sw, struct band *band){
    int i, j;
    int qtf2;
	double max;
                   
    sw->beamwidth = rot_beamwidth();// / 2;
    for (i=0;i<=180;i++){
        sw->antchar[i]=cos(M_PI/180.0*(double)i*120.0/sw->beamwidth);
       /* dbg("i=%3d %5.3f\n", i, antchar[i]);*/
        if (sw->antchar[i]<=0) break;
    }
    for (;i<=180;i++) sw->antchar[i]=0;
    
    for (i=0; i<360; i++) sw->gst[i]=0.0;
    
    if (!band) return;

    for (i = 0; i < band->qsos->len; i++){
        struct qso *q = (struct qso *)z_ptr_array_index(band->qsos, i);
        if (q->qtf<0 || q->qtf>=360) continue;
        
        for (j=0;j<=180;j++){
            qtf2 = q->qtf + j;
            if (sw->antchar[j] == 0) break;
            if (qtf2<0) qtf2 += 360;
            sw->gst[qtf2%360] += q->qrb * sw->antchar[j];
        }
        for (j=1;j<180;j++){
            qtf2 = q->qtf - j;
            if (sw->antchar[j] == 0) break;
            if (qtf2<0) qtf2 += 360;
            sw->gst[qtf2%360] += q->qrb * sw->antchar[j];
        }
    }
    max = 0;
    for (i=0; i<360; i++) if (sw->gst[i] > max) max = sw->gst[i];
    if (!max) return;
    for (i=0; i<360; i++) sw->gst[i] = sw->gst[i] / max; 
} 

void plot_hgt(struct subwin *sw, SDL_Rect *area, int xx, int yy, char *file)
{
	char s[256];
	FILE *f;
	int x, y, max = -10000, min = 10000, c;

	strcpy(s, "../src/");
	strcat(s, file);
	z_wokna(s);
	f = fopen(s, "rb");
	if (f){
		signed short u;
		for (x = 0; x <= 1201; x++){
			for (y = 0; y <= 1201; y++){
				if (fread(&u, sizeof(u), 1, f) != 1) 
					break;
				u = ntohs(u);
				if (u == -32768) continue;
				if (u < min) min = u;
				if (u > max) max = u;
			}
		}
		fclose(f);
	}
	
    SDL_SetClipRect(sw->screen, &sw->map);

	f = fopen(s, "rb");
	if (f){
		signed short u;
		for (y = 0; y <= 1200; y++){
			for (x = 0; x <= 1200; x++){
				if (fread(&u, sizeof(u), 1, f) != 1) 
					break;
				u = ntohs(u);
				if (u == -32768) {
					z_putpixel(sw->screen, xx + x/2 + area->x, yy + y/2 + area->y, z_makecol(0, 50, 100));
				}else{
					c = (u - min) * 255 / (max - min);
					z_putpixel(sw->screen, xx + x/2 + area->x, yy + y/2 + area->y, z_makecol(c, c, c));
				}
			}
		}
		fclose(f);
	}
}

void plot_hgts(struct subwin *sw, SDL_Rect *area){
	plot_hgt(sw, area, 0, 0, "N50E012.hgt");
	plot_hgt(sw, area, 600, 0, "N50E013.hgt");
	plot_hgt(sw, area, 0, 600, "N49E012.hgt");
	plot_hgt(sw, area, 600, 600, "N49E013.hgt");
}

void map_cor_callback(void)
{
	if (!gses) return;
	if (gses && gses->ontop && gses->ontop->type == SWT_MAP) {
		gses->ontop->gdirty = 1;
		qrv_recalc_wkd(qrv);
		qrv_recalc_qrbqtf(qrv);
		qrv_recalc_gst(qrv);
		map_recalc_gst(gses->ontop, aband);
		sw_map_redraw(gses->ontop, aband, 0);
	}
}

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

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

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

void sw_map_check_bounds(struct subwin *sw){
}

void sw_map_raise(struct subwin *sw){
}

int maps_reload(){
    return 0;
}

void map_clear_qso(struct qso *qso, struct band *band){
}

void map_add_qso(struct qso *qso, struct band *band){
}
int maps_update_showwwls(){
}
#endif
