/*
 * camapplicationinfo.h - CAM (EN50221) Application Info resource
 * Copyright (C) 2007 Alessandro Decina
 * 
 * Authors:
 *   Alessandro Decina <alessandro@nnva.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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 <string.h>

#include "camapplicationinfo.h"

#define GST_CAT_DEFAULT cam_debug_cat
#define TAG_APPLICATION_INFO_ENQUIRY 0x9F8020
#define TAG_APPLICATION_INFO_REPLY 0x9F8021
#define TAG_APPLICATION_INFO_ENTER_MENU 0x9F8022

static CamReturn session_request_impl (CamALApplication * application,
    CamSLSession * session, CamSLResourceStatus * status);
static CamReturn open_impl (CamALApplication * application,
    CamSLSession * session);
static CamReturn close_impl (CamALApplication * application,
    CamSLSession * session);
static CamReturn data_impl (CamALApplication * application,
    CamSLSession * session, guint tag, guint8 * buffer, guint length);

CamApplicationInfo *
cam_application_info_new ()
{
  CamApplicationInfo *info;
  CamALApplication *application;

  info = g_new0 (CamApplicationInfo, 1);
  application = CAM_AL_APPLICATION (info);
  _cam_al_application_init (application);
  application->resource_id = CAM_AL_APPLICATION_INFO_ID;
  application->session_request = session_request_impl;
  application->open = open_impl;
  application->close = close_impl;
  application->data = data_impl;

  return info;
}

void
cam_application_info_destroy (CamApplicationInfo * info)
{
  _cam_al_application_destroy (CAM_AL_APPLICATION (info));
  g_free (info);
}

static CamReturn
send_simple (CamApplicationInfo * info, CamSLSession * session, guint tag)
{
  guint8 *buffer;
  guint offset;
  guint buffer_size;
  CamReturn ret;

  cam_al_calc_buffer_size (CAM_AL_APPLICATION (info)->al, 0, &buffer_size,
      &offset);
  buffer = g_malloc (buffer_size);

  ret = cam_al_application_write (CAM_AL_APPLICATION (info), session,
      tag, buffer, buffer_size, 0);

  g_free (buffer);

  return ret;
}

static CamReturn
send_application_info_enquiry (CamApplicationInfo * info,
    CamSLSession * session)
{
  GST_DEBUG ("sending application info enquiry");
  return send_simple (info, session, TAG_APPLICATION_INFO_ENQUIRY);
}

static CamReturn
session_request_impl (CamALApplication * application,
    CamSLSession * session, CamSLResourceStatus * status)
{
  *status = CAM_SL_RESOURCE_STATUS_OPEN;

  return CAM_RETURN_OK;
}

static CamReturn
open_impl (CamALApplication * application, CamSLSession * session)
{
  CamApplicationInfo *info = CAM_APPLICATION_INFO (application);

  return send_application_info_enquiry (info, session);
}

static CamReturn
close_impl (CamALApplication * application, CamSLSession * session)
{
  return CAM_RETURN_OK;
}

static CamReturn
handle_application_info_reply (CamApplicationInfo * info,
    CamSLSession * session, guint8 * buffer, guint length)
{
  guint8 type;
  guint8 menu_length;
  gchar menu[255];

  type = buffer[0];
  menu_length = buffer[5];
  menu_length = MIN (menu_length, 255);
  memcpy (menu, buffer + 6, menu_length);
  menu[menu_length] = 0;

  GST_INFO ("application info reply, type: %d, menu: %s", type, menu);

  return CAM_RETURN_OK;
}

static CamReturn
data_impl (CamALApplication * application, CamSLSession * session,
    guint tag, guint8 * buffer, guint length)
{
  CamReturn ret;
  CamApplicationInfo *info = CAM_APPLICATION_INFO (application);

  switch (tag) {
    case TAG_APPLICATION_INFO_REPLY:
      ret = handle_application_info_reply (info, session, buffer, length);
      break;
    default:
      g_return_val_if_reached (CAM_RETURN_ERROR);
  }

  return ret;
}
