/* OpenAmiga.org
 *  This file is part of the OpenAmiga "xfdmaster library project"
 *
 * For more information look at:
 *   http://openamiga.org/?function=viewproject&projectid=67
 */

/****************************************************************************
*   XFD library system for cruncher handling
*   Copyright (C) 1994-1998 by Georg Hörmann
*   Copyright (C) 1998 by Dirk Stöcker <soft@dstoecker.de>
*   Copyright (C) 2014 by Fredrik Wikström <fredrik@a500.org>
*
*   This library is free software; you can redistribute it and/or
*   modify it under the terms of the GNU Lesser General Public
*   License as published by the Free Software Foundation; either
*   version 2.1 of the License, or (at your option) any later version.
*
*   This library 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
*   Lesser General Public License for more details.
*
*   You should have received a copy of the GNU Lesser General Public
*   License along with this library; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
****************************************************************************/

#include <interfaces/xfdmaster.h>
#include "../xfdmaster_vectors.h"
#include "../xfdmaster_internal.h"

/****** xfdmaster.library/xfdRecogSegment ******************************************
*
*   NAME
*      xfdRecogSegment -- Description
*
*   SYNOPSIS
*      BOOL xfdRecogSegment(struct xfdSegmentInfo * segmentinfo);
*
*   FUNCTION
*
*   INPUTS
*       segmentinfo - 
*
*   RESULT
*       The result ...
*
*   EXAMPLE
*
*   NOTES
*
*   BUGS
*
*   SEE ALSO
*
*****************************************************************************
*
*/

BOOL _xfdMaster_xfdRecogSegment(struct xfdMasterIFace *Self,
	struct xfdSegmentInfo *segmentinfo)
{
	DEBUGF("xfdRecogSegment(0x%08lx, 0x%08lx)\n", Self, segmentinfo);
	struct xfdMasterBase *libBase = (struct xfdMasterBase *)Self->Data.LibBase;
	struct ExecIFace *IExec = libBase->xfdm_IExec;
	struct xfdSlave *slave;

	if (segmentinfo->xfdsi_SegList == ZERO) {
		segmentinfo->xfdsi_Error = XFDERR_NOSOURCE;
		return FALSE;
	}

	slave = libBase->xfdm_FirstSlave;
	while (slave != NULL) {
		if (slave->xfds_Version <= XFDS_VERSION &&
			slave->xfds_MasterVersion <= libBase->LibNode.lib_Version &&
			(slave->xfds_PackerFlags & XFDPFF_RELOC) != 0 &&
			slave->xfds_RecogSegment != NULL &&
			((slave->xfds_PackerFlags & XFDPFF_EXTERN) == 0 ||
			(segmentinfo->xfdsi_Flags & XFDFF_RECOGEXTERN) != 0))
		{
			ULONG res;

			if (IExec->IsNative(slave->xfds_RecogSegment)) {
				xfdRecogSegmentFunc func = (xfdRecogSegmentFunc)slave->xfds_RecogSegment;
				res = func(Self, segmentinfo->xfdsi_SegList);
			} else {
				res = IExec->EmulateTags(slave->xfds_RecogSegment,
					ET_SaveParamRegs, TRUE,
					ET_RegisterA0,    segmentinfo->xfdsi_SegList,
					ET_RegisterA6,    libBase,
					TAG_END);
			}
			if (res) {
				segmentinfo->xfdsi_Slave = NULL;
				segmentinfo->xfdsi_PackerName = slave->xfds_PackerName;
				segmentinfo->xfdsi_PackerFlags = slave->xfds_PackerFlags & ~XFDPFF_EXTERN;
				segmentinfo->xfdsi_MaxSpecialLen = slave->xfds_MaxSpecialLen;
				return TRUE;
			}
		}
		slave = slave->xfds_Next;
	}

	segmentinfo->xfdsi_Slave = NULL;
	segmentinfo->xfdsi_PackerName = NULL;
	segmentinfo->xfdsi_PackerFlags = 0;
	segmentinfo->xfdsi_Error = XFDERR_UNKNOWN;
	return FALSE;
}

