
#include "mview_clips.h"

#include "gx11/visual_context.h"
#include "mview_main.h"
#include "mview_spectrum.h"
#include "mview_stuff.h"
#include "mview_cursor.h"
#include "mview_slice.h"
#include "mview_display.h"
#include "mview_view.h"
#include "mview_misc.h"
#include "mview_macros.h"
#include "mview_widgets.h"

#include <stdio.h>
#include <Xm/MwmUtil.h>
#include <Xm/Text.h>
#include <Xm/PushB.h>
#include <Xm/PushBG.h>
#include <Xm/Scale.h>
#include <Xm/Form.h>
#include <Xm/XmStrDefs.h>

static Widget clipshell = NULL;
static char dumstr[80];
static Widget ok;
static Widget clip_dismiss;

void clips( )
{

    Widget clips_w, dummy;
    static char edit_traversal[] = "<Key>Delete: delete-previous-character( )\n\
 <Key>BackSpace: delete-previous-character( )\n\
 <Key>Left: backward-character( )\n\
 <Key>Right: forward-character( )\n\
 <Key>Up: traverse-prev( )\n\
 <Key>Return: activate( )\n\
 <Key>Down: traverse-next( )\n";


    if (clipshell != NULL) {
        XMapRaised( display, XtWindow( clipshell));
        return;
    }

    clipshell = XtVaAppCreateShell( "Clips",
                                   "clipshell",
                                   topLevelShellWidgetClass,
                                   XtDisplay( toplevel),
                                   XmNmappedWhenManaged, True,
                                   XmNmwmDecorations, MWM_DECOR_TITLE | MWM_DECOR_BORDER | MWM_DECOR_MINIMIZE, NULL);

    clips_w = XtVaCreateManagedWidget( "clips_w", xmFormWidgetClass, clipshell, NULL);
    highscale =
     XtVaCreateManagedWidget( "highscale",
                             xmScaleWidgetClass,
                             clips_w,
                             XmNtopAttachment, XmATTACH_FORM,
                             XmNleftAttachment, XmATTACH_FORM,
                             XmNrightAttachment, XmATTACH_FORM,
                             XmNminimum, 1, XmNshowValue, True, XmNvalue, 100, XmNwidth, 256, XmNorientation, XmHORIZONTAL, NULL);
    XtAddCallback( highscale, XmNdragCallback, (XtCallbackProc) change_clips, (XtPointer) k_highscale);
    XtAddCallback( highscale, XmNvalueChangedCallback, (XtCallbackProc) change_clips, (XtPointer) k_highscale);

    create( highscale, k_highscale, NULL);
    dummy = XtVaCreateManagedWidget( "hicuttext",
                                    xmTextWidgetClass,
                                    clips_w,
                                    XmNtopAttachment, XmATTACH_WIDGET,
                                    XmNtopWidget, highscale,
                                    XmNleftAttachment, XmATTACH_FORM,
                                    XmNwidth, 80, XmNvalue, "High Cut", XmNcursorPositionVisible, FALSE, XmNeditable, FALSE, NULL);

    highcut = XtVaCreateManagedWidget( "highcut",
                                      xmTextWidgetClass,
                                      clips_w,
                                      XmNtopAttachment, XmATTACH_WIDGET,
                                      XmNtopWidget, highscale,
                                      XmNrightAttachment, XmATTACH_FORM,
                                      XmNleftAttachment, XmATTACH_WIDGET,
                                      XmNleftWidget, dummy,
                                      XmNcursorPositionVisible, FALSE, XmNeditable, TRUE, XmNeditMode, XmSINGLE_LINE_EDIT, NULL);
    XtAddCallback( highcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);

    XtOverrideTranslations( highcut, XtParseTranslationTable( edit_traversal));
    create( highcut, k_highcut, NULL);
    lowscale =
     XtVaCreateManagedWidget( "lowscale",
                             xmScaleWidgetClass,
                             clips_w,
                             XmNtopAttachment, XmATTACH_WIDGET,
                             XmNtopWidget, highcut,
                             XmNleftAttachment, XmATTACH_FORM,
                             XmNrightAttachment, XmATTACH_FORM,
                             XmNminimum, 1, XmNshowValue, True, XmNvalue, 1, XmNwidth, 256, XmNorientation, XmHORIZONTAL, NULL);
    XtAddCallback( lowscale, XmNdragCallback, (XtCallbackProc) change_clips, (XtPointer) k_lowscale);
    XtAddCallback( lowscale, XmNvalueChangedCallback, (XtCallbackProc) change_clips, (XtPointer) k_lowscale);

    create( lowscale, k_lowscale, NULL);

    dummy = XtVaCreateManagedWidget( "locuttext",
                                    xmTextWidgetClass,
                                    clips_w,
                                    XmNtopAttachment, XmATTACH_WIDGET,
                                    XmNtopWidget, lowscale,
                                    XmNleftAttachment, XmATTACH_FORM,
                                    XmNwidth, 80, XmNvalue, "Low Cut", XmNcursorPositionVisible, FALSE, XmNeditable, FALSE, NULL);

    lowcut = XtVaCreateManagedWidget( "lowcut",
                                     xmTextWidgetClass,
                                     clips_w,
                                     XmNtopAttachment, XmATTACH_WIDGET,
                                     XmNtopWidget, lowscale,
                                     XmNleftAttachment, XmATTACH_WIDGET,
                                     XmNleftWidget, dummy,
                                     XmNrightAttachment, XmATTACH_FORM,
                                     XmNcursorPositionVisible, FALSE, XmNeditable, TRUE, XmNeditMode, XmSINGLE_LINE_EDIT, NULL);
    XtAddCallback( lowcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);

    create( lowcut, k_lowcut, NULL);

    ok = XtVaCreateManagedWidget( "OK",
                                 xmPushButtonGadgetClass,
                                 clips_w,
                                 XmNtopAttachment, XmATTACH_WIDGET,
                                 XmNtopWidget, lowcut, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL);
    XtAddCallback( ok, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_ok);
    comput = XtVaCreateManagedWidget( "comput",
                                     xmTextWidgetClass,
                                     clips_w,
                                     XmNcursorPositionVisible, FALSE,
                                     XmNsensitive, FALSE,
                                     XmNtopAttachment, XmATTACH_WIDGET,
                                     XmNtopWidget, ok, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL);
    create( comput, k_ok, NULL);

    clip_dismiss = XtVaCreateManagedWidget( "Dismiss",
                                           xmPushButtonGadgetClass,
                                           clips_w,
                                           XmNtopAttachment, XmATTACH_WIDGET,
                                           XmNtopWidget, comput,
                                           XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL);
    XtAddCallback( clip_dismiss, XmNactivateCallback, (XtCallbackProc) dismiss_clips, NULL);

    XtRealizeWidget( clipshell);
    set_colormap( clipshell);
}

