/******************************************************************************
 *    ScriptLib.h
 *
 *    This file is part of Object Script Library
 *    Copyright (C) 2005-2009 Tom N Harris <telliamed@whoopdedo.org>
 *
 *    Permission is hereby granted, free of charge, to any person obtaining
 *    a copy of this software and associated documentation files (the 
 *    "Software"), to deal in the Software without restriction, including 
 *    without limitation the rights to use, copy, modify, merge, publish, 
 *    distribute, sublicense, and/or sell copies of the Software, and to 
 *    permit persons to whom the Software is furnished to do so.
 *    
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 *    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 *    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-
 *    INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 *    BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 
 *    AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 
 *    IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
 *    THE SOFTWARE.
 *
 *****************************************************************************/
#ifndef SCRIPTLIB_H
#define SCRIPTLIB_H

#if _MSC_VER > 1000
#pragma once
#endif

#include <lg/config.h>
#include <lg/objstd.h>
#include <lg/interface.h>
#include <lg/types.h>
#include <lg/scrservices.h>
#include <lg/scrmanagers.h>
#include <lg/links.h>

interface IScript;

/****************
 * Globals
 * The hosting app/module must define these.
 */
extern IMalloc* g_pMalloc;
extern IScriptMan* g_pScriptManager;


/* An unassigned cMultiParm. Useful for filling in default arguments. */
/* DEPRECATED use cMultiParm::Undef instead */
extern const cMultiParm g_mpUndef;

/* Game-dependent string constants. */
extern const char* g_pszDesignNote;
extern const char* g_pszCDLinkFlavor;

/*************
 * Properties
 */

// Read parameters from the Editor\DesignNote property.
// Strings are allocated using g_pMalloc. Please use Free.

// Returns the whole Design Note.
// Useful to save time if you're reading a lot of params.
char* GetObjectParams(int iObject);
int SetObjectParams(int iObject, const char* pszParams);
// Returns the param as a particular type.
char* GetObjectParamString(int iObject, const char* pszParam, const char* pszDefault = NULL);
int GetObjectParamInt(int iObject, const char* pszParam, int iDefault = 0);
float GetObjectParamFloat(int iObject, const char* pszParam, float iDefault = 0.0f);
bool GetObjectParamBool(int iObject, const char* pszParam, bool bDefault = false);
int SetObjectParamString(int iObject, const char* pszParam, const char* pszVal);
int SetObjectParamInt(int iObject, const char* pszParam, int iVal);
int SetObjectParamFloat(int iObject, const char* pszParam, float fVal);
int SetObjectParamBool(int iObject, const char* pszParam, bool bVal);
// Same, but uses the supplied string instead of extracting from the object.
char* GetParamString(const char* pszString, const char* pszParam, const char* pszDefault = NULL);
int GetParamInt(const char* pszString, const char* pszParam, int iDefault = 0);
float GetParamFloat(const char* pszString, const char* pszParam, float fDefault = 0.0f);
bool GetParamBool(const char* pszString, const char* pszParam, bool bDefault = false);
char* SetParamString(char* pszString, const char* pszParam, const char* pszVal);
char* SetParamInt(char* pszString, const char* pszParam, int iVal);
char* SetParamFloat(char* pszString, const char* pszParam, float fVal);
char* SetParamBool(char* pszString, const char* pszParam, bool bVal);
// Delete a specific parameter from the Design Note.
// All occurances of the parameter are removed.
bool RemoveObjectParam(int iObject, const char* pszParam);

int GetObjectParamObject(int iObject, const char* pszParam, int iDefault = 0);
int GetParamObject(const char* pszString, const char* pszParam, int iDefault = 0);
int GetObjectParamTime(int iObject, const char* pszParam, int iDefault = 0);
int GetParamTime(const char* pszString, const char* pszParam, int iDefault = 0);


/***********
 * Metaproperties
 */

// These functions take care to not put more than one instance 
// of a metaproperty on an object.
int AddSingleMetaProperty(const char* pszMetaProp, int iObjId);
int AddSingleMetaProperty(int iMetaProp, int iObjId);
int RemoveSingleMetaProperty(const char* pszMetaProp, int iObjId);
int RemoveSingleMetaProperty(int iMetaProp, int iObjId);
// Simple add and replace. Allows for duplicates.
int AddMetaProperty(const char* pszMetaProp, int iObjId);
int RemoveMetaProperty(const char* pszMetaProp, int iObjId);


/********
 * Links
 */
typedef int (*LinkIterCallbackFunc)(ILinkSrv*,ILinkQuery*,IScript*,void*);

