
package uk.co.wingpath.gpx;

import java.io.*;
import java.util.*;
import uk.co.wingpath.xml.*;

// Represents a track - an ordered list of points describing a path

public class Track
    implements Xml.Savable, Xml.Loader
{
    private String name;                // GPS name of track.
    private String cmt;                 // GPS comment for track.
    private String desc;                // User description of track.
    private String src;                 // Source of data. Included to give
                                        // user some idea of reliability and
                                        // accuracy of data.
    private List<Link> link;            // Links to external information
                                        // about track.
    private int number;                 // GPS track number.
    private boolean hasNumber;
    private String type;                // Type (classification) of track.
    private List<TrackSegment> trkseg;  // A Track Segment holds a list of
                                        // Track Points which are logically
                                        // connected in order. To represent
                                        // a single GPS track where GPS
                                        // reception was lost, or the GPS
                                        // receiver was turned off, start
                                        // a new Track Segment for each
                                        // continuous span of track data.

	public Track ()
    {
        name = null;
        cmt = null;
        desc = null;
        src = null;
        link = new ArrayList<Link> ();
        hasNumber = false;
        type = null;
        trkseg = new ArrayList<TrackSegment> ();
    }

    public List<TrackSegment> getSegments ()
    {
        return trkseg;
    }

	public String getName ()
    {
        return name;
    }

    public String getDescription ()
    {
        return desc;
    }

	public String getComment ()
    {
        return cmt;
    }

	public int getNumber ()
    {
        return number;
    }

    public void setName (String n)
    {
        name = n;
    }

    public void setDescription (String d)
    {
        desc = d;
    }

    public void setComment (String c)
    {
        cmt = c;
    }

	public void setNumber (int n)
    {
        number = n;
        hasNumber = true;
    }

    public Xml.Loader startChild (String tag)
    {
        if (tag.equalsIgnoreCase ("link"))
        {
            Link l = new Link ();
            link.add (l);
            return l;
        }
        else if (tag.equalsIgnoreCase ("trkseg"))
        {
            TrackSegment ts = new TrackSegment ();
            trkseg.add (ts);
            return ts;
        }
        if (tag.equalsIgnoreCase ("name"))
        {
            return new Xml.StringLoader (new Xml.Receiver<String> ()
            {
                public void receive (String value)
                {
                    name = value;
                }
            });
        }
        if (tag.equalsIgnoreCase ("cmt"))
        {
            return new Xml.StringLoader (new Xml.Receiver<String> ()
            {
                public void receive (String value)
                {
                    cmt = value;
                }
            });
        }
        if (tag.equalsIgnoreCase ("desc"))
        {
            return new Xml.StringLoader (new Xml.Receiver<String> ()
            {
                public void receive (String value)
                {
                    desc = value;
                }
            });
        }
        if (tag.equalsIgnoreCase ("src"))
        {
            return new Xml.StringLoader (new Xml.Receiver<String> ()
            {
                public void receive (String value)
                {
                    src = value;
                }
            });
        }
        if (tag.equalsIgnoreCase ("number"))
        {
            return new Xml.IntegerLoader (new Xml.Receiver<Integer> ()
            {
                public void receive (Integer value)
                {
                    number = value;
                    hasNumber = true;
                }
            });
        }
        if (tag.equalsIgnoreCase ("type"))
        {
            return new Xml.StringLoader (new Xml.Receiver<String> ()
            {
                public void receive (String value)
                {
                    type = value;
                }
            });
        }
        return null;
    }

    public void attribute (String attr, String value)
    {
    }

    public void end (String value)
    {
    }

    public void cleanup ()
    {
    }

    public void save (Xml.Saver saver)
        throws IOException
    {
        if (name != null)
            saver.saveValue ("name", name);
        if (cmt != null)
            saver.saveValue ("cmt", cmt);
        if (desc != null)
            saver.saveValue ("desc", desc);
        if (src != null)
            saver.saveValue ("src", src);

        for (Link l : link)
            saver.saveValue ("link", l);

        if (hasNumber)
            saver.saveValue ("number", "" + number);
        if (type != null)
            saver.saveValue ("type", type);

        for (TrackSegment ts : trkseg)
            saver.saveValue ("trkseg", ts);
    }
}

