/*
 * LZ Decompression functions
 *
 * Copyright 1996 Marcus Meissner
 *
 * 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 "winbase.h"
#include "lzexpand.h"

#include "wine/winbase16.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(file);

#define MAX_LZSTATES 16

#define IS_LZ_HANDLE(h) (((h) >= 0x400) && ((h) < 0x400+MAX_LZSTATES))


/***********************************************************************
 *           LZStart   (LZEXPAND.7)
 */
INT16 WINAPI LZStart16(void)
{
    TRACE("(void)\n");
    return 1;
}


/***********************************************************************
 *           LZInit   (LZEXPAND.3)
 */
HFILE16 WINAPI LZInit16( HFILE16 hfSrc )
{
    HFILE ret = LZInit( (HFILE)DosFileHandleToWin32Handle(hfSrc) );
    if (IS_LZ_HANDLE(ret)) return ret;
    if ((INT)ret <= 0) return ret;
    return hfSrc;
}


/***********************************************************************
 *           GetExpandedName   (LZEXPAND.10)
 */
INT16 WINAPI GetExpandedName16( LPCSTR in, LPSTR out )
{
    return (INT16)GetExpandedNameA( in, out );
}


/***********************************************************************
 *           LZRead   (LZEXPAND.5)
 */
INT16 WINAPI LZRead16( HFILE16 fd, LPVOID buf, UINT16 toread )
{
    if (IS_LZ_HANDLE(fd)) return LZRead( fd, buf, toread );
    return _lread( (HFILE)DosFileHandleToWin32Handle(fd), buf, toread );
}


/***********************************************************************
 *           LZSeek   (LZEXPAND.4)
 */
LONG WINAPI LZSeek16( HFILE16 fd, LONG off, INT16 type )
{
    if (IS_LZ_HANDLE(fd)) return LZSeek( fd, off, type );
    return _llseek( (HFILE)DosFileHandleToWin32Handle(fd), off, type );
}


/***********************************************************************
 *           LZCopy   (LZEXPAND.1)
 *
 */
LONG WINAPI LZCopy16( HFILE16 src, HFILE16 dest )
{
    /* already a LZ handle? */
    if (IS_LZ_HANDLE(src)) return LZCopy( src, (HFILE)DosFileHandleToWin32Handle(dest) );

    /* no, try to open one */
    src = LZInit16(src);
    if ((INT16)src <= 0) return 0;
    if (IS_LZ_HANDLE(src))
    {
        LONG ret = LZCopy( src, (HFILE)DosFileHandleToWin32Handle(dest) );
        LZClose( src );
        return ret;
    }
    /* it was not a compressed file */
    return LZCopy( (HFILE)DosFileHandleToWin32Handle(src), (HFILE)DosFileHandleToWin32Handle(dest) );
}


/***********************************************************************
 *           LZOpenFile   (LZEXPAND.2)
 */
HFILE16 WINAPI LZOpenFile16( LPCSTR fn, LPOFSTRUCT ofs, UINT16 mode )
{
    HFILE hfret = LZOpenFileA( fn, ofs, mode );
    /* return errors and LZ handles unmodified */
    if ((INT)hfret <= 0) return hfret;
    if (IS_LZ_HANDLE(hfret)) return hfret;
    /* but allocate a dos handle for 'normal' files */
    return Win32HandleToDosFileHandle((HANDLE)hfret);
}


/***********************************************************************
 *           LZClose   (LZEXPAND.6)
 */
void WINAPI LZClose16( HFILE16 fd )
{
    if (IS_LZ_HANDLE(fd)) LZClose( fd );
    else DisposeLZ32Handle( DosFileHandleToWin32Handle((HFILE)fd) );
}


/***********************************************************************
 *           CopyLZFile   (LZEXPAND.8)
 */
LONG WINAPI CopyLZFile16( HFILE16 src, HFILE16 dest )
{
    TRACE("(%d,%d)\n",src,dest);
    return LZCopy16(src,dest);
}
