/*=========================================================================*/
/*                                                                         */
/* ICOWRITE.C                                                              */
/*                                                                         */
/* Responsible for writing the icon out to an external ICO file.           */
/*                                                                         */
/* (C) Copyright 1990, 1991  Marc Adler/Magma Systems  All Rights Reserved */
/*                                                                         */
/*=========================================================================*/

#include <stdio.h>
#include <ctype.h>
#include <memory.h>
#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <string.h>
#include <windows.h>
#include "ico.h"


int ICOWrite(pszFile, hBits)
  char *pszFile;
  HANDLE hBits;
{
  int    fd;
  int    i;
  char   pFilename[65];
  PSTR   pszZeros;
  PSTR   pANDMask;
  int    nTotalBytesPerLine;
  LPSTR  lpBits;
  LPBITMAPINFO lpbmi;
  extern BYTE rgb[16][3];


  /*
    Open the file for writing. Make sure it has an ICO extension.
  */
  strcpy(pFilename, pszFile);
  if (strchr(pFilename, '.') == NULL)
    strcat(pFilename, ".ico");
  if ((fd = open(pFilename, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT,
                            S_IREAD | S_IWRITE)) < 0)
  {
    MessageBox(hWndMain, "Couldn't open file", NULL, MB_OK);
    return FALSE;
  }


  /*
    Fill the icon file with 766 bytes of zeros
  */
  pszZeros = (PSTR) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, 766);
  write(fd, pszZeros, 766);
  LocalFree((HANDLE) pszZeros);
  lseek(fd, 0L, 0);

  /*
    Write out the icon file header and directory entry. Then write
    the bitmap header and color information.
  */
  write(fd, (char *) &IconHeader, sizeof(IconHeader));
  write(fd, (char *) &IconDir, sizeof(IconDir));
  lpbmi = (LPBITMAPINFO) GlobalLock(IconInfo.hBitmapInfo);
  lpbmi->bmiHeader.biHeight = IconDir.Height * 2;
  _lwrite(fd, (LPSTR) lpbmi, sizeof(BITMAPINFOHEADER) + 16*sizeof(RGBQUAD));
  GlobalUnlock(IconInfo.hBitmapInfo);


  /*
    Write the AND mask.
  */
  pANDMask = (PSTR) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
                                        IconDir.Width*IconDir.Height/8);
  if (pANDMask == NULL)
  {
    MessageBox(hWndMain, "Can't allocate AND mask buffer", NULL, MB_OK);
    return FALSE;
  }
  lseek(fd, (long)
        IconDir.icoDIBOffset+IconDir.icoDIBSize-(IconDir.Width*IconDir.Height/8),
        0);
  write(fd, pANDMask, IconDir.Width*IconDir.Height/8);
  /*
    Free the AND mask buffer
  */
  LocalFree((HANDLE) pANDMask);


  /*
    Figure out the number of bytes per line
  */
  switch (IconDir.ColorCount)
  {
    case 2 : /* 1 byte = 8 pixels */
      nTotalBytesPerLine = IconDir.Width / 8;
      break;
    case 8 : /* 1 byte = 2 pixels??? */
      nTotalBytesPerLine = IconDir.Width / 2;
      break;
    case 16 : /* 1 byte = 2 pixels */
      nTotalBytesPerLine = IconDir.Width / 2;
      break;
  }

  /*
    Write out the image
  */
  lseek(fd, (long)
        IconDir.icoDIBOffset + IconDir.icoDIBSize -
        (IconDir.Width * IconDir.Height / 8) -
        (nTotalBytesPerLine * IconDir.Height),
        0);
  if ((lpBits = GlobalLock(hBits)) == NULL)
  {
    MessageBox(hWndMain, "Can't lock the bit buffer", NULL, MB_OK);
  }
  else
  {
    _lwrite(fd, lpBits, (int) (nTotalBytesPerLine * IconDir.Height));
    GlobalUnlock(hBits);
  }


  /*
    Close the file and clear the "dirty" bit.
  */
  close(fd);
  IconInfo.fFlags &= ~STATE_DIRTY;
  return TRUE;
}