extern XImage *hugeimage;
extern char *lotofpixels;
extern Widget zoomshell, zoom_w;
extern Dimension zoom_width, zoom_height;

void scale_images( )
{
    int Z, curz, pos[2];

    XSetForeground( display, gc, g_vc.black_pixel);

    if ((lotofpixels != NULL) && (zoomshell == NULL))
        XFillRectangle( display, XtWindow( small_w), gc, 0, 0, 64, 64);
    if ((lotofpixels != NULL) && (zoomshell != NULL))
        XFillRectangle( display, XtWindow( zoom_w), gc, 0, 0, zoom_width, zoom_height);


    if (subpixmap[0] != 0) {
        for (Z = 0; Z < Nsubs; Z++) {
            AffImage( &fimage[isize * Z], pixmap, sizex, sizey,
                     1, npix[0] / incr, 1, npix[1] / incr,
                     zoom, zoom, displayclip[0], displayclip[1], incr, 0, 0, col[Z] * sizex, row[Z] * sizey, sizex, sizey);
            /* Make subset's pixmaps */
            AffImage( &fimage[isize * Z], subpixmap[Z], zsizex, zsizey,
                     1, npix[0], 1, npix[1], localzoom, localzoom, displayclip[0], displayclip[1], 1, 0, 0, 0, 0, zsizex, zsizey);
        }
    }
    draw_wedge( displayclip);

    XSetForeground( display, gc, g_vc.white_pixel);

    for (Z = 1; Z < cols; Z++)
        XDrawLine( display, pixmap, gc, sizex * Z, 0, sizex * Z, rows * sizey - 1);
    for (Z = 1; Z < rows; Z++)
        XDrawLine( display, pixmap, gc, 0, sizey * Z, cols * sizex - 1, sizey * Z);

    redraw( XtWindow( radec));
    /*
       XtVaGetValues( cursorbutton,
       XmNbackground, &selectcursor, 
       NULL);
       XtVaGetValues( slicebutton,
       XmNbackground, &selectslice, 
       NULL);
       if (selectcursor == blackpix)
       redraws_box( );

       if (selectslice == blackpix) {
       redraws_slice( );
       }

     */
    curz = GET_CURZ();

    if (subpixmap[0] != 0)
        XCopyArea( display, subpixmap[curz], subsetpixmap, gc, 0, 0, zsizex, zsizey, 0, 0);
    else
        XCopyArea( display,
                  pixmap,
                  subsetpixmap,
                  gc,
                  POSX(0, curz), POSY(voffset, curz),
                  sizex, sizey, (maxspectrumwidth - sizex) / 2, (maxspectrumheight - sizey) / 2);

    if (XtWindow( subset) != (Window) NULL)
        XCopyArea( display, subsetpixmap, XtWindow( subset), gc, 0, 0, zsizex, zsizey, 0, 0);

    redraws_slice_in_subset( );

    redraw_zcross( subset);

    XSetForeground( display, gc, g_vc.black_pixel);

    XFillRectangle( display, spixmap, gc, 0, 0, slice_zoomx * slicewidth, slice_zoomy * Nsubs);

    AffImage( Buffer, spixmap, slice_zoomx * Np, slice_zoomy * Nsubs,
             1, Np, 1, Nsubs,
             slice_zoomx, slice_zoomy, displayclip[0], displayclip[1], 1,
             0, 0, (slice_zoomx * slicewidth) / 2 - (slice_zoomx * Np) / 2, 0, slice_zoomx * Np, slice_zoomy * Nsubs);

    if (XtWindow( coupe) != (Window) NULL)
        XCopyArea( display, spixmap, XtWindow( coupe), gc, 0, 0, slice_zoomx * slicewidth, slice_zoomy * Nsubs, 0, 0);

    make_huge( );


    get_crosspos( pos);
    if ((lotofpixels != NULL) && (zoomshell == NULL))   /* && 
                                                           (pos[0]>=32/factor) && ((pos[1]+voffset)>=(32/factor)) &&
                                                           (pos[0]<pixmapdim[0]-32/factor) && 
                                                           ((pos[1]+voffset)<(rows*sizey-32/factor))) */
        XPutImage( display, XtWindow( small_w), gc, hugeimage, factor * pos[0] - 32, factor * (pos[1] + voffset) - 32, 0, 0, 64, 64);

    if ((lotofpixels != NULL) && (zoomshell != NULL)) { /* && 
                                                           (pos[0]>=zoom_width/(2*factor)) && 
                                                           ((pos[1]+voffset)>=zoom_height/(2*factor)) &&
                                                           (pos[0]<pixmapdim[0]-zoom_width/(2*factor)) && 
                                                           ((pos[1]+voffset)<(rows*sizey-zoom_height/(2*factor)))) */
        XPutImage( display, XtWindow( zoom_w), gc, hugeimage,
                  factor * pos[0] - zoom_width / 2, factor * (pos[1] + voffset) - zoom_height / 2, 0, 0, zoom_width, zoom_height);
        DRAWCROSS(zoom_w, zoom_width / 2, zoom_height / 2);
    }
}