// GetOne... - return the first link found.
// GetAny... - Randomly select a link from all that exist.
// ...Inheritedxxx - Crawl up the inheritence tree for the source or dest 
//     until a match is found. For GetAny, the crawl will stop at the first 
//     object found with a valid link.
// ...ByData - Filter based on link data. If the length is -1, a case-insensitive
//     string comparison is used.

long GetOneLink(const char* pszFlavor, int iSource, int iDest, sLink* pResult);
long GetOneLinkInheritedSrc(const char* pszFlavor, int iSource, int iDest, sLink* pResult);
int GetOneLinkDest(const char* pszFlavor, int iSource);
long GetOneLinkByData(const char* pszFlavor, int iSource, int iDest, sLink* pResult, const void* pvData, int iDataLen);
long GetOneLinkByDataInheritedSrc(const char* pszFlavor, int iSource, int iDest, sLink* pResult, const void* pvData, int iDataLen);
int GetOneLinkByDataDest(const char* pszFlavor, int iSource, const void* pvData, int iDataLen);
long GetAnyLink(const char* pszFlavor, int iSource, int iDest, sLink* pResult);
long GetAnyLinkInheritedSrc(const char* pszFlavor, int iSource, int iDest, sLink* pResult);
int GetAnyLinkDest(const char* pszFlavor, int iSource);
long GetAnyLinkByData(const char* pszFlavor, int iSource, int iDest, sLink* pResult,
			    const void* pvData, int iDataLen);
long GetAnyLinkByDataInheritedSrc(const char* pszFlavor, int iSource, int iDest, sLink* pResult,
			    const void* pvData, int iDataLen);
int GetAnyLinkByDataDest(const char* pszFlavor, int iSource, const void* pvData, int iDataLen);
// The iterator callback should be a static member function. 
// (Or just a regular non-member function.)
// Iteration will be halted if the callback returns 0.
long IterateLinks(const char* pszFlavor, int iSource, int iDest,
			    LinkIterCallbackFunc pfnLinkIterCallback, IScript* pScript, void* pData);
long IterateLinksByData(const char* pszFlavor, int iSource, int iDest,
			    const void* pvFilter, int iFilterLen,
			    LinkIterCallbackFunc pfnLinkIterCallback, IScript* pScript, void* pData);
void DeleteAllLinks(const char* pszFlavor, int iSource, int iDest);
void DeleteAllLinksByData(const char* pszFlavor, int iSource, int iDest, const void* pvData, int iDataLen);

// Any links between the source and the object that's the source of a PlayerFactory link
// will be relinked so the source points to the actual Player object.
void FixupPlayerLinks(int iSource, int iPlayer);


/***********
 * Messages
 */

void SimpleSend(int iSource, int iDest, const char* pszMessage,
		    const cMultiParm& mpData1 = g_mpUndef, const cMultiParm& mpData2 = g_mpUndef, const cMultiParm& mpData3 = g_mpUndef);
void SimplePost(int iSource, int iDest, const char* pszMessage,
		    const cMultiParm& mpData1 = g_mpUndef, const cMultiParm& mpData2 = g_mpUndef, const cMultiParm& mpData3 = g_mpUndef);
long CDSend(const char* pszMessage, int iSource);
long CDSend(const char* pszMessage, int iSource, const cMultiParm& mpData);


/*************
 * MultiParms
 */

// The cMultiParm class provides for direct assignment and casting.
// This is mostly for setting the pReply in ReceiveMessage.
void MultiParmAssignInt(sMultiParm* pParm, int iValue);
void MultiParmAssignFloat(sMultiParm* pParm, float fValue);
void MultiParmAssignString(sMultiParm* pParm, const char* pszValue);
void MultiParmAssignVector(sMultiParm* pParm, const mxs_vector* pvValue);


/*************
 * Objects
 */

int StrToObject(const char* pszName);


/***********
 * User
 */

int CalcTextTime(const char* pszText, int iWordTime = 500);
int ShowBook(int iObject, bool bArt, int iTime = 0);
void ShowString(const char* pszStr, int iTime, COLORREF color = 0);
__attribute__((format (printf,1,2)))
	void DebugPrintf(const char* pszFormat, ...);
__attribute__((format (printf,1,2)))
	void DisplayPrintf(const char* pszFormat, ...);


/************
 * Utils
 */
__attribute__((nonnull (1,2)))
	char* strsep(char** str, const char* delim);
__attribute__((nonnull (1,2,3)))
	char* strqsep(char** str, const char* delim, const char* quotes);

int strtocolor(const char* str);
int strtotime(const char* str);

#endif // SCRIPTLIB_H
