package com.moseph.mra.visualise;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.util.List;
import java.util.Vector;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JPanel;
import com.moseph.mra.Channel;
import com.moseph.mra.Span;
import com.moseph.mra.TemporalEvent;
import static com.moseph.mra.MRAUtilities.*;
public class ChannelVisualiser extends UnitVisualiser
{
double length = 10.0;
EventDisplay display;
public ChannelVisualiser()
{
super();
}
public ChannelVisualiser( double length )
{
this();
this.length = length;
}
public void setLength( double length )
{
//System.out.println( "ChannelVisualiser setting length to " + length );
this.length =length;
if( display != null ) display.setLength( length );
revalidate();
}
void dataFromObject()
{
if( data == null | !(data instanceof Channel)) return;
Channel channel = (Channel)data;
display = new EventDisplay( length, channel.getEvents() );
add( display );
/*
Box b = new Box( BoxLayout.X_AXIS );
if( channel.getAttributes().size() > 0 ) b.add( getListPanel( channel.getAttributes(), "Attributes"));
JComponent p = getListPanel( channel.getUnits(), null, BoxLayout.X_AXIS);
p.setBackground( Color.red );
p.setOpaque( true );
b.add( p );
add( b );
*/
}
public void fitToWindow()
{
display.fitToWindow();
}
public void setMinimumSize( Dimension d )
{
if( display != null ) display.setMinimumSize( d );
super.setMinimumSize( d );
}
public void setPreferredSize( Dimension d )
{
if( display != null ) display.setPreferredSize( d );
super.setPreferredSize( d );
}
class EventDisplay extends JPanel
{
public static final int DISPLAYHEIGHT = 60;
public static final int RULERHEIGHT = 20;
public static final int EVENTSIZE = 10;
double length = 10.0;
double zoom = 100.0;
final Color DEFAULT_BACKGROUND = Color.LIGHT_GRAY;
final Color DEFAULT_BORDER = Color.DARK_GRAY;
List<TemporalEvent> events = new Vector<TemporalEvent>();
double xscale;
public EventDisplay()
{
super();
setAlignmentX(Component.LEFT_ALIGNMENT );
}
public EventDisplay( double length, List<TemporalEvent> evt )
{
this();
this.length = length;
setContent( evt );
}
public void setLength( double length )
{
this.length = length;
}
public void fitToWindow()
{
zoom = (double)getWidth() / length;
}
public void setContent( List<TemporalEvent> events )
{
this.events = events;
}
public void paint( Graphics g )
{
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
drawRuler( g );
g.setColor( Color.BLACK );
g.drawRect( timeToPosition(0.0), RULERHEIGHT, lengthToWidth( length ), getWindowHeight() );
for( TemporalEvent event : events )
{
renderTemporalEvent( g, event );
}
}
void drawRuler( Graphics g )
{
double tickTiming = 10.0;
int TICKHEIGHT = RULERHEIGHT / 2;
int MINITICKHEIGHT = TICKHEIGHT / 2;
int miniTickTiming = lengthToWidth( tickTiming / 4 );
for( double tick = 0.0; tick <= length; tick += tickTiming )
{
int pos = timeToPosition( tick );
g.drawLine( pos, TICKHEIGHT, pos, TICKHEIGHT * 2 );
g.drawString( formatBeat( tick ), pos, TICKHEIGHT );
pos += miniTickTiming;
g.drawLine( pos, TICKHEIGHT + MINITICKHEIGHT, pos, TICKHEIGHT * 2 );
pos += miniTickTiming;
g.drawLine( pos, TICKHEIGHT + MINITICKHEIGHT / 2, pos, TICKHEIGHT * 2 );
pos += miniTickTiming;
g.drawLine( pos, TICKHEIGHT + MINITICKHEIGHT, pos, TICKHEIGHT * 2 );
}
}
void renderTemporalEvent( Graphics g, TemporalEvent s )
{
int startX = timeToPosition( s.getOnset() ) - EVENTSIZE;
g.setColor( getEventFiller( s ) );
g.fillRect( startX, RULERHEIGHT, 2 * EVENTSIZE, getWindowHeight() );
g.setColor( getEventBorder( s ) );
g.drawRect( startX, RULERHEIGHT, 2 * EVENTSIZE, getWindowHeight() );
g.setColor( Color.BLACK );
g.drawString( s.getContentString(), startX + 3, DISPLAYHEIGHT - 4 );
}
Color getEventFiller( TemporalEvent e )
{
return DEFAULT_BACKGROUND;
}
Color getEventBorder( TemporalEvent e )
{
return DEFAULT_BORDER;
}
int timeToPosition( double time )
{
return lengthToWidth( time ) + EVENTSIZE;
}
int lengthToWidth( double time )
{
return (int)( time * zoom);
}
public Dimension getMaximumSize() { return getPreferredSize(); }
public Dimension getMinimumSize() { return getPreferredSize(); }
public Dimension getPreferredSize()
{
return new Dimension( getDisplayWidth(), getDisplayHeight() );
}
int getWindowHeight()
{
return DISPLAYHEIGHT;
}
int getWindowWidth()
{
return (int)( length * zoom);
}
int getDisplayWidth()
{
return getWindowWidth() + 5 * EVENTSIZE;
}
int getDisplayHeight()
{
return getWindowHeight() + 2 + RULERHEIGHT;
}
}
}