
/*
 * CINELERRA
 * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
 * Copyright (C) 2003-2016 Cinelerra CV contributors
 *
 * 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 "automation.h"
#include "autos.h"
#include "clip.h"
#include "cplayback.h"
#include "cwindow.h"
#include "cwindowgui.h"
#include "edits.h"
#include "edl.h"
#include "edlsession.h"
#include "gwindowgui.h"
#include "keyframe.h"
#include "labels.h"
#include "localsession.h"
#include "maincursor.h"
#include "mainmenu.h"
#include "mainsession.h"
#include "mtimebar.h"
#include "mwindow.h"
#include "mwindowgui.h"
#include "patchbay.h"
#include "playbackengine.h"
#include "plugin.h"
#include "pluginset.h"
#include "resourcethread.h"
#include "samplescroll.h"
#include "theme.h"
#include "trackcanvas.h"
#include "tracks.h"
#include "track.h"
#include "transportque.h"
#include "zoombar.h"


void MWindow::update_plugins()
{
// Show plugins which are visible and hide plugins which aren't
// Update plugin pointers in plugin servers
}


int MWindow::expand_sample()
{
	if(gui)
	{
		if(edl->local_session->zoom_sample < 0x100000)
		{
			edl->local_session->zoom_sample *= 2;
			gui->zoombar->sample_zoom->update(edl->local_session->zoom_sample);
			zoom_sample(edl->local_session->zoom_sample);
		}
	}
	return 0;
}

int MWindow::zoom_in_sample()
{
	if(gui)
	{
		if(edl->local_session->zoom_sample > 1)
		{
			edl->local_session->zoom_sample /= 2;
			gui->zoombar->sample_zoom->update(edl->local_session->zoom_sample);
			zoom_sample(edl->local_session->zoom_sample);
		}
	}
	return 0;
}

int MWindow::zoom_sample(int64_t zoom_sample)
{
	CLAMP(zoom_sample, 1, 0x100000);
	edl->local_session->zoom_sample = zoom_sample;
	find_cursor();

	TimelinePane *pane = gui->get_focused_pane();
	samplemovement(edl->local_session->view_start[pane->number], pane->number);
	return 0;
}

void MWindow::find_cursor()
{
	TimelinePane *pane = gui->get_focused_pane();
	edl->local_session->view_start[pane->number] =
		Units::round((edl->local_session->get_selectionend(1) +
		edl->local_session->get_selectionstart(1)) /
		2 *
		edl->session->sample_rate /
		edl->local_session->zoom_sample -
		(double)pane->canvas->get_w() /
		2);

	if(edl->local_session->view_start[pane->number] < 0)
		edl->local_session->view_start[pane->number] = 0;
}


void MWindow::fit_selection()
{
	if(EQUIV(edl->local_session->get_selectionstart(1),
		edl->local_session->get_selectionend(1)))
	{
		double total_samples = edl->tracks->total_length() *
			edl->session->sample_rate;
		TimelinePane *pane = gui->get_focused_pane();
		for(edl->local_session->zoom_sample = 1;
			pane->canvas->get_w() * edl->local_session->zoom_sample < total_samples;
			edl->local_session->zoom_sample *= 2)
			;
	}
	else
	{
		double total_samples = (edl->local_session->get_selectionend(1) -
			edl->local_session->get_selectionstart(1)) *
			edl->session->sample_rate;
		TimelinePane *pane = gui->get_focused_pane();
		for(edl->local_session->zoom_sample = 1;
			pane->canvas->get_w() * edl->local_session->zoom_sample < total_samples;
			edl->local_session->zoom_sample *= 2)
			;
	}

	edl->local_session->zoom_sample = MIN(0x100000,
		edl->local_session->zoom_sample);
	zoom_sample(edl->local_session->zoom_sample);
}


void MWindow::fit_autos(int all)
{
	float min = 0, max = 0;
	double start, end;

// Test all autos
	if(EQUIV(edl->local_session->get_selectionstart(1),
		edl->local_session->get_selectionend(1)))
	{
		start = 0;
		end = edl->tracks->total_length();
	}
	else
// Test autos in highlighting only
	{
		start = edl->local_session->get_selectionstart(1);
		end = edl->local_session->get_selectionend(1);
	}

	int forstart = edl->local_session->zoombar_showautotype;
	int forend   = edl->local_session->zoombar_showautotype + 1;

	if( all ) {
		forstart = 0;
		forend   = AUTOGROUPTYPE_COUNT;
	}

	for (int i = forstart; i < forend; i++)
	{
// Adjust min and max
		edl->tracks->get_automation_extents(&min, &max, start, end, i);
//printf("MWindow::fit_autos %d %f %f results in ", i, min, max);

		float range = max - min;
		switch (i)
		{
		case AUTOGROUPTYPE_AUDIO_FADE:
			if (range < 1) {
				min = MIN(min, edl->local_session->automation_mins[i]);
				max = MAX(max, edl->local_session->automation_maxs[i]);
				if( min >= max-0.1 ) { min = -80.0; min = 6.0; }
			}
			break;
		case AUTOGROUPTYPE_VIDEO_FADE:
			if (range < 1) {
				min = MIN(min, edl->local_session->automation_mins[i]);
				max = MAX(max, edl->local_session->automation_maxs[i]);
				if( min >= max-0.1 ) { min = 0.0; min = 100.0; }
			}
			break;
		case AUTOGROUPTYPE_ZOOM:
			if (range < 0.001) {
				min = floor(min*50)/100;
				max = floor(max*200)/100;
			}
			break;
		case AUTOGROUPTYPE_SPEED:
			if (range < 0.001) {
				min = floor(min*5)/100;
				max = floor(max*300)/100;
			}
			break;
		case AUTOGROUPTYPE_X:
		case AUTOGROUPTYPE_Y:
			if (range < 1) {
				float scale = bmin(edl->session->output_w, edl->session->output_h);
				min = floor((min+max)/2) - 0.5*scale;
				max = floor((min+max)/2) + 0.5*scale;
			}
			break;
		}
//printf("%f %f\n", min, max);
		if (!Automation::autogrouptypes_fixedrange[i])
		{
			edl->local_session->automation_mins[i] = min;
			edl->local_session->automation_maxs[i] = max;
		}
	}

// Show range in zoombar
	gui->zoombar->update();

// Draw
	gui->draw_overlays(1);
}


void MWindow::change_currentautorange(int autogrouptype, int increment, int changemax)
{
	float val;
	if (changemax) {
		val = edl->local_session->automation_maxs[autogrouptype];
	} else {
		val = edl->local_session->automation_mins[autogrouptype];
	}

	if (increment)
	{
		switch (autogrouptype) {
		case AUTOGROUPTYPE_AUDIO_FADE:
			val += 2;
			break;
		case AUTOGROUPTYPE_VIDEO_FADE:
			val += 1;
			break;
		case AUTOGROUPTYPE_ZOOM:
		case AUTOGROUPTYPE_SPEED:
			if (val == 0)
				val = 0.001;
			else
				val = val*2;
			break;
		case AUTOGROUPTYPE_X:
		case AUTOGROUPTYPE_Y:
			val = floor(val + 50);
			break;
		}
	}
	else
	{ // decrement
		switch (autogrouptype) {
		case AUTOGROUPTYPE_AUDIO_FADE:
			val -= 2;
			break;
		case AUTOGROUPTYPE_VIDEO_FADE:
			val -= 1;
			break;
		case AUTOGROUPTYPE_ZOOM:
		case AUTOGROUPTYPE_SPEED:
			if (val > 0) val = val/2;
			break;
		case AUTOGROUPTYPE_X:
		case AUTOGROUPTYPE_Y:
			val = floor(val-50);
			break;
		}
	}

	AUTOMATIONVIEWCLAMPS(val, autogrouptype);

	if (changemax) {
		if (val > edl->local_session->automation_mins[autogrouptype])
			edl->local_session->automation_maxs[autogrouptype] = val;
	}
	else
	{
		if (val < edl->local_session->automation_maxs[autogrouptype])
			edl->local_session->automation_mins[autogrouptype] = val;
	}
}

void MWindow::update_autorange(int type, int increment, int use_max)
{
	gui->lock_window("MWindow::update_autorange");
	int group = Automation::autogrouptype(type, 0);
	change_currentautorange(group, increment, use_max);
	int color = GWindowGUI::auto_colors[type];
	gui->zoombar->update_autozoom(group, color);
	gui->draw_overlays(0);
	gui->update_patchbay();
	gui->flash_canvas(1);
	gui->unlock_window();
}

void MWindow::expand_autos(int changeall, int domin, int domax)
{
	if (changeall)
		for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) {
			if (domin) change_currentautorange(i, 1, 0);
			if (domax) change_currentautorange(i, 1, 1);
		}
	else
	{
		if (domin) change_currentautorange(edl->local_session->zoombar_showautotype, 1, 0);
		if (domax) change_currentautorange(edl->local_session->zoombar_showautotype, 1, 1);
	}
	gui->zoombar->update_autozoom();
	gui->draw_overlays(0);
	gui->update_patchbay();
	gui->flash_canvas(1);
}

void MWindow::shrink_autos(int changeall, int domin, int domax)
{
	if (changeall)
		for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) {
			if (domin) change_currentautorange(i, 0, 0);
			if (domax) change_currentautorange(i, 0, 1);
		}
	else
	{
		if (domin) change_currentautorange(edl->local_session->zoombar_showautotype, 0, 0);
		if (domax) change_currentautorange(edl->local_session->zoombar_showautotype, 0, 1);
	}
	gui->zoombar->update_autozoom();
	gui->draw_overlays(0);
	gui->update_patchbay();
	gui->flash_canvas(1);
}


void MWindow::zoom_autos(float min, float max)
{
	int i = edl->local_session->zoombar_showautotype;
	edl->local_session->automation_mins[i] = min;
	edl->local_session->automation_maxs[i] = max;
	gui->zoombar->update_autozoom();
	gui->draw_overlays(1);
}


void MWindow::zoom_amp(int64_t zoom_amp)
{
	edl->local_session->zoom_y = zoom_amp;
	gui->draw_canvas(0, 0);
	gui->flash_canvas(0);
	gui->update_patchbay();
	gui->flush();
}

void MWindow::zoom_atrack(int64_t zoom)
{
	int64_t old_zoom = edl->local_session->zoom_atrack;
	CLAMP(zoom, MIN_TRACK_ZOOM, MAX_TRACK_ZOOM);
	edl->local_session->zoom_atrack = zoom;

	edl->local_session->zoom_atrack = zoom;
	for( Track *track= edl->tracks->first; track; track=track->next ) {
		if( track->data_type != TRACK_AUDIO ) continue;
		track->data_h = zoom;
	}
// shift row position
	for( int i=0; i<TOTAL_PANES; ++i ) edl->local_session->track_start[i] =
		(edl->local_session->track_start[i] * zoom) / old_zoom;
	edl->tracks->update_y_pixels(theme);
	gui->draw_trackmovement();
}

void MWindow::zoom_vtrack(int64_t zoom)
{
	int64_t old_zoom = edl->local_session->zoom_vtrack;
	CLAMP(zoom, MIN_TRACK_ZOOM, MAX_TRACK_ZOOM);
	edl->local_session->zoom_vtrack = zoom;

	for( Track *track= edl->tracks->first; track; track=track->next ) {
		if( track->data_type != TRACK_VIDEO ) continue;
		track->data_h = zoom;
	}
// shift row position
	for( int i=0; i<TOTAL_PANES; ++i ) edl->local_session->track_start[i] =
		(edl->local_session->track_start[i] * zoom) / old_zoom;
	edl->tracks->update_y_pixels(theme);
	gui->draw_trackmovement();
}

void MWindow::trackmovement(int offset, int pane_number)
{
	edl->local_session->track_start[pane_number] += offset;
	if(edl->local_session->track_start[pane_number] < 0)
		edl->local_session->track_start[pane_number] = 0;

	if(pane_number == TOP_RIGHT_PANE ||
		pane_number == TOP_LEFT_PANE)
	{
		edl->local_session->track_start[TOP_LEFT_PANE] =
			edl->local_session->track_start[TOP_RIGHT_PANE] =
			edl->local_session->track_start[pane_number];
	}
	else
	if(pane_number == BOTTOM_RIGHT_PANE ||
		pane_number == BOTTOM_LEFT_PANE)
	{
		edl->local_session->track_start[BOTTOM_LEFT_PANE] =
			edl->local_session->track_start[BOTTOM_RIGHT_PANE] =
			edl->local_session->track_start[pane_number];
	}


	edl->tracks->update_y_pixels(theme);
	gui->draw_trackmovement();
}

void MWindow::move_up(int64_t distance)
{
	TimelinePane *pane = gui->get_focused_pane();
	if(distance == 0) distance = pane->canvas->get_h() / 10;
	trackmovement(-distance, pane->number);
}

void MWindow::move_down(int64_t distance)
{
	TimelinePane *pane = gui->get_focused_pane();
	if(distance == 0) distance = pane->canvas->get_h() / 10;
	trackmovement(distance, pane->number);
}

int MWindow::goto_end()
{
	TimelinePane *pane = gui->get_focused_pane();
	int64_t old_view_start = edl->local_session->view_start[pane->number];

	if( edl->tracks->total_length() > (double)pane->canvas->get_w() *
		edl->local_session->zoom_sample / edl->session->sample_rate ) {
		edl->local_session->view_start[pane->number] =
			Units::round(edl->tracks->total_length() *
				edl->session->sample_rate /
				edl->local_session->zoom_sample -
				pane->canvas->get_w() /
				2);
	}
	else
	{
		edl->local_session->view_start[pane->number] = 0;
	}

	if(gui->shift_down())
	{
		edl->local_session->set_selectionend(edl->tracks->total_length());
	}
	else
	{
		edl->local_session->set_selectionstart(edl->tracks->total_length());
		edl->local_session->set_selectionend(edl->tracks->total_length());
	}

	if(edl->local_session->view_start[pane->number] != old_view_start)
	{
		samplemovement(edl->local_session->view_start[pane->number], pane->number);
		gui->draw_samplemovement();
	}

	update_plugin_guis();

	gui->update_patchbay();
	gui->update_cursor();
	gui->activate_timeline();
	gui->zoombar->update();
	gui->update_timebar(1);
	cwindow->update(1, 0, 0, 0, 1);
	return 0;
}

int MWindow::goto_start()
{
	TimelinePane *pane = gui->get_focused_pane();
	int64_t old_view_start = edl->local_session->view_start[pane->number];

	edl->local_session->view_start[pane->number] = 0;
	if(gui->shift_down())
	{
		edl->local_session->set_selectionstart(0);
	}
	else
	{
		edl->local_session->set_selectionstart(0);
		edl->local_session->set_selectionend(0);
	}

	if(edl->local_session->view_start[pane->number] != old_view_start)
	{
		samplemovement(edl->local_session->view_start[pane->number], pane->number);
		gui->draw_samplemovement();
	}

	update_plugin_guis();
	gui->update_patchbay();
	gui->update_cursor();
	gui->activate_timeline();
	gui->zoombar->update();
	gui->update_timebar(1);
	cwindow->update(1, 0, 0, 0, 1);
	return 0;
}

int MWindow::goto_position(double position)
{
	position = edl->align_to_frame(position, 0);
	if( position < 0 ) position = 0;
	select_point(position);
	gui->activate_timeline();
	return 0;
}

int MWindow::samplemovement(int64_t view_start, int pane_number)
{
	if( view_start < 0 ) view_start = 0;
	edl->local_session->view_start[pane_number] = view_start;
	if(edl->local_session->view_start[pane_number] < 0)
		edl->local_session->view_start[pane_number] = 0;

	if(pane_number == TOP_LEFT_PANE ||
		pane_number == BOTTOM_LEFT_PANE)
	{
		edl->local_session->view_start[TOP_LEFT_PANE] =
			edl->local_session->view_start[BOTTOM_LEFT_PANE] =
			edl->local_session->view_start[pane_number];
	}
	else
	{
		edl->local_session->view_start[TOP_RIGHT_PANE] =
			edl->local_session->view_start[BOTTOM_RIGHT_PANE] =
			edl->local_session->view_start[pane_number];
	}

	gui->draw_samplemovement();

	return 0;
}

int MWindow::move_left(int64_t distance)
{
	TimelinePane *pane = gui->get_focused_pane();
	if(!distance)
		distance = pane->canvas->get_w() / 10;
	edl->local_session->view_start[pane->number] -= distance;
	samplemovement(edl->local_session->view_start[pane->number],
		pane->number);
	return 0;
}

int MWindow::move_right(int64_t distance)
{
	TimelinePane *pane = gui->get_focused_pane();
	if(!distance)
		distance = pane->canvas->get_w() / 10;
	edl->local_session->view_start[pane->number] += distance;
	samplemovement(edl->local_session->view_start[pane->number],
		pane->number);
	return 0;
}

void MWindow::select_all()
{
	if( edl->local_session->get_selectionstart(1) == 0 &&
	    edl->local_session->get_selectionend(1) == edl->tracks->total_length() )
		edl->local_session->set_selectionend(0);
	else {
		edl->local_session->set_selectionstart(0);
		edl->local_session->set_selectionend(edl->tracks->total_length());
	}
	gui->update(0, NORMAL_DRAW, 1, 1, 0, 1, 0);
	gui->activate_timeline();
	cwindow->update(1, 0, 0, 0, 1);
	update_plugin_guis();
}

int MWindow::next_label(int shift_down)
{
	double position = edl->local_session->get_selectionend(1);
	double total_length = edl->tracks->total_length();
	Label *current = edl->labels->next_label(position);
	double new_position = current ? current->position : total_length;
// last playback endpoints as fake label positions
	double playback_start = edl->local_session->playback_start;
	double playback_end = edl->local_session->playback_end;
	if( playback_start > position && playback_start < new_position )
		new_position = playback_start;
	else if( playback_end > position && playback_end < new_position )
		new_position = playback_end;
	if( new_position > total_length )
		new_position = total_length;
	edl->local_session->set_selectionend(new_position);
//printf("MWindow::next_edit_handle %d\n", shift_down);
	if( !shift_down )
		edl->local_session->set_selectionstart(new_position);
	return find_selection(new_position);
}

int MWindow::prev_label(int shift_down)
{
	double position = edl->local_session->get_selectionstart(1);
	Label *current = edl->labels->prev_label(position);
	double new_position = current ? current->position : 0;
// last playback endpoints as fake label positions
	double playback_start = edl->local_session->playback_start;
	double playback_end = edl->local_session->playback_end;
	if( playback_end < position && playback_end > new_position )
		new_position = playback_end;
	else if( playback_start < position && playback_start > new_position )
		new_position = playback_start;
	if( new_position < 0 )
		new_position = 0;
	edl->local_session->set_selectionstart(new_position);
//printf("MWindow::next_edit_handle %d\n", shift_down);
	if( !shift_down )
		edl->local_session->set_selectionend(new_position);
	return find_selection(new_position);
}

int MWindow::next_edit_handle(int shift_down)
{
	double position = edl->local_session->get_selectionend(1);
	double new_position = edl->next_edit(position);
	double total_length = edl->tracks->total_length();
	if( new_position >= total_length )
		new_position = total_length;
	edl->local_session->set_selectionend(new_position);
//printf("MWindow::next_edit_handle %d\n", shift_down);
	if( !shift_down )
		edl->local_session->set_selectionstart(new_position);
	return find_selection(new_position);
}

int MWindow::prev_edit_handle(int shift_down)
{
	double position = edl->local_session->get_selectionstart(1);
	double new_position = edl->prev_edit(position);
	if( new_position < 0 )
		new_position = 0;
	edl->local_session->set_selectionstart(new_position);
	if( !shift_down )
		edl->local_session->set_selectionend(new_position);
	return find_selection(new_position);
}

int MWindow::nearest_plugin_keyframe(int shift_down, int dir)
{
	KeyFrame *keyframe = 0;
	double start = edl->local_session->get_selectionstart(1);
	double end = edl->local_session->get_selectionend(1);
	double position = dir == PLAY_FORWARD ? end : start;
	double new_position = dir == PLAY_FORWARD ? start : end;
	for( Track *track=edl->tracks->first; track; track=track->next ) {
		if( !track->is_armed() ) continue;
		for( int i=0; i<track->plugin_set.size(); ++i ) {
			PluginSet *plugin_set = track->plugin_set[i];
			int64_t pos = track->to_units(position, 0);
			KeyFrame *key = plugin_set->nearest_keyframe(pos, dir);
			if( !key ) continue;
			double key_position = track->from_units(key->position);
			if( keyframe && (dir == PLAY_FORWARD ?
				key_position >= new_position :
				new_position >= key_position ) ) continue;
			keyframe = key;  new_position = key_position;
		}
	}

	new_position = keyframe ?
		keyframe->autos->track->from_units(keyframe->position) :
		dir == PLAY_FORWARD ? edl->tracks->total_length() : 0;

	if( !shift_down )
		start = end = new_position;
	else if( dir == PLAY_FORWARD )
		end = new_position;
	else
		start = new_position;

	edl->local_session->set_selectionstart(start);
	edl->local_session->set_selectionend(end);
	return find_selection(new_position);
}

int MWindow::nearest_auto_keyframe(int shift_down, int dir)
{
	Auto *keyframe = 0;
	double start = edl->local_session->get_selectionstart(1);
	double end = edl->local_session->get_selectionend(1);
	double position = dir == PLAY_FORWARD ? end : start;
	double new_position = dir == PLAY_FORWARD ? start : end;
	for( Track *track=edl->tracks->first; track; track=track->next ) {
		if( !track->is_armed() ) continue;
		int64_t pos = track->to_units(position, 0);
		for( int i=0; i<AUTOMATION_TOTAL; ++i ) {
			Autos *autos = track->automation->autos[i];
			if( !autos ) continue;
			Auto *key = dir == PLAY_FORWARD ?
				 autos->nearest_after(pos) :
				 autos->nearest_before(pos);
			if( !key ) continue;
			double key_position = track->from_units(key->position);
			if( keyframe && (dir == PLAY_FORWARD ?
				key_position >= new_position :
				new_position >= key_position ) ) continue;
			keyframe = key;  new_position = key_position;
		}
	}

	new_position = keyframe ?
		keyframe->autos->track->from_units(keyframe->position) :
		dir == PLAY_FORWARD ? edl->tracks->total_length() : 0;

	if( !shift_down )
		start = end = new_position;
	else if( dir == PLAY_FORWARD )
		end = new_position;
	else
		start = new_position;

	edl->local_session->set_selectionstart(start);
	edl->local_session->set_selectionend(end);
	return find_selection(new_position);
}

int MWindow::find_selection(double position, int scroll_display)
{
	update_plugin_guis();
	TimelinePane *pane = gui->get_focused_pane();
	double pixel_zoom = (double)edl->session->sample_rate / edl->local_session->zoom_sample;
	if( !scroll_display ) {
		double timeline_start = edl->local_session->view_start[pane->number] / pixel_zoom;
		double timeline_end = timeline_start + pane->canvas->time_visible();
		if( position >= timeline_end || position < timeline_start )
			scroll_display = 1;
	}
	if( scroll_display ) {
		samplemovement((int64_t)(position * pixel_zoom - pane->canvas->get_w() / 2), pane->number);
		cwindow->update(1, 0, 0, 0, 0);
	}
	else {
		gui->update_patchbay();
		gui->update_timebar(0);
		gui->hide_cursor(0);
		gui->draw_cursor(0);
		gui->zoombar->update();
		gui->flash_canvas(1);
		cwindow->update(1, 0, 0, 0, 1);
	}
	return 0;
}

double MWindow::get_position()
{
	return edl->local_session->get_selectionstart(1);
}

void MWindow::set_position(double position)
{
	if( position != get_position() ) {
		if( position < 0 ) position = 0;
		edl->local_session->set_selectionstart(position);
		edl->local_session->set_selectionend(position);
		gui->lock_window();
		find_cursor();
		gui->update(1, NORMAL_DRAW, 1, 1, 1, 1, 0);
		gui->unlock_window();
		cwindow->update(1, 0, 0, 0, 0);
	}
}


double MWindow::get_timecode_offset()
{
	return edl->session->timecode_offset;
}

void MWindow::set_timecode_offset(double offset)
{
	edl->session->time_format = TIME_TIMECODE;
	edl->session->timecode_offset = offset;
	gui->lock_window();
	gui->update(1, NORMAL_DRAW, 1, 1, 1, 1, 0);
	gui->unlock_window();
	cwindow->update(1, 0, 0, 0, 0);
}


int MWindow::expand_y()
{
	int result = edl->local_session->zoom_y * 2;
	result = MIN(result, MAX_AMP_ZOOM);
	zoom_amp(result);
	gui->zoombar->update();
	return 0;
}

int MWindow::zoom_in_y()
{
	int result = edl->local_session->zoom_y / 2;
	result = MAX(result, MIN_AMP_ZOOM);
	zoom_amp(result);
	gui->zoombar->update();
	return 0;
}

int MWindow::expand_t()
{
	int zoom = edl->local_session->zoom_atrack * 2;
	zoom = MIN(zoom, MAX_TRACK_ZOOM);
	zoom_atrack(zoom);
	zoom = edl->local_session->zoom_vtrack * 2;
	zoom = MIN(zoom, MAX_TRACK_ZOOM);
	zoom_vtrack(zoom);
	gui->zoombar->update();
	return 0;
}

int MWindow::zoom_in_t()
{
	int zoom = edl->local_session->zoom_atrack / 2;
	zoom = MAX(zoom, MIN_TRACK_ZOOM);
	zoom_atrack(zoom);
	zoom = edl->local_session->zoom_vtrack / 2;
	zoom = MAX(zoom, MIN_TRACK_ZOOM);
	zoom_vtrack(zoom);
	gui->zoombar->update();
	return 0;
}

void MWindow::split_x()
{
	gui->resource_thread->stop_draw(1);

	if(gui->pane[TOP_RIGHT_PANE])
	{
		gui->delete_x_pane(theme->mcanvas_w);
		edl->local_session->x_pane = -1;
	}
	else
	{
		gui->create_x_pane(theme->mcanvas_w / 2);
		edl->local_session->x_pane = theme->mcanvas_w / 2;
	}

	gui->mainmenu->update_toggles(0);
	gui->update_pane_dividers();
	gui->update_cursor();
	gui->draw_samplemovement();
// required to get new widgets to appear
	gui->show_window();

	gui->resource_thread->start_draw();
}

void MWindow::split_y()
{
	gui->resource_thread->stop_draw(1);
	if(gui->pane[BOTTOM_LEFT_PANE])
	{
		gui->delete_y_pane(theme->mcanvas_h);
		edl->local_session->y_pane = -1;
	}
	else
	{
		gui->create_y_pane(theme->mcanvas_h / 2);
		edl->local_session->y_pane = theme->mcanvas_h / 2;
	}

	gui->mainmenu->update_toggles(0);
	gui->update_pane_dividers();
	gui->update_cursor();
	gui->draw_trackmovement();
// required to get new widgets to appear
	gui->show_window();
	gui->resource_thread->start_draw();
}