void change_clips( Widget w, XtPointer tag, XmScaleCallbackStruct * cbs)
{
    static int firstpass = 1;
    static float newclip, clipsav[2];
    static char *dum;
    int Clipmin = 1, Clipmax = 100;

    if (firstpass) {
        clipsav[0] = clip[0];
        clipsav[1] = clip[1];
        displayclip[0] = clip[0];
        displayclip[1] = clip[1];
        firstpass = 0;
    }

    switch ((int)(long)tag) {
    case k_lowscale:
        newclip = clipsav[0] + ((clipsav[1] - clipsav[0]) / 99.) * (cbs->value - 1);
        displayclip[0] = newclip;
        Clipmin = cbs->value;
        if (Clipmin == Clipmax) {
            XtRemoveCallback( lowcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
            XmTextSetString( lowcut, "?????");
            XtAddCallback( lowcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
            return;
        }
        XtRemoveCallback( highcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        XtRemoveCallback( lowcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        sprintf( dumstr, "%f", displayclip[0]);
        XmTextSetString( lowcut, dumstr);
        sprintf( dumstr, "%f", displayclip[1]);
        XmTextSetString( highcut, dumstr);
        XtAddCallback( lowcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        XtAddCallback( highcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        break;

    case k_highscale:
        newclip = clipsav[0] + ((clipsav[1] - clipsav[0]) / 99.) * (cbs->value - 1);
        displayclip[1] = newclip;
        Clipmax = cbs->value;
        if (Clipmin == Clipmax) {
            XtRemoveCallback( highcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
            XmTextSetString( highcut, "?????");
            XtAddCallback( highcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
            return;
        }
        XtRemoveCallback( highcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        XtRemoveCallback( lowcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        sprintf( dumstr, "%f", displayclip[0]);
        XmTextSetString( lowcut, dumstr);
        sprintf( dumstr, "%f", displayclip[1]);
        XmTextSetString( highcut, dumstr);
        XtAddCallback( lowcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        XtAddCallback( highcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        break;
    case k_newval:
        dum = (char *)XmTextGetString( highcut);
        if (sscanf( dum, "%f", &displayclip[1]) != 1) {
            XtRemoveCallback( highcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
            XmTextSetString( highcut, "?????");
            displayclip[1] = clipsav[1];
            return;
            XtAddCallback( highcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        }
        dum = (char *)XmTextGetString( lowcut);
        if (sscanf( dum, "%f", &displayclip[0]) != 1) {
            XtRemoveCallback( lowcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
            XmTextSetString( lowcut, "?????");
            displayclip[0] = clipsav[0];
            return;
            XtAddCallback( lowcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        }
        return;
    case k_ok:
        dum = (char *)XmTextGetString( highcut);
        if (sscanf( dum, "%f", &displayclip[1]) != 1) {
            XtRemoveCallback( highcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
            XmTextSetString( highcut, "?????");
            displayclip[1] = clipsav[1];
            return;
            XtAddCallback( highcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        }
        dum = (char *)XmTextGetString( lowcut);
        if (sscanf( dum, "%f", &displayclip[0]) != 1) {
            XtRemoveCallback( lowcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
            XmTextSetString( lowcut, "?????");
            displayclip[0] = clipsav[0];
            return;
            XtAddCallback( lowcut, XmNactivateCallback, (XtCallbackProc) change_clips, (XtPointer) k_newval);
        }
        XmTextSetString( comput, "Computing ...");
        scale_images( );
        XmTextSetString( comput, "Press OK to validate");
        break;
    }
}

void dismiss_clips( Widget w, XtPointer w_code, XmAnyCallbackStruct * cbs)
{
    XtUnmapWidget( clipshell);
}

