#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//
#include "proto.h"
#include "bucket.h"
#include "main.h"
#include "flash.h"
#include "matrix.h"
#include "action.h"
#include "button.h"



static BUTTONSOUND *buttonsounds;
static S32 buttonsoundcount = 0;



S32 button_write(BUTTON *button) {

  U32 ptr, i, defined, notdefined;

  if (button->count == 0)                                   return 1;

  if (flush_bucket())                                       return 1;
  ptr = read_position(NULL);
  if (write_ushort(0))                                      return 1;
  if (write_ushort(button->id))                             return 1;

  // figure out which states have been defined
  defined = 0;
  for (i = 0; i < button->count; i++) {
    BUTTONSTATE *state;
    state = button->states+i;
    defined |= state->state;
  }
  // make bitfield with undefined states
  notdefined = defined ^ (BUTTONSTATE_UP   | BUTTONSTATE_OVER |
                          BUTTONSTATE_DOWN | BUTTONSTATE_SHAPE);
  // write all states
  for (i = 0; i < button->count; i++) {
    BUTTONSTATE *state;
    state = button->states+i;
    if (write_ubyte(state->state | notdefined))             return 1;
    if (write_ushort(state->id))                            return 1;
    if (write_ushort(state->depth))                         return 1;
    if (matrix_write(&state->matrix))                       return 1;
  }
  // write 'end of states'
  if (write_ubyte(0))                                       return 1;
  // if there are any actions, write them
  if (button->actioncount)
    if (action_write_list(button->actions, button->actioncount))
                                                            return 1;
  return update_record_header(stagDefineButton, ptr);
}


S32 button_create(BUTTON **button) {

  *button = malloc(sizeof(BUTTON));
  if (!*button)                         return 1;
  memset(button, 0, sizeof(BUTTON));

  return 1;
}



S32 buttonsound_add(BUTTONSOUND *bs) {

  if (!buttonsounds) {
    buttonsounds = malloc(sizeof(BUTTONSOUND));
    if (!buttonsounds)        return 1;
  } else {
    BUTTONSOUND *newbs;
    newbs = realloc(buttonsounds, (buttonsoundcount+1)*sizeof(BUTTONSOUND));
    if (!newbs)               return 1;
    buttonsounds = newbs;
  }

  memcpy(buttonsounds+buttonsoundcount, bs, sizeof(BUTTONSOUND));
  buttonsoundcount++;

  return 0;
}


S32 buttonsound_write_all() {

  S32 i;

  for (i = 0; i < buttonsoundcount; i++) {
    S32 transition, size;

    size = 2;                 // button id
    for (transition = 0; transition < 4; transition++) {
      size += 2;              // sound id
      if (buttonsounds[i].soundids[transition]) {
        size += 1;            // flags
        if (buttonsounds[i].loops[transition] > 1)  size += 2; // loop
      }
    }

    if (write_ushort((stagDefineButtonSound<<6) | size))    return 1;
    if (write_ushort(buttonsounds[i].buttonid))             return 1;
    for (transition = 0; transition < 4; transition++) {
      if (write_ushort(buttonsounds[i].soundids[transition]))  return 1;
      if (buttonsounds[i].soundids[transition]) {
        switch (buttonsounds[i].loops[transition]) {
        case 0:
          if (write_ubyte(0x20))                            return 1;
          break;
        case 1:
          if (write_ubyte(0))                               return 1;
          break;
        default:
          if (write_ubyte(0x04))                            return 1;
          if (write_ushort(buttonsounds[i].loops[transition]))   return 1;
          break;
        }
      }
    }
  }
  return 0;
}
