#include <stdio.h>
//
#include "proto.h"
#include "bucket.h"
#include "cxform.h"
#include "bitcount.h"


S32 cxform_write(CXFORM *cxform, S32 usealpha) {

  U32 bits, bits2, add, mul;
  S16 addr, addg, addb, adda, mulr, mulg, mulb, mula;

  if (flush_bucket())                             return 1;

  addr = cxform->addr;
  addg = cxform->addg;
  addb = cxform->addb;
  if (usealpha)
    adda = cxform->adda;
  else
    adda  = 0;
  mulr = cxform->mulr;
  mulg = cxform->mulg;
  mulb = cxform->mulb;
  if (usealpha)
    mula = cxform->mula;
  else
    mula = 255;

  if ((addr != 0) || (addg != 0) || (addb != 0) || (adda != 0))
    add = 1;
  else
    add = 0;

  if ((mulr != 255) || (mulg != 255) || (mulb != 255) || (mula != 255))
    mul = 1;
  else
    mul = 0;

  if (write_ubits(1, add))                        return 1;
  if (write_ubits(1, mul))                        return 1;

  bits = bitcount_signed(addr, addg, addb, adda);
  bits2 = bitcount_signed(mulr, mulg, mulb, mula);
  if (bits2 > bits)   bits = bits2;
  if (write_ubits(4, bits))                       return 1;

  if (mul) {
    if (write_bits(bits, mulr))                   return 1;
    if (write_bits(bits, mulg))                   return 1;
    if (write_bits(bits, mulb))                   return 1;
    if (usealpha)
      if (write_bits(bits, mula))                 return 1;
  }

  if (add) {
    if (write_bits(bits, addr))                   return 1;
    if (write_bits(bits, addg))                   return 1;
    if (write_bits(bits, addb))                   return 1;
    if (usealpha)
      if (write_bits(bits, adda))                 return 1;
  }

  return 0;
}



S32 cxform_is_empty(CXFORM *cxform) {

  if ((cxform->mulr != 255)  ||
      (cxform->mulg != 255)  ||
      (cxform->mulb != 255)  ||
      (cxform->mula != 255)  ||
      (cxform->addr != 0)    ||
      (cxform->addg != 0)    ||
      (cxform->addb != 0)    ||
      (cxform->addr != 0))              return 0;

  return 1;
}


U32 cxform_count_bits(CXFORM *cxform, S32 usealpha) {

  U32 max, bits;
  S32 r, g, b, a;

  bits = 6;

  if (usealpha) {
    r = cxform->mulr;
    g = cxform->mulg;
    b = cxform->mulb;
    a = cxform->mula;
    if ((r != 255) || (g != 255) || (b != 255) || (a != 255)) {
      max = bitcount_signed(r, g, b, a);
      bits += 4*max;
    }
    r = cxform->addr;
    g = cxform->addg;
    b = cxform->addb;
    a = cxform->adda;
    if ((r != 0) || (g != 0) || (b != 0) && (a != 0)) {
      max = bitcount_signed(r, g, b, a);
      bits += 4*max;
    }
  } else {
    r = cxform->mulr;
    g = cxform->mulg;
    b = cxform->mulb;
    if ((r != 255) || (g != 255) || (b != 255)) {
      max = bitcount_signed(r, g, b, 0);
      bits += 3*max;
    }
    r = cxform->addr;
    g = cxform->addg;
    b = cxform->addb;
    if ((r != 0) || (g != 0) || (b != 0)) {
      max = bitcount_signed(r, g, b, 0);
      bits += 3*max;
    }
  }

  return bits;
}


void cxform_reset(CXFORM *cxform) {

  cxform->mulr = cxform->mulg = cxform->mulb = cxform->mula = 255;
  cxform->addr = cxform->addg = cxform->addb = cxform->adda = 0;
}
