/* vim: set sw=3 ts=3 sts=3 expandtab: */
#include "ecdb.h"

int ecdb_erase_project_init(Ecdb_Erase_Project *proj);
static void ecdb_erase_progress_handler(void *data, void *buffer,
                                                         unsigned int nbyte);
int ecdb_erase_finished(void *data, int type, void *event);
   
Ecdb_Erase_Project *
ecdb_erase_project_new(void)
{
   Ecdb_Erase_Project *proj;

   proj = calloc(1, sizeof(Ecdb_Erase_Project));
   if (!proj)
   {
      return NULL;
   }
   
   if (!ecdb_erase_project_init(proj))
   {
      FREE(proj);
      return NULL;
   }

   return proj;
}

int
ecdb_erase_project_init(Ecdb_Erase_Project *proj)
{
   if (!ecdb_project_init(ECDB_PROJECT(proj)))
   {
      return FALSE;
   }

   /* Proper defaults */
   ecdb_project_type_set(ECDB_PROJECT(proj), ECDB_ERASE_PROJECT);
   proj->quick = TRUE;
   proj->format = FALSE;

   return TRUE;
}

void
ecdb_erase_project_destroy(Ecdb_Erase_Project *proj)
{
   ecdb_project_destroy(ECDB_PROJECT(proj));
   FREE(proj);
}

// FIXME Make this return an error code
int
ecdb_erase_disc(Ecdb_Erase_Project *proj)
{
   BurnDriveStatus disc_state;
   pthread_t progress_update;

   disc_state = burn_disc_get_status(ECDB_PROJECT(proj)->drive->
                                                         tangible[0].drive);
   if (disc_state == BURN_DISC_BLANK)
   {
      printf("Disc is already blank!\n");
      return FALSE;
   }
   else if (disc_state == BURN_DISC_EMPTY)
   {
      printf("No disc!\n");
      return FALSE;
   }
   else if (!burn_disc_erasable(ECDB_PROJECT(proj)->drive->
                     tangible[0].drive))
   {
      printf("Not able to erase!\n");
      return FALSE;
   }
   else if (disc_state == BURN_DISC_FULL || BURN_DISC_APPENDABLE)
   {
      printf("Beginning to erase disc!\n");
      ECDB_PROJECT(proj)->pipe = ecore_pipe_add(ecdb_erase_progress_handler,
                                                            proj);
      burn_disc_erase(ECDB_PROJECT(proj)->drive->tangible[0].drive,
                                                            proj->quick);
      pthread_create(&progress_update, NULL, ecdb_drive_progress_update, proj);
      pthread_detach(progress_update);
      ECDB_PROJECT(proj)->ev_handler = ecore_event_handler_add
            (ECDB_DRIVE_ACTION_FINISHED, ecdb_erase_finished, proj);
      return TRUE;
   }
   else
   {
      printf("Not of erasable type\n");
      return FALSE;
   }
}

static void
ecdb_erase_progress_handler(void *data, void *buffer, unsigned int nbyte)
{
   BurnProgress *p;
   Evas_Object *swallow;
   static int last_sector = 0;
   Edje_Message_Int_Set *progress_msg;

   printf("In progress handler, %d, %d\n", sizeof(BurnProgress), nbyte);
   if (nbyte != sizeof(BurnProgress))
   {
      ecore_event_add(ECDB_DRIVE_ACTION_FINISHED, NULL, NULL, NULL);
      printf("Adding event to queue.\n");
      last_sector = 0;
      return;
   }
   else
   {
      p = buffer;
   }


   /* Libburn reports p->sector as being 0 right at the end of the job,
    * so store the last sector and use that to determine the proper
    * percentage/sector to set
    */
   if (last_sector <= p->sector)
   {
      last_sector = p->sector;
   }
   else
   {
      last_sector = p->sectors;
   }

   swallow = evas_object_name_find(ecore_evas_get(em->main_win_ee),
                                                         "erase_page");

   progress_msg = alloca(sizeof(Edje_Message_Int_Set) + (4 * sizeof(int)));
   progress_msg->count = 5;
   progress_msg->val[0] = (int)((double)(last_sector + 1) /
                  (double)p->sectors * 100.0);
   progress_msg->val[1] = last_sector;
   progress_msg->val[2] = p->sectors;
   progress_msg->val[3] = (int)p->buffer_available;
   progress_msg->val[4] = (int)p->buffer_capacity;
   edje_object_message_send(swallow, EDJE_MESSAGE_INT_SET, 0, progress_msg);
}

int
ecdb_erase_finished(void *data, int type, void *event)
{
   Ecdb_Erase_Project *proj;

   proj = data;

   burn_drive_release(ECDB_PROJECT(proj)->drive->tangible[0].drive, 0);
   burn_drive_info_free(ECDB_PROJECT(proj)->drive->tangible);
   ecore_event_handler_del(ECDB_PROJECT(proj)->ev_handler);
   ecore_pipe_del(ECDB_PROJECT(proj)->pipe);
   ecdb_erase_project_destroy(proj);
   ecdb_erase_cleanup();

   return TRUE;
}

