/*
 * Copyright 1999 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 <stdio.h>
#include <assert.h>
#include <string.h>
#include "windef.h"
#include "windows.h"
#include "mmsystem.h"
#include "vfw.h"


int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
{
    int			n;
    HRESULT		hres;
    HMODULE		avifil32 = LoadLibrary("avifil32.dll");
    PAVIFILE		avif;
    PAVISTREAM		vids,auds;
    AVIFILEINFO		afi;
    AVISTREAMINFO	asi;

void	(WINAPI *fnAVIFileInit)(void);
void	(WINAPI *fnAVIFileExit)(void);
ULONG	(WINAPI *fnAVIFileRelease)(PAVIFILE);
ULONG	(WINAPI *fnAVIStreamRelease)(PAVISTREAM);
HRESULT (WINAPI *fnAVIFileOpen)(PAVIFILE * ppfile,LPCTSTR szFile,UINT uMode,LPCLSID lpHandler);
HRESULT (WINAPI *fnAVIFileInfo)(PAVIFILE ppfile,AVIFILEINFO *afi,LONG size);
HRESULT (WINAPI *fnAVIFileGetStream)(PAVIFILE ppfile,PAVISTREAM *afi,DWORD fccType,LONG lParam);
HRESULT (WINAPI *fnAVIStreamInfo)(PAVISTREAM iface,AVISTREAMINFO *afi,LONG size);

#define XX(x) fn##x = (void*)GetProcAddress(avifil32,#x);assert(fn##x);
#ifdef UNICODE
# define XXT(x) fn##x = (void*)GetProcAddress(avifil32,#x"W");assert(fn##x);
#else
# define XXT(x) fn##x = (void*)GetProcAddress(avifil32,#x"A");assert(fn##x);
#endif
	/* Non character dependent routines: */
	XX (AVIFileInit);
	XX (AVIFileExit);
	XX (AVIFileRelease);
	XX (AVIStreamRelease);
	XX (AVIFileGetStream);
	/* A/W routines: */
	XXT(AVIFileOpen);
	XXT(AVIFileInfo);
	XXT(AVIStreamInfo);
#undef XX
#undef XXT

    fnAVIFileInit();
    if (GetFileAttributes(cmdline) == INVALID_FILE_ATTRIBUTES) {
    	fprintf(stderr,"Usage: aviinfo <avifilename>\n");
	exit(1);
    }
    hres = fnAVIFileOpen(&avif,cmdline,OF_READ,NULL);
    if (hres) {
    	fprintf(stderr,"AVIFileOpen: 0x%08lx\n",hres);
	exit(1);
    }
    hres = fnAVIFileInfo(avif,&afi,sizeof(afi));
    if (hres) {
    	fprintf(stderr,"AVIFileInfo: 0x%08lx\n",hres);
	exit(1);
    }
    fprintf(stderr,"AVI File Info:\n");
    fprintf(stderr,"\tdwMaxBytesPerSec: %ld\n",afi.dwMaxBytesPerSec);
#define FF(x) if (afi.dwFlags & AVIFILEINFO_##x) fprintf(stderr,#x",");
    fprintf(stderr,"\tdwFlags: 0x%lx (",afi.dwFlags);
    FF(HASINDEX);FF(MUSTUSEINDEX);FF(ISINTERLEAVED);FF(WASCAPTUREFILE);
    FF(COPYRIGHTED);
    fprintf(stderr,")\n");
#undef FF
#define FF(x) if (afi.dwCaps & AVIFILECAPS_##x) fprintf(stderr,#x",");
    fprintf(stderr,"\tdwCaps: 0x%lx (",afi.dwCaps);
    FF(CANREAD);FF(CANWRITE);FF(ALLKEYFRAMES);FF(NOCOMPRESSION);
    fprintf(stderr,")\n");
#undef FF
    fprintf(stderr,"\tdwStreams: %ld\n",afi.dwStreams);
    fprintf(stderr,"\tdwSuggestedBufferSize: %ld\n",afi.dwSuggestedBufferSize);
    fprintf(stderr,"\tdwWidth: %ld\n",afi.dwWidth);
    fprintf(stderr,"\tdwHeight: %ld\n",afi.dwHeight);
    fprintf(stderr,"\tdwScale: %ld\n",afi.dwScale);
    fprintf(stderr,"\tdwRate: %ld\n",afi.dwRate);
    fprintf(stderr,"\tdwLength: %ld\n",afi.dwLength);
    fprintf(stderr,"\tdwEditCount: %ld\n",afi.dwEditCount);
    fprintf(stderr,"\tszFileType: %s\n",afi.szFileType);

    for (n = 0;n<afi.dwStreams;n++) {
    	    char buf[5];
	    PAVISTREAM	ast;

	    hres = fnAVIFileGetStream(avif,&ast,0,n);
	    if (hres) {
		fprintf(stderr,"AVIFileGetStream %d: 0x%08lx\n",n,hres);
		exit(1);
	    }
	    hres = fnAVIStreamInfo(ast,&asi,sizeof(asi));
	    if (hres) {
		fprintf(stderr,"AVIStreamInfo %d: 0x%08lx\n",n,hres);
		exit(1);
	    }
	    fprintf(stderr,"Stream %d:\n",n);
	    buf[4]='\0';memcpy(buf,&(asi.fccType),4);
	    fprintf(stderr,"\tfccType: %s\n",buf);
	    memcpy(buf,&(asi.fccHandler),4);
	    fprintf(stderr,"\tfccHandler: %s\n",buf);
	    fprintf(stderr,"\tdwFlags: 0x%08lx\n",asi.dwFlags);
	    fprintf(stderr,"\tdwCaps: 0x%08lx\n",asi.dwCaps);
	    fprintf(stderr,"\twPriority: %d\n",asi.wPriority);
	    fprintf(stderr,"\twLanguage: %d\n",asi.wLanguage);
	    fprintf(stderr,"\tdwScale: %ld\n",asi.dwScale);
	    fprintf(stderr,"\tdwRate: %ld\n",asi.dwRate);
	    fprintf(stderr,"\tdwStart: %ld\n",asi.dwStart);
	    fprintf(stderr,"\tdwLength: %ld\n",asi.dwLength);
	    fprintf(stderr,"\tdwInitialFrames: %ld\n",asi.dwInitialFrames);
	    fprintf(stderr,"\tdwSuggestedBufferSize: %ld\n",asi.dwSuggestedBufferSize);
	    fprintf(stderr,"\tdwQuality: %ld\n",asi.dwQuality);
	    fprintf(stderr,"\tdwSampleSize: %ld\n",asi.dwSampleSize);
	    fprintf(stderr,"\tdwEditCount: %ld\n",asi.dwEditCount);
	    fprintf(stderr,"\tdwFormatChangeCount: %ld\n",asi.dwFormatChangeCount);
	    fprintf(stderr,"\tszName: %s\n",asi.szName);
	    switch (asi.fccType) {
	    case streamtypeVIDEO:
	    	vids = ast;
		break;
	    case streamtypeAUDIO:
	    	auds = ast;
		break;
	    default:  {
	    	char type[5];
		type[4]='\0';memcpy(type,&(asi.fccType),4);

	    	fprintf(stderr,"Unhandled streamtype %s\n",type);
		break;
	    }
	    }
	    fnAVIStreamRelease(ast);
    }
    fnAVIFileRelease(avif);
    fnAVIFileExit();
    return 0;
}
