/* 
  ==========================================================================
  Tcl interface for MuPDF libray  (see http://mupdf.org)
  ---
  Oct 2020 - A.Buratti fecit
  ==========================================================================
*/

#include <tcl.h>
#include <tclOO.h>
#ifdef USE_TK_STUBS
	#include <tk.h>
#endif

 // sub-modules
#include "MUDoc.h"
#include "MUPage.h"
#include "MUTextSearch.h"

#include "tclMuPDF.h"

  // =======================================================================
  // All Tcl commands/objects will be created in the MU_NS namespace
  // =======================================================================
#define MU_NS "::mupdf::"



// ============================================================================
// mupdf basic commands
// ============================================================================

#include <mupdf/fitz/version.h>

  // Returns info about the current implementation ..
  //    version
  //    ... others to do
static
TclResCode CMD_libinfo( CMD_ARGS ) {
	if (objc != 1) {
		Tcl_WrongNumArgs(interp, 1, objv, NULL);
		return TCL_ERROR;
	}
	//////////////////////////////////////////////////
	Tcl_Obj *objPtr;
	Tcl_Obj *listPtr = Tcl_NewListObj(0,NULL);
	Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj("version",-1));
	Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(FZ_VERSION,-1));
	//////////////////////////////////////////////////
	Tcl_SetObjResult(interp, listPtr);
	return TCL_OK;
}


DLLEXPORT
TclResCode Mupdf_Init(Tcl_Interp* interp) {
	TclResCode res = TCL_OK;
	
	if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
		return TCL_ERROR;
	}
#ifdef USE_TK_STUBS
	if (Tk_InitStubs(interp, "8.6-", 0) == NULL) {
		return TCL_ERROR;
	}
#endif
 	if (TclOOInitializeStubs(interp, "1.0") == NULL) {
		return TCL_ERROR;
	}
	
	
	typedef int (*SetupProcType)(Tcl_Interp *);
	
	 // list of submodules to initialize
	const SetupProcType setupProc[] = {
		MUDoc_Setup,
		MUPage_Setup,
		MUTextSearch_Setup,
		NULL
	};
	
	 // initialize all submodules
	for (int i=0; setupProc[i] != NULL; ++i) {
		if ( setupProc[i](interp) != TCL_OK ) {
			res =TCL_ERROR;
			break;
		}
	}
	
	 // === initialize extra commands =========================================
	const
	struct {
		const char* name;
		TclResCode (*cmd)( CMD_ARGS );
	}
	extra[] = {
		{ MU_NS "libinfo", CMD_libinfo },
		{ NULL, NULL }
	};
	for (int i=0; extra[i].name != NULL; ++i) {
		Tcl_Command cmd;
		cmd = Tcl_CreateObjCommand( interp, extra[i].name, extra[i].cmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL) ;
		res = (cmd ? TCL_OK : TCL_ERROR );		
		if (res != TCL_OK) break;
	}
	return res;	
 }
