# These routine provide for coordinate conversions between gif
# postscript and user coordinates
#
# They assume that axes already exist on the gif with origin
# at (gmid_x, gmid_y) and ends at (gmin_x, gmax_x) etc
# 
# Find gif coords with xv (middle button)
# NOTE that the GIF y axis is "upside down!
#
# Similary the ps coords of axes tips are given by pmin_x, etc
# Note that the clipping window may extend beyond the ends of the axes
# NOTE that ps coords are also positive in the down direction
#

###############################################################
#
# subroutine gifsize - set gif axes limits and origin
#
# arguments gmin_x, gmax_x, gmin_y, gmax_y, gmid_x, gmid_y

sub gifsize {
    local($gmx1, $gmx2, $gmy1, $gmy2, $gdx, $gdy) = @_;

    $gmin_x = $gmx1;  $gmax_x = $gmx2; $gmin_y = $gmy1;  $gmax_y = $gmy2;
    $gmid_x = $gdx;  # use this as x=0
    $gmid_y = $gdy;  # use this as y=0
    return 1;
}

###############################################################
#
# subroutine pssize  - set ps axes limits
#
# arguments pmin_x, pmax_x, pmin_y, pmax_y

sub pssize {
    local($pmx1, $pmx2, $pmy1, $pmy2) = @_;

    $pmin_x = $pmx1;  $pmax_x = $pmx2; $pmin_y = $pmy1;  $pmax_y = $pmy2;
    return 1;
}


###############################################################
#
# subroutine sizetofit - scale user units to fit on axes
#
# arguments xmax, ymax
#
# Sets xunits and yunits, the  pixel to user unit ratios
# Sets umin_x, etc to be axes end points in user coords
# These values are used in coord conversions
#
# WARNINGS: The arguments xmax, ymax must be positive.  
#           &gifsize must be called first

sub sizetofit {
    local($xmax, $ymax) = @_;

    if ($debug > 0) {system("echo sizetofit called with $xmax, $ymax >> erlog");}

    # choose units -- origin is at gmid_x, gmid_y
    
    $xunits = ($gmax_x - $gmid_x) / $xmax; 
    $yunits = ($gmid_y - $gmax_y) / $ymax; # gif coords positive is down

    # set global variables

    $umin_x = ($gmin_x - $gmid_x) / $xunits;
    $umax_x = ($gmax_x - $gmid_x) / $xunits;
    $umin_y = ($gmid_y - $gmin_y) / $yunits;
    $umax_y = ($gmid_y - $gmax_y) / $yunits;

    if ($debug > 0) {system("echo ux=$umin_x, $umax_x uy=$umin_y, $umax_y >> erlog");}

    return 1;
}



###############################################################
#
# subroutine u2p - convert user coords to ps coords
#
# arguments ux, uy


sub u2p {
    local($x, $y) = @_;

    $mu2px = ($pmax_x - $pmin_x)/($umax_x - $umin_x);
    $mu2py = ($pmax_y - $pmin_y)/($umax_y - $umin_y);

    
    $tx = sprintf("%.2f", $mu2px * ($x - $umin_x) + $pmin_x);
    $ty = sprintf("%.2f", $mu2py * ($y - $umin_y) + $pmin_y);

    return ( $tx, $ty );
}

###############################################################
#
# subroutine p2u - convert user coords to ps coords
#
# arguments px, py


sub p2u {
    local($x, $y) = @_;

    $mp2ux = ($umax_x - $umin_x)/($pmax_x - $pmin_x);
    $mp2uy = ($umax_y - $umin_y)/($pmax_y - $pmin_y);

    
    $tx = sprintf("%.2f", $mp2ux * ($x - $pmin_x) + $umin_x);
    $ty = sprintf("%.2f", $mp2uy * ($y - $pmin_y) + $umin_y);

    return ( $tx, $ty );
}


###############################################################
#
# subroutine g2p - convert user coords to ps coords
#
# arguments gx, gy


sub g2p {
    local($x, $y) = @_;

    $mg2px = ($pmax_x - $pmin_x)/($gmax_x - $gmin_x);
    $mg2py = ($pmax_y - $pmin_y)/($gmax_y - $gmin_y);

    
    $tx = sprintf("%.2f", $mg2px * ($x - $gmin_x) + $pmin_x);
    $ty = sprintf("%.2f", $mg2py * ($y - $gmin_y) + $pmin_y);

    return ( $tx, $ty );
}


###############################################################
#
# subroutine p2g - convert user coords to ps coords
#
# arguments px, py


