/*
 * op call program copyright (C) 2009 - 2013 H.Niwa
 */


/*
 * 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <errno.h>
#include <setjmp.h>
#include <sys/time.h>
#include <math.h>
#include <libgen.h>
#include <setjmp.h>

#include <string>
#include <complex>

#include "syserr.h"

#include "bin_node.h"
#include "gc.h"
#include "var.h"
#include "pred.h"
#include "context.h"
#include "unify.h"
#include "builtin.h"
#include "sysmodule.h"
#include "expression.h"
#include "let.h"
#include "func.h"
#include "token.h"
#include "module.h"
#include "code.h"
#include "timeout.h"
#include "help.h"
#include "ncurlib.h"
#include "lisp.h"
#include "complx.h"
#include "compiler.h"
#include "matrix.h"
#include "generator.h"
#include "lib_include.h"
#include "opcall.h"



int OpCall(Context* cx, Node* goalscar, List* module)
{
	int r;
	
	goalscar = goalscar->Cdr();
	if (ListLength(goalscar) <= 0) {
		syserr("usage: <opcall OPNUM [ARG..]>\n");
		return 0;
	}
	
	Node* nop = goalscar->Car();
	if (nop->kind() != ATOM) {
		syserr("usage: <opcall OPNUM [ARG..]>\n");
		return 0;
	}
		
	long long op;
	if (!((Atom*)nop)->toInt(op)) {
		syserr("usage: <opcall OPNUM [ARG..]>\n");
		return 0;
	}

	switch(op) {

#if HAVE_LIBNCURSES && !defined(__MINGW32__)
	case CURS_STARTCURSES :
		r = curs_startcurses(cx, goalscar, module);
		return r;
	case CURS_MVPRINTW :
		r = curs_mvprintw(cx, goalscar, module);
		return r;
	case CURS_PRINTW :
		r = curs_printw(cx, goalscar, module);
		return r;
	case CURS_REFRESH :
		r = curs_refresh(cx, goalscar, module);
		return r;
	case CURS_MOVE :
		r = curs_move(cx, goalscar, module);
		return r;
	case CURS_CBREAK :
		r = curs_cbreak(cx, goalscar, module);
		return r;
	case CURS_NOCBREAK :
		r = curs_nocbreak(cx, goalscar, module);
		return r;
	case CURS_RAW :
		r = curs_raw(cx, goalscar, module);
		return r;
	case CURS_NORAW :
		r = curs_noraw(cx, goalscar, module);
		return r;
	case CURS_ECHO :
		r = curs_echo(cx, goalscar, module);
		return r;
	case CURS_NOECHO :
		r = curs_noecho(cx, goalscar, module);
		return r;
	case CURS_ERASE :
		r = curs_erase(cx, goalscar, module);
		return r;
	case CURS_CLEAR :
		r = curs_clear(cx, goalscar, module);
		return r;
	case CURS_GETCH :
		r = curs_getch(cx, goalscar, module);
		return r;
	case CURS_UNGETCH :
		r = curs_ungetch(cx, goalscar, module);
		return r;
	case CURS_GETSTR :
		r = curs_getstr(cx, goalscar, module);
		return r;
	case CURS_INCH :
		r = curs_inch(cx, goalscar, module);
		return r;
	case CURS_INSTR :
		r = curs_instr(cx, goalscar, module);
		return r;
	case CURS_ISENDWIN :
		r = curs_isendwin(cx, goalscar, module);
		return r;
	case CURS_BEEP :
		r = curs_beep(cx, goalscar, module);
		return r;
	case CURS_FLASH :
		r = curs_flash(cx, goalscar, module);
		return r;
	case CURS_HLINE :
		r = curs_hline(cx, goalscar, module);
		return r;
	case CURS_VLINE :
		r = curs_vline(cx, goalscar, module);
		return r;
	case CURS_KEYPAD :
		r = curs_keypad(cx, goalscar, module);
		return r;
	case CURS_SCROLLOK :
		r = curs_scrollok(cx, goalscar, module);
		return r;
	case CURS_SCRL :
		r = curs_scrl(cx, goalscar, module);
		return r;
	case CURS_LINES :
		r = curs_LINES(cx, goalscar, module);
		return r;
	case CURS_COLS :
		r = curs_COLS(cx, goalscar, module);
		return r;
	case CURS_DELCH :
		r = curs_delch(cx, goalscar, module);
		return r;
	case CURS_MVDELCH :
		r = curs_mvdelch(cx, goalscar, module);
		return r;
	case CURS_CLRTOBOT :
		r = curs_clrtobot(cx, goalscar, module);
		return r;
	case CURS_CLRTOEOL :
		r = curs_clrtoeol(cx, goalscar, module);
		return r;
	case CURS_BORDER :
		r = curs_border(cx, goalscar, module);
		return r;
#endif /* HAVE_LIBNCURSES && !defined(__MINGW32__) */

	case COMPCHECKRESERVED :
		r = CompCheckReserved(cx, goalscar, module);
		return r;
	case COMPGETVAR :
		r = CompGetVar(cx, goalscar, module);
		return r;
	case COMPADDVAR :
		r = CompAddVar(cx, goalscar, module);
		return r;
	case COMPCHECKVAR :
		r = CompCheckVar(cx, goalscar, module);
		return r;
	case COMPNEWFUNC :
		r = CompNewFunc(cx, goalscar, module);
		return r;
	case COMPENDFUNC :
		r = CompEndFunc(cx, goalscar, module);
		return r;

	case MATRIXZERO :
		r = matrix_zero(cx, goalscar, module);
		return r;
	case MATRIXUNIT :
		r = matrix_unit(cx, goalscar, module);
		return r;
	case MATRIXSET :
		r = matrix_set(cx, goalscar, module);
		return r;
	case MATRIXDISPLAY :
		r = matrix_display(cx, goalscar, module);
		return r;
	case MATRIXADD :
		r = matrix_add(cx, goalscar, module);
		return r;
	case MATRIXSUB :
		r = matrix_sub(cx, goalscar, module);
		return r;
	case MATRIXMUL :
		r = matrix_mul(cx, goalscar, module);
		return r;
	case MATRIXMULSCALAR :
		r = matrix_mulscalar(cx, goalscar, module);
		return r;
	case MATRIXDIVSCALAR :
		r = matrix_divscalar(cx, goalscar, module);
		return r;
	case MATRIXTRA :
		r = matrix_tra(cx, goalscar, module);
		return r;
	case MATRIXEQ :
		r = matrix_equal(cx, goalscar, module);
		return r;
	case MATRIXNOTEQ :
		r = matrix_notequal(cx, goalscar, module);
		return r;
	case MATRIXDIM :
		r = matrix_dimentions(cx, goalscar, module);
		return r;
	case MATRIXGETROW :
		r = matrix_getrow(cx, goalscar, module);
		return r;
	case MATRIXGETCOLUMN :
		r = matrix_getcolumn(cx, goalscar, module);
		return r;
	case MATRIXSWAPROW :
		r = matrix_swaprow(cx, goalscar, module);
		return r;
	case MATRIXSWAPCOLUMN :
		r = matrix_swapcolumn(cx, goalscar, module);
		return r;
	case MATRIXRANGEROW :
		r = matrix_rangerow(cx, goalscar, module);
		return r;
	case MATRIXRANGECOLUMN :
		r = matrix_rangecolumn(cx, goalscar, module);
		return r;
	case MATRIXRANGE :
		r = matrix_range(cx, goalscar, module);
		return r;
	case MATRIXISMATRIX :
		r = matrix_ismatrix(cx, goalscar, module);
		return r;
	case MATRIXISVECTOR :
		r = matrix_isvector(cx, goalscar, module);
		return r;
	case MATRIXISSQUARE :
		r = matrix_issquare(cx, goalscar, module);
		return r;
	case MATRIXISNULL :
		r = matrix_isnull(cx, goalscar, module);
		return r;
	case MATRIXISDIAGONAL :
		r = matrix_isdiagonal(cx, goalscar, module);
		return r;
	case MATRIXISSYMMETRIC :
		r = matrix_issymmetric(cx, goalscar, module);
		return r;
	case MATRIXISREGULAR :
		r = matrix_isregular(cx, goalscar, module);
		return r;
	case MATRIXISSINGULAR :
		r = matrix_issingular(cx, goalscar, module);
		return r;
	case MATRIXDET :
		r = matrix_det(cx, goalscar, module);
		return r;
	case MATRIXINV :
		r = matrix_inv(cx, goalscar, module);
		return r;
	case MATRIXRANDOM :
		r = matrix_random(cx, goalscar, module);
		return r;
	case MATRIXGETVAL :
		r = matrix_getrow_column(cx, goalscar, module);
		return r;
	case MATRIXSETVAL :
		r = matrix_setrow_column(cx, goalscar, module);
		return r;
	case MATRIXSOLVE :
		r = matrix_solve(cx, goalscar, module);
		return r;
	case MATRIXEIGEN :
		r = matrix_eigen(cx, goalscar, module);
		return r;
	case MATRIXFOURIER :
		r = matrix_fourier(cx, goalscar, module);
		return r;
	case MATRIXINVFOURIER :
		r = matrix_invfourier(cx, goalscar, module);
		return r;
	case MATRIXROWSORTASND :
		r = matrix_row_sort_ascending(cx, goalscar, module);
		return r;
	case MATRIXROWSORTDESND :
		r = matrix_row_sort_descending(cx, goalscar, module);
		return r;
	case MATRIXCOLUMNSORTASND :
		r = matrix_column_sort_ascending(cx, goalscar, module);
		return r;
	case MATRIXCOLUMNSORTDESND :
		r = matrix_column_sort_descending(cx, goalscar, module);
		return r;
	case MATRIXCOPY :
		r = matrix_copy(cx, goalscar, module);
		return r;
	case GENPERMREP :
		r = generator_perm_rep(cx, goalscar, module);
		return r;
	case GENCOMBIREP :
		r = generator_combi_rep(cx, goalscar, module);
		return r;
	case GENPERM :
		r = generator_permutation(cx, goalscar, module);
		return r;
	case GENCOMBI :
		r = generator_combination(cx, goalscar, module);
		return r;
	case GENPERMALL :
		r = generator_permutationAll(cx, goalscar, module);
		return r;
	case GENCOMBIALL :
		r = generator_combinationAll(cx, goalscar, module);
		return r;
	}
	
	syserr("invalid op code : %d\n", op);
	return 0;			
}
