#ifndef XPKMASTER_PROGRESS_C
#define XPKMASTER_PROGRESS_C

/* Routinesheader

	Name:		progress.c
	Main:		xpkmaster
	Versionstring:	$VER: progress.c 1.4 (26.03.1998)
	Author:		SDI
	Distribution:	Freeware
	Description:	Progress report handler

 1.0   06.10.96 : first real version
 1.1   24.03.97 : added auto hook, changed speed calculation
 1.2   25.04.97 : changed time calculation
 1.3   09.01.98 : added XPK_ALLINONE
 1.4   26.03.98 : a bit shorter exe code
*/

#include <proto/exec.h>
#include <proto/intuition.h>
#include <xpk/xpkprefs.h>
#include "xpkmaster.h"

XPK_ALLINONE LONG callprogress(struct XpkBuffer *xbuf)
{
  struct XpkProgress *prog = &xbuf->xb_Prog;
  struct Hook *hk = xbuf->xb_ChunkHook;
  struct XpkPrefsSemaphore *sem = 0;

  if(!hk && (xbuf->xb_Flags & XMF_AUTOPRHOOK) && (sem = GetPrefsSem()))
    hk = sem->xps_ProgressHook;

  if(hk)
  {
    ULONG ucur, ulen;

    if((ucur = prog->xp_UCur) && (ulen = prog->xp_ULen))
    {
      ULONG secs;
      LONG mics;

      CurrentTime (&secs, (ULONG *) &mics);
      secs -= xbuf->xb_Secs;
      mics -= xbuf->xb_Mics;

      /* 7813 = 100000 / 128, 0x20000000 = 0x100000000/128 (ULONG size),
         +1 prevents division by zero */
      if(ucur < 0x20000000)
        prog->xp_Speed = (ucur<<7) / ((secs<<7) + mics/7813 + 1);
      else
        prog->xp_Speed = ucur / ++secs;

      prog->xp_Done = 100 * ucur/ulen;
      prog->xp_CF = 100 - 100 * prog->xp_CCur / ucur;
    }
    if(prog->xp_CF < 0)
      prog->xp_CF = 0;

    if((*(regfunc) hk->h_Entry) (hk, prog, 0 A4SUPP2))
      xbuf->xb_Result = XPKERR_ABORTED;
  }

  if(sem)
    ReleaseSemaphore((struct SignalSemaphore *) sem);

  return xbuf->xb_Result;
}

#endif /* XPKMASTER_PROGRESS_C */