sub p2g {
    local($x, $y) = @_;

    $mp2gx = ($pmax_x - $pmin_x)/($gmax_x - $gmin_x);
    $mp2gy = ($pmax_y - $pmin_y)/($gmax_y - $gmin_y);

    $tx = sprintf("%.2f", $mp2gx * ($x - $gmin_x) + $pmin_x);
    $ty = sprintf("%.2f", $mp2gy * ($y - $gmin_y) + $pmin_y);

    return ( $tx, $ty );
}


###############################################################
#
# subroutine u2g - convert user coords to ps coords
#
# arguments ux, uy


sub u2g {
    local($x, $y) = @_;

    $mu2gx = ($gmax_x - $gmin_x)/($umax_x - $umin_x);
    $mu2gy = ($gmax_y - $gmin_y)/($umax_y - $umin_y);

    
    $tx = sprintf("%.2f", $mu2gx * ($x - $umin_x) + $gmin_x);
    $ty = sprintf("%.2f", $mu2gy * ($y - $umin_y) + $gmin_y);

    return ( $tx, $ty );
}

###############################################################
#
# subroutine g2u - convert user coords to ps coords
#
# arguments gx, gy


sub g2u {
    local($x, $y) = @_;

    $mg2ux = ($umax_x - $umin_x)/($gmax_x - $gmin_x);
    $mg2uy = ($umax_y - $umin_y)/($gmax_y - $gmin_y);

    
    $tx = sprintf("%.2f", $mg2ux * ($x - $gmin_x) + $umin_x);
    $ty = sprintf("%.2f", $mg2uy * ($y - $gmin_y) + $umin_y);

    return ( $tx, $ty );
}
###############################################################
#
# subroutine xticks - draw in good tick marks
#


sub xticks {
    local($t, $tx, $ty, $tyu, $typ, $txp, $e);
    local($tickunit, $tickmax, $tickmin);

    $tickunit = ($umax_x - $umin_x) / 5;

    if ($debug > 1){system("echo xtick $umin_x $umax_x $tickunit >> erlog");}

    for $e (-2..4) {
	if ($tickunit >= 10**$e && $tickunit < 10**($e+1)) {
	    $tickunit = (10**$e) * int($tickunit / (10**$e) );
	}
    }

    $tickmax = int($umax_x / $tickunit);
    $tickmin = int($umin_x / $tickunit);

    if ($tickmax - $tickmin > 6) {
	$tickmax = int($tickmax/ 2);
	$tickmin = int($tickmin/ 2);
	$tickunit *= 2;
    }

    print TMP "\n% draw x ticks \n\n";
    for $t ($tickmin..$tickmax) {
	if ($t != 0) {
	    $tick = sprintf("%.2f", $t * $tickunit);
	    ($tx, $ty) = &u2p($tick, 0);
	    $tyu = $ty + 5;
	    $typ = $ty + 20;
	    $txp = $tx - 8;
	    if($tickunit>=2){
	       $tick = sprintf("%.1f", $tick);
	    }
	    print TMP "newpath  $tx $ty moveto $tx $tyu lineto stroke \n";
	    print TMP "/Helvetica findfont 12.00 scalefont setfont \n";
	    print TMP "$txp $typ moveto gsave ($tick) show grestore\n\n";
	}
    }
}

sub yticks {
    local($t, $tx, $ty, $tyu, $typ, $txp, $e);
    local($tickunit, $tickmax, $tickmin);

    $tickunit = ($umax_y - $umin_y) / 5;

    for $e (-2..4) {
	if ($tickunit >= 10**$e && $tickunit < 10**($e+1)) {
	    $tickunit = (10**$e) * int($tickunit / (10**$e) );
	}
    }

    if ($deubg > 0) {system("echo yticks $umin_y $umax_y $tickunit >> erlog")};

    $tickmax = int($umax_y / $tickunit);
    $tickmin = int($umin_y / $tickunit);

    if ($tickmax - $tickmin > 6) {
	$tickmax = int($tickmax / 2);
	$tickmin = int($tickmin/ 2);
	$tickunit *= 2;
    }

    print TMP "\n % draw y ticks \n\n";
    for $t ($tickmin..$tickmax) {
	if ($t != 0) {
	    $tick = sprintf("%.2f", $t * $tickunit);
	    ($tx, $ty) = &u2p(0, $tick);
	    $txr = $tx +  5;
	    $typ = $ty + 3;
	    $txp = $tx + 10;
	    if($tickunit>=2){
	       $tick = sprintf("%.1f", $tick);
	    }
	    print TMP "newpath $tx $ty moveto $txr $ty lineto stroke \n";
	    print TMP "/Helvetica findfont 12.00 scalefont setfont \n";
	    print TMP "$txp $typ moveto gsave ($tick) show grestore\n\n";
	}
    }
}

1;
