/*
    GDAM - Geoff & Dave's Audio Mixer
    Copyright (C) 1999    Dave Benson, Geoff Matters.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser 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

    Contact:
        daveb@ffem.org <Dave Benson>
        geoff@ugcs.caltech.edu <Geoff Matters>
*/
#ifndef __GDAMTURNTABLE_SKIN__H_
#define __GDAMTURNTABLE_SKIN__H_

#include "gdamskin.h"
#include "gtktrackdisplay.h"
#include <gdam/component/gdamturntable.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkdrawingarea.h>

typedef struct _GdamTurntableSkinClass GdamTurntableSkinClass;
typedef struct _GdamTurntableSkin GdamTurntableSkin;


GtkType gdam_turntable_skin_get_type();
#define GDAM_TYPE_TURNTABLE_SKIN              (gdam_turntable_skin_get_type ())
#define GDAM_TURNTABLE_SKIN(obj)              (GTK_CHECK_CAST ((obj), GDAM_TYPE_TURNTABLE_SKIN, GdamTurntableSkin))
#define GDAM_TURNTABLE_SKIN_CLASS(klass)      (GTK_CHECK_CLASS_CAST ((klass), GDAM_TYPE_TURNTABLE_SKIN, GdamTurntableSkinClass))
#define GDAM_IS_TURNTABLE_SKIN(obj)           (GTK_CHECK_TYPE ((obj), GDAM_TYPE_TURNTABLE_SKIN))
#define GDAM_IS_TURNTABLE_SKIN_CLASS(klass)   (GTK_CHECK_CLASS_TYPE ((klass), GDAM_TYPE_TURNTABLE_SKIN))

struct _GdamTurntableSkinClass {
	GdamSkinClass		skin_class;
	void          (*match_tempo)(GdamTurntableSkin* turntable_skin);
};


struct _GdamTurntableSkin {
	GdamSkin		base;
	GtkAdjustment*		resample_adj;
	GtkContainer*		producer_container;
	GtkLabel*		anchored_label;
	GtkLabel*		time_label;
	GtkLabel*		hour_label;
	GtkLabel*		minute_label;
	GtkLabel*		second_label;
	gboolean		user_dragging_resample;
	GdamSkin*               producer_skin;
	char*			producer_name;
	char*			producer_skin_name;
	double			timer_origin;
	double			last_time;
	double			last_rate_nudge;
	double			last_song_nudge;

	/*  As a hack, we keep track of the event state of button press
	    events, so that we are aware of the state when the "clicked"
	    callback is called.  */
	guint			event_state;
	  /* timeouts which we must remove on destruction. */
	int       		timer_id;
	int       		playing_arg_connect_id;
	int       		play_or_synch_arg_connect_id;
	int       		anchored_arg_connect_id;

	GtkTrackDisplay*        track_display;
	gboolean		fine_rate_control;

	/* track nudging and automatically correct tempo as
	 * user corrects phase.
	 * TODO: this belongs in model, not skin.
	 */
	gboolean                is_tracking_nudge;
	/* When within the song the user indicated 'in sync' */
	gdouble			autotempo_time_start;
	/* Amount of nudging user has done since time_start, seconds */
	gdouble 		autotempo_nudge_amount;

	/* A more natural interface to autotempo, the user taps
	 * out a target rhythm and we deduce tempo and phase from
	 * that.  To average out timing wobbles, we save up pending 
	 * nudges until phase_count reaches some value then apply
	 * the average nudge.  _count is reset and that makes one
	 * cycle.  the first cycle, we adjust only phase.  after
	 * that, we assume each cycle starts out in phase, and
	 * our nudges are sent to the autotempo function. */
	int			tap_phase_count;
	int			tap_phase_cycle_count;
	/* total amount of pending nudge, in beats */
	gdouble			tap_phase_pending_nudge;
	GTimeVal		first_tap_timeval;
	GTimeVal		last_tap_timeval;
	gdouble			last_tap_beat_period;
	int			num_taps;  /* redundant?? */
	/* To visually track state of tap interpreter 
	 * 0 = not started
	 * 1 = counting initial estimate
	 * 2 = have initial estimate, now tracking phase
	 * 3 = phase stable
	 */
	int			tap_status;
	gdouble			tap_latency;
};


typedef struct _NudgeInfo {
	GdamTurntableSkin*	skin;
	GdamTurntable* 		turntable;
	float			amount;
} NudgeInfo;

#if 0
gboolean	gdam_turntable_skin_set_producer(	
						GdamTurntableSkin* 	skin,
						const char* 	component_name, 
						const char* 	skin_name);
#endif


#endif
