/* This is -*- C -*- */
/* $Id: guppi-seq-date-core.c,v 1.1 2002/01/08 06:29:00 trow Exp $ */

/*
 * guppi-seq-date-core-impl.c
 *
 * Copyright (C) 2000 EMC Capital Management, Inc.
 * Copyright (C) 2001 The Free Software Foundation
 *
 * Developed by Jon Trowbridge <trow@gnu.org> and
 * Havoc Pennington <hp@pobox.com>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include <config.h>
#include "guppi-seq-date-core.h"

#include <guppi-convenient.h>
#include <guppi-data-plug-in.h>


static GtkObjectClass *parent_class = NULL;

enum {
  ARG_0
};

static void
guppi_seq_date_core_get_arg (GtkObject *obj, GtkArg *arg, guint arg_id)
{
  switch (arg_id) {

  default:
    break;
  };
}

static void
guppi_seq_date_core_set_arg (GtkObject *obj, GtkArg *arg, guint arg_id)
{
  switch (arg_id) {

  default:
    break;
  };
}

static void
guppi_seq_date_core_destroy (GtkObject *obj)
{
  if (parent_class->destroy)
    parent_class->destroy (obj);
}

static void
guppi_seq_date_core_finalize (GtkObject *obj)
{
  GuppiSeqDateCore *core = GUPPI_SEQ_DATE_CORE (obj);

  guppi_unref0 (core->garray);

  if (parent_class->finalize)
    parent_class->finalize (obj);
}

/***************************************************************************/

static GDate *
v_seq_date_get (GuppiSeqDate *sd, gint i)
{
  GuppiSeqDateCore *core = GUPPI_SEQ_DATE_CORE (sd);
  GDate *data;
  data = (GDate *) guppi_garray_data (core->garray);
  i -= core->index_basis;

  return &data[i];
}

static void
v_seq_date_set (GuppiSeqDate *sd, gint i, GDate *dt)
{
  GuppiSeqDateCore *core = GUPPI_SEQ_DATE_CORE (sd);
  GDate *data;
  data = (GDate *) guppi_garray_data (core->garray);
  data[i - core->index_basis] = *dt;

  if (GUPPI_SEQ_DATE_CLASS (parent_class)->set)
    GUPPI_SEQ_DATE_CLASS (parent_class)->set (sd, i, dt);
}

static void
v_seq_date_insert (GuppiSeqDate *sd, gint i, GDate *dt)
{
  GuppiSeqDateCore *core = GUPPI_SEQ_DATE_CORE (sd);
  GDate *data;
  gint j;

  if (core->size == 0)
    core->index_basis = i;

  i -= core->index_basis;

  if (guppi_garray_size (core->garray) <= core->size)
    guppi_garray_set_size (core->garray, MAX (20, 2 *core->size));

  data = (GDate *) guppi_garray_data (core->garray);
  for (j = core->size - 1; i <= j; --j)
    data[j + 1] = data[j];
  data[i] = *dt;
  ++core->size;

  if (GUPPI_SEQ_DATE_CLASS (parent_class)->insert)
    GUPPI_SEQ_DATE_CLASS (parent_class)->insert (sd, i + core->index_basis, dt);
}

static void
v_seq_size_hint (GuppiSeq *seq, gsize n)
{
  GuppiSeqDateCore *core = GUPPI_SEQ_DATE_CORE (seq);

  if (guppi_garray_size (core->garray) < n)
    guppi_garray_set_size (core->garray, n);

  if (GUPPI_SEQ_CLASS (parent_class)->size_hint)
    GUPPI_SEQ_CLASS (parent_class)->size_hint (seq, n);
}

static void
v_seq_get_bounds (GuppiSeq *seq, gint *min, gint *max)
{
  GuppiSeqDateCore *core = GUPPI_SEQ_DATE_CORE (seq);

  if (min)
    *min = core->index_basis;

  if (max)
    *max = core->index_basis - 1 + core->size;
}

