package net.xoetrope.optional.layout;
import java.io.Reader;
import java.util.Vector;
import java.util.StringTokenizer;
import net.xoetrope.builder.BuilderSupport;
import net.xoetrope.debug.DebugLogger;
import net.xoetrope.xml.XmlElement;
import net.xoetrope.xml.XmlSource;
import net.xoetrope.xui.XProject;
import net.xoetrope.xui.build.BuildProperties;
/**
* Support object holding the guide information on behalf of a page
* <p> Copyright (c) Xoetrope Ltd., 2002-2003</p>
* <p> $Revision: 1.12 $</p>
* <p> License: see License.txt</p>
*/
public class GuideSupport implements BuilderSupport
{
private int left, top, width, height;
private XProject currentProject;
/**
* the tolerance for guide selection. The distance within which one must click on a
* guide to manipulate it within the editor
*/
public static final int GUIDE_SELECTION_TOLERANCE = 5;
private Vector horzGuides = new Vector();
private Vector vertGuides = new Vector();
/**
* Create a new GuideSupport
* @param project the owner project
*/
public GuideSupport( XProject project )
{
left = top = 0;
currentProject = project;
}
/**
* Set the dimensions of the page container whos grid is being rendered
* @param x the x or left coordinate
* @param y the y or top coordinate
* @param w the width dimension
* @param h the height dimension
*/
public void setPageBounds( int x, int y, int w, int h )
{
left = x;
top = y;
width = w;
height = h;
updateGuides( vertGuides, w );
updateGuides( horzGuides, h );
}
/**
* Get the guide coordinates
* @param vert true for the vertical guides
* @return the complete set of guides
*/
public Vector getGuideCoords( boolean vert )
{
if ( vert )
return vertGuides;
else
return horzGuides;
}
/**
* Set the guide coordinates
* @param coords the coordinates
* @param vert true for the vertical guides
*/
public void setGuideCoords( Vector coords, boolean vert )
{
if ( vert )
vertGuides = coords;
else
horzGuides = coords;
}
/**
* Add a guide
* @param g the new Guide
*/
public void addGuide( Guide g )
{
if ( g.getIsVertical() )
vertGuides.add( g );
else
horzGuides.add( g );
}
/**
* Read an included file
* @param fileName the file to read
*/
public void read( String fileName )
{
Reader r = null;
try {
String fn = fileName;
if ( fn.indexOf( ".xml" ) < 0 )
fn += ".xml";
r = currentProject.getBufferedReader( fn, null );
}
catch ( Exception ex ) {
if ( BuildProperties.DEBUG )
DebugLogger.logError( "File NOT found: " + fileName );
}
try {
if (( r == null ) || !r.ready())
return;
XmlElement guideModel = XmlSource.read( r );
read( guideModel );
}
catch ( Exception e ) {
if ( BuildProperties.DEBUG )
DebugLogger.logError( "Unable to load and process the guide file: " + fileName );
}
}
/**
* Read the guides from an XML element loaded from the page XML.
* @param layoutElement the layout XML element containing the guide configuration
*/
public void read( XmlElement layoutElement )
{
// Read the guide attributes
int originalWidth = Integer.parseInt( layoutElement.getAttribute( "width" ));
int originalHeight = Integer.parseInt( layoutElement.getAttribute( "height" ));
// Read the vertical guides
/** @todo drop reading of this old style reading after then next beta */
String vertGuideStr = layoutElement.getAttribute( "vert" );
if (( vertGuideStr != null ) && ( vertGuideStr.length() > 0 ))
readGuides( vertGuides, vertGuideStr, originalWidth, true );
else {
Vector guides = layoutElement.getChildren( "vert" );
if ( guides.size() > 0 )
readGuides( vertGuides, (XmlElement)guides.elementAt( 0 ), originalWidth, true );
}
// Read the horizontal guides
/** @todo drop reading of this old style reading after then next beta */
String horzGuideStr = layoutElement.getAttribute( "horz" );
if (( horzGuideStr != null ) && ( horzGuideStr.length() > 0 ))
readGuides( horzGuides, horzGuideStr, originalHeight, false );
else {
Vector guides = layoutElement.getChildren( "horz" );
if ( guides.size() > 0 )
readGuides( horzGuides, (XmlElement)guides.elementAt( 0 ), originalHeight, false );
}
}
private void readGuides( Vector guides, XmlElement guidesElement, int max, boolean isVertical )
{
guides.clear();
Vector guideElements = guidesElement.getChildren( "Guide" );
int numGuides = guideElements.size();
int[] previousGuides = new int[ numGuides ];
// Pass one - create the guides
for ( int i = 0; i < numGuides; i++ ) {
XmlElement guideElement = (XmlElement)guideElements.elementAt( i );
int id = Integer.parseInt( guideElement.getAttribute( "id" ));
double pos = Double.parseDouble( guideElement.getAttribute( "pos" ));
Guide guide = new Guide( pos, id, max, isVertical );
int positioning = Integer.parseInt( guideElement.getAttribute( "type" ));
guide.setPositioning( positioning );
guide.setCoordinates( Integer.parseInt( guideElement.getAttribute( "coords" )));
if ( positioning == Guide.RELATIVE_POSITION ) {
int previousGuideId = Integer.parseInt( guideElement.getAttribute( "prev" ));;
previousGuides[ i ] = previousGuideId;
}
else
previousGuides[ i ] = -1;
guides.add( guide );
}
// Pass two - set the previous guide references
for ( int i = 0; i < numGuides; i++ ) {
int prevId = previousGuides[ i ];
if ( prevId >=0 ) {
Guide guide = (Guide)guides.elementAt( i );
guide.setPreviousGuide( (Guide)guides.elementAt( prevId ));
}
}
}
/**
* @deprecated since beta 2
*/
private void readGuides( Vector guides, String dataStr, int max, boolean isVertical )
{
/** @todo drop reading of this old style reading after then next beta */
guides.clear();
StringTokenizer guideTokenizer = new StringTokenizer( dataStr, "{}" );
while ( guideTokenizer.hasMoreTokens()) {
String guideToken = guideTokenizer.nextToken();
StringTokenizer attribTokenizer = new StringTokenizer( guideToken, "," );
int id = Integer.parseInt( attribTokenizer.nextToken ());
double pos = Double.parseDouble( attribTokenizer.nextToken ());
int positioning = Integer.parseInt( attribTokenizer.nextToken ());
int coordinates = Integer.parseInt( attribTokenizer.nextToken ());
Guide guide = new Guide( pos, id, max, isVertical );
guide.positioning = positioning;
guide.coordinates = coordinates;
if ( positioning == Guide.RELATIVE_POSITION ) {
int previousGuideId = Integer.parseInt( attribTokenizer.nextToken ());
guide.previousGuide = (Guide)guides.elementAt( previousGuideId );
}
guides.add( guide );
}
}
/**
* Set the maximum extent for the guides
*/
private void updateGuides( Vector guides, int extent )
{
int numGuides = guides.size ();
for ( int i = 0; i < numGuides; i++ ) {
Guide guide = (Guide)guides.elementAt( i );
guide.setMaxExtent( extent );
}
}
}