/* FunctionEditor_LongSound.c */
/* Paul Boersma, March 31, 2001 */

#include "FunctionEditor_LongSound.h"

void FunctionEditor_LongSound_draw (I) {
	iam (FunctionEditor);
	long first, last;
	LongSound longSound = my longSound.data;
	int fits, nchan = longSound -> numberOfChannels, ichan;
	double tfirst, tlast;
	int cursorVisible = my startSelection == my endSelection && my startSelection >= my startWindow && my startSelection <= my endWindow;
	double cursorFunctionValue = 0.0;
	/*
	 * Make sure that the window fits the LongSound buffer (has been done already in prepareDraw (), but we forgot).
	 */
	fits = LongSound_haveWindow (longSound, my startWindow, my endWindow);
	iferror {
		int outOfMemory = strstr (Melder_getError (), "memory") != NULL;
		Melder_clearError ();
		Graphics_setWindow (my graphics, 0, 1, 0, 1);
		Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF);
		Graphics_printf (my graphics, 0.5, 0.5, outOfMemory ? "(out of memory)" : "(cannot read sound file)");
	} else if (! fits) {
		Graphics_setWindow (my graphics, 0, 1, 0, 1);
		Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF);
		Graphics_printf (my graphics, 0.5, 0.5, "(window too large; zoom in to see the data)");
	} else if (Sampled_getWindowSamples (longSound, my startWindow, my endWindow, & first, & last) > 1) {
		/*
		 * Draw the function value of the cursor position.
		 */
		/*
		if (cursorVisible) cursorFunctionValue = Vector_getValueAtX (my sound, my cursor, 70);*/
		/*if (cursorVisible)
			FunctionEditor_drawCursorFunctionValue (me, "%.4g", cursorFunctionValue);*/
		/*
		 * Draw the function(s).
		 */
		Graphics_setColour (my graphics, Graphics_BLACK);
		tfirst = Sampled_indexToX (longSound, first), tlast = Sampled_indexToX (longSound, last);
		for (ichan = 1; ichan <= nchan; ichan ++) {
			/*
			 * BUG: this will only work for mono or stereo, until Graphics_function16 handles quadro.
			 */
			double ymin = (double) (nchan - ichan) / nchan;
			double ymax = (double) (nchan + 1 - ichan) / nchan;
			Graphics_Viewport vp = Graphics_insetViewport (my graphics, 0, 1, ymin, ymax);
			long horizontal = 0;
			double minimum = -1.0, maximum = 1.0;
			if (my sound.autoscaling)
				LongSound_getWindowExtrema (longSound, my startWindow, my endWindow, ichan, & minimum, & maximum);
			Graphics_setColour (my graphics, Graphics_BLUE);
			if (minimum >= maximum) {
				double value = 0.5 * (minimum + maximum);
				horizontal = 1;
				minimum -= 1; maximum += 1;
				Graphics_setTextAlignment (my graphics, Graphics_RIGHT, Graphics_HALF);
				Graphics_setWindow (my graphics, 0, 1, minimum, maximum);
				Graphics_printf (my graphics, 0, value, "%.4g", value);
			} else if (my sound.autoscaling) {
				Graphics_setWindow (my graphics, 0, 1, -1.0, 1.0);
				Graphics_fillRectangle (my graphics, 1, 2, minimum, maximum);
				Graphics_setTextAlignment (my graphics, Graphics_LEFT, Graphics_TOP);
				Graphics_printf (my graphics, 1, minimum, "%.4g", minimum);
				Graphics_setTextAlignment (my graphics, Graphics_LEFT, Graphics_BOTTOM);
				Graphics_printf (my graphics, 1, maximum, "%.4g", maximum);
			} else {
				Graphics_setWindow (my graphics, my startWindow, my endWindow, -1.0, 1.0);
				FunctionEditor_drawRangeMark (me, "%.4g", minimum, Graphics_BOTTOM);
				FunctionEditor_drawRangeMark (me, "%.4g", maximum, Graphics_TOP);
			}
			if (minimum < 0 && maximum > 0 && ! horizontal) {
				Graphics_setWindow (my graphics, 0, 1, minimum, maximum);
				if (! cursorVisible || fabs (Graphics_dyWCtoMM (my graphics, cursorFunctionValue - 0.0)) > 3.0) {
					Graphics_setColour (my graphics, Graphics_BLACK);
					Graphics_setTextAlignment (my graphics, Graphics_RIGHT, Graphics_HALF);
					Graphics_text (my graphics, 0, 0, "0");
				}
				Graphics_setColour (my graphics, Graphics_CYAN);
				Graphics_setLineType (my graphics, Graphics_DOTTED);
				Graphics_line (my graphics, 0, 0, 1, 0);
				Graphics_setLineType (my graphics, Graphics_DRAWN);
			}
			/*
			 * Garnish the drawing area of each channel.
			 */
			Graphics_setWindow (my graphics, 0, 1, 0, 1);
			Graphics_setColour (my graphics, Graphics_CYAN);
			Graphics_innerRectangle (my graphics, 0, 1, 0, 1);
			/*
			 * Draw a very thin separator line underneath.
			 */
			if (ichan < nchan) {
				/*Graphics_setColour (my graphics, Graphics_BLACK);*/
				Graphics_line (my graphics, 0, 0, 1, 0);
			}
			/*
			 * Draw the samples.
			 */
			Graphics_setWindow (my graphics, my startWindow, my endWindow, minimum * 32768, maximum * 32768);
			Graphics_setColour (my graphics, Graphics_BLACK);
			Graphics_function16 (my graphics,
				longSound -> buffer - longSound -> imin * nchan + (ichan - 1), nchan - 1, first, last, tfirst, tlast);
			Graphics_resetViewport (my graphics, vp);
		}
	} else {
		Graphics_setWindow (my graphics, 0, 1, 0, 1);
		Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF);
		Graphics_printf (my graphics, 0.5, 0.5, "(zoom out to see the data)");
	}

}

/* End of file FunctionEditor_LongSound.c */