static void
v_seq_shift_indices (GuppiSeq *seq, gint delta)
{
  GuppiSeqDateCore *core = GUPPI_SEQ_DATE_CORE (seq);
  core->index_basis += delta;

  if (GUPPI_SEQ_CLASS (parent_class)->shift_indices)
    GUPPI_SEQ_CLASS (parent_class)->shift_indices (seq, delta);
}

static void
v_seq_delete_many (GuppiSeq *seq, gint i, gsize N)
{
  GuppiSeqDateCore *core = GUPPI_SEQ_DATE_CORE (seq);
  GDate *data;
  gint j;

  data = (GDate *) guppi_garray_data (core->garray);
  i -= core->index_basis;

  for (j = i; j + N < core->size; ++j)
    data[j] = data[j + N];

  core->size -= N;

  if (GUPPI_SEQ_CLASS (parent_class)->delete_many)
    GUPPI_SEQ_CLASS (parent_class)->delete_many (seq, i + core->index_basis, N);
}

static GuppiData *
v_data_copy (GuppiData *d)
{
  g_assert_not_reached ();
  return NULL;
}

static gint
v_data_size_in_bytes (GuppiData *d)
{
  GuppiSeqDateCore *core = GUPPI_SEQ_DATE_CORE (d);
  return guppi_garray_size (core->garray) * sizeof (GDate) + sizeof (GuppiSeqDateCore);
}

static void
guppi_seq_date_core_class_init (GuppiSeqDateCoreClass *klass)
{
  GtkObjectClass *object_class = (GtkObjectClass *) klass;
  GuppiSeqDateClass *date_class = GUPPI_SEQ_DATE_CLASS (klass);
  GuppiSeqClass *seq_class = GUPPI_SEQ_CLASS (klass);
  GuppiDataClass *data_class = GUPPI_DATA_CLASS (klass);

  parent_class = gtk_type_class (GUPPI_TYPE_SEQ_DATE);

  date_class->get = v_seq_date_get;
  date_class->set = v_seq_date_set;
  date_class->insert = v_seq_date_insert;

  seq_class->size_hint = v_seq_size_hint;
  seq_class->get_bounds = v_seq_get_bounds;
  seq_class->shift_indices = v_seq_shift_indices;
  seq_class->delete_many = v_seq_delete_many;
  seq_class->support_missing_values = TRUE;

  data_class->copy = v_data_copy;
  data_class->get_size_in_bytes = v_data_size_in_bytes;
  data_class->is_leaf_type = TRUE;

  object_class->get_arg = guppi_seq_date_core_get_arg;
  object_class->set_arg = guppi_seq_date_core_set_arg;
  object_class->destroy = guppi_seq_date_core_destroy;
  object_class->finalize = guppi_seq_date_core_finalize;

}

static void
guppi_seq_date_core_init (GuppiSeqDateCore *obj)
{
  obj->index_basis = 0;
  obj->size = 0;
  obj->garray = guppi_garray_new (sizeof (GDate));
}

GtkType guppi_seq_date_core_get_type (void)
{
  static GtkType guppi_seq_date_core_type = 0;
  if (!guppi_seq_date_core_type) {
    static const GtkTypeInfo guppi_seq_date_core_info = {
      "GuppiSeqDateCore",
      sizeof (GuppiSeqDateCore),
      sizeof (GuppiSeqDateCoreClass),
      (GtkClassInitFunc) guppi_seq_date_core_class_init,
      (GtkObjectInitFunc) guppi_seq_date_core_init,
      NULL, NULL, (GtkClassInitFunc) NULL
    };
    guppi_seq_date_core_type =
      gtk_type_unique (GUPPI_TYPE_SEQ_DATE,
		       &guppi_seq_date_core_info);
  }
  return guppi_seq_date_core_type;
}

GuppiSeqDate *
guppi_seq_date_core_new (void)
{
  return GUPPI_SEQ_DATE (guppi_type_new (guppi_seq_date_core_get_type ()));
}


/* $Id: guppi-seq-date-core.c,v 1.1 2002/01/08 06:29:00 trow Exp $ */


syntax highlighted by Code2HTML, v. 0.9.1