//-----------------------------------------------------------------------------
// Copyright © 2003 - Philip Howard - All rights reserved
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//-----------------------------------------------------------------------------
// package	libh/weblogsplit
// homepage	http://libh.slashusr.org/
//-----------------------------------------------------------------------------
// author	Philip Howard
// email	phil@ipal.org
// homepage	http://phil.ipal.org/
//-----------------------------------------------------------------------------
// This file is best viewed using a fixed spaced font such as Courier
// and in a display at least 112 columns wide.
//-----------------------------------------------------------------------------

#include <math.h>
#include <stdio.h>
#include <string.h>

#include <libh/string.h>

//-----------------------------------------------------------------------------
// function	print_num
//
// purpose	Print a number
//
// arguments	1 (long double) number
//
// returns	(int) number of characters in number
//-----------------------------------------------------------------------------
int
print_num (
    long double		arg_num
    )
{
    char	num_buf		[256]	;
    char *	p			;
    char *	q			;
    size_t	len			;

    snprintf( num_buf, sizeof num_buf, "%100.100Lf", arg_num );
    len = strlen( num_buf );
    p = num_buf + len;
    q = p;
    while ( q > num_buf && * -- q == '0' );
    if ( * q == '.' && q < p ) * ++ q = '0';
    * ++ q = 0;
    p = num_buf;
    while ( * p == ' ' ) ++ p;
    fputs( p, stdout );

    return q - p;
}

//-----------------------------------------------------------------------------
// function	main
//
// purpose	Begin here
//
// syntax	[arith|sin|cos|tan|asin|acos|atan] [-opt] value ...
//-----------------------------------------------------------------------------
int
main (
    int		argc
    ,
    char * *	argv
    )
{
    long double		a		;
    long double		d		;
    long double		m		;
    long double		p		;
    long double		r		;

    const char *	n		;
    const char *	s		;

    int			v		;

    p = 2646693125139304345.0L / 842468587426513207.0L;
    m = 1.0L;
    d = 1.0L;
    s = "";
    v = 0;

    n = str_tail( argv[0], '/', 1 );

    while ( -- argc && * ++ argv ) {

	if ( argv[0][0] == '-' ) {
	    if ( argv[0][1] == 0 ) continue;
	    if ( argv[0][2] == 0 ) {
		if ( argv[0][1] == 'd' ) {
		    m = p;
		    d = 180.0L;
		    s = "deg";
		    continue;
		}
		if ( argv[0][1] == 'n' ) {
		    m = 1.0L;
		    d = 1.0L;
		    s = "";
		    continue;
		}
		if ( argv[0][1] == 'r' ) {
		    m = p;
		    d = 2.0L;
		    s = "rad";
		    continue;
		}
		if ( argv[0][1] == 'v' ) {
		    ++v;
		    continue;
		}
		if ( argv[0][1] == 'q' ) {
		    --v;
		    continue;
		}
	    }
	}
	    
	a = str_expr_to_ld( argv[0], NULL );

	if ( strcmp( n, "arith" ) == 0 ) {
	    if ( v > 0 ) {
		printf( "%s = %32.16Lf\n", argv[0], a );
	    } else {
		print_num( a );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "exp" ) == 0 ) {
	    r = expl( ( a * m ) / d );
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "log" ) == 0 ) {
	    r = logl( ( a * m ) / d );
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

#if 0
	if ( strcmp( n, "log2" ) == 0 ) {
	    r = log2l( ( a * m ) / d );
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}
#endif

	if ( strcmp( n, "log10" ) == 0 ) {
	    r = log10l( ( a * m ) / d );
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "sqrt" ) == 0 ) {
	    r = sqrtl( ( a * m ) / d );
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "sin" ) == 0 ) {
	    r = sinl( ( a * m ) / d );
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "cos" ) == 0 ) {
	    r = cosl( ( a * m ) / d );
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "tan" ) == 0 ) {
	    r = tanl( ( a * m ) / d );
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "asin" ) == 0 ) {
	    r = asinl( a ) * d / m;
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "acos" ) == 0 ) {
	    r = acosl( a ) * d / m;
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "atan" ) == 0 ) {
	    r = atanl( a ) * d / m;
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "sinh" ) == 0 ) {
	    r = sinhl( ( a * m ) / d );
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "cosh" ) == 0 ) {
	    r = coshl( ( a * m ) / d );
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "tanh" ) == 0 ) {
	    r = tanhl( ( a * m ) / d );
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "asinh" ) == 0 ) {
	    r = asinhl( a ) * d / m;
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "acosh" ) == 0 ) {
	    r = acoshl( a ) * d / m;
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

	if ( strcmp( n, "atanh" ) == 0 ) {
	    r = atanhl( a ) * d / m;
	    if ( v > 0 ) {
		printf( "%s%s( %s = %32.16Lf ) = %32.16Lf\n", n, s, argv[0], a, r );
	    } else {
		print_num( r );
		fputc( '\n', stdout );
	    }
	    continue;
	}

    }

    return 0;
}

