
function Segment()
{
    this.m_startPoint = null;
    this.m_endPoint = null;
    this.m_bearing = null;
    this.m_distance = null;
}


function Route()
{
    this.m_routeID = "";
    this.m_name = "";
    this.m_region = "";   // canton (new)

    this.m_video = "";  // full url
    this.m_flv = "";    // flv filename only
    
    this.m_points = [];

    this.m_startPoint = null;
    this.m_endPoint = null;
    
    this.m_startMarker = null;
    this.m_endMarker = null;
    
    this.m_overlay = null;
    this.m_bounds = null;
    
    this.m_nameLower = "";
    
    this.m_segmentList = null;
    this.m_distance = 0;
    
    this.m_syncChecked = false;  // set once all points have been assigned a time value
}

//
Route.prototype.m_loadJS = function(a)
{

    this.m_routeID = a[0];

    this.m_name = a[1];
    this.m_nameLower = formatLowerCase(this.m_name);
    
    this.m_region = a[2];

    this.m_video = videoPlayPath + this.m_routeID + ".flv";      // used for playing of video
    this.m_flv = videoDownloadPath + this.m_routeID + ".flv";    // used for download link
        
    // split coordinate string, first into x,y,z substrings and then into individual points.
    var l_coordinates = a[3]; 

    this.m_bounds = new GLatLngBounds();
    
    if (l_coordinates.length > 0)
    {
        // split and use all the numerical values
        var l_coords = l_coordinates;
        for (var i in l_coordinates)
        {
            var v = l_coordinates[i];
            
            var x = v[0];
            var y = v[1];
            var t = v[2];
                    
            var l_point = new GLatLng(y,x);
            l_point.time = t;
            this.m_points.push(l_point);
        }
        
        // _TODO ----- init timestamps if not pre-set
        
        for (var i=0; i<this.m_points.length; i++)
        {
            this.m_bounds.extend(this.m_points[i]);
        }
        
        this.m_startPoint = this.m_points[0];
        this.m_endPoint = this.m_points[this.m_points.length-1];
    }
}


Route.prototype.m_showInfo = function(p_point, p_recentre)
{	
	
    gen.m_routeTime = -1;   // reset so maker will update
    
    if (p_recentre)
    {
        map.setCenter(p_point);
    }
    
    // zoom in to min level for route overlay to be displayed
    var l_zoom = map.getZoom();
    if (l_zoom < gen.m_midRouteZoom)
    {
        map.setZoom(gen.m_midRouteZoom);
    }    
    
    // Show street name
    //eID("titleDiv").innerHTML = this.m_name;

    // Change video playing ... 
    initialize(); 
	
    if (flashPanoramaPlayer && flashPanoramaPlayer.loadVideo)
    {
        gen.m_currentRoute = this;
        flashPanoramaPlayer.loadVideo(this.m_video);
        
        // and start playing video (after delay)
        setTimeout("launchVideo()", 500);
    }

}

function launchVideo()
{
    initialize(); 
	var my_status = flashPanoramaPlayer.get_status();
	var length = my_status[0];
	
    // and start playing
    if (flashPanoramaPlayer && flashPanoramaPlayer.play_video && length > 1)
    {
        initialize();
        flashPanoramaPlayer.play_video();
        
        setTimeout("launchVideo2()", 500);
        return;
    }

    setTimeout("launchVideo()", 200);
}

function launchVideo2()
{
    initialize(); 
	var my_status = flashPanoramaPlayer.get_status();
	var length = my_status[0];
	
    // and start playing
    if (flashPanoramaPlayer && flashPanoramaPlayer.press_start_button && length > 1)
    {
        initialize();
        // flashPanoramaPlayer.play_video();
        
        flashPanoramaPlayer.press_start_button();
        
        return;
    }

    setTimeout("launchVideo2()", 200);
}


Route.prototype.m_getIndexHtml = function()
{
    var l_html =
        "<div style='width:224px;padding:2px;height:15px;float:left'>" +
        "&bull; <a href='javascript:routeClick(\"" + this.m_routeID + "\");'>" + this.m_name + "</a> " + this.m_region +
        // " <a href='" + this.m_flv + "'>flv</a>" +
        "</div>";
        
    return l_html;
}

Route.prototype.m_createOverlay = function()
{
    var l_route = this;
    
    var l_overlay = new GPolyline(l_route.m_points, "#FF0000", 7, 0.5); 
    map.addOverlay(l_overlay);  

    this.m_overlay = l_overlay;
    
    // click handler    
    GEvent.addListener(l_overlay, 'click', function(p_point) 
    {
        l_route.m_showInfo(p_point, false);
    });
    
}


Route.prototype.m_initSegments = function()
{
    this.m_segmentList = [];
    
    this.m_distance = 0;
    for (var i=0; i<this.m_points.length-1; i++)
    {
        var seg = new Segment();
        seg.m_startPoint = this.m_points[i];
        seg.m_endPoint = this.m_points[i+1];
        
        seg.m_distance = seg.m_startPoint.distanceFrom(seg.m_endPoint);        
        seg.m_bearing = this.m_getBearing(seg.m_startPoint, seg.m_endPoint);
        
        this.m_segmentList.push(seg);        
        
        this.m_distance += seg.m_distance;
    }
    
}

// set time value for each point within the route
Route.prototype.m_syncSegments = function()
{
    var l_syncRequired = false;
    for (var i=1; i<this.m_points.length; i++)
    {
        if (this.m_points[i].time == 0)
        {
            l_syncRequired = true;
        }
    }

    if (l_syncRequired)
    {    
        var startIX = 0;
        
        // get total video duration
        initialize();    
        var l_panStatus = flashPanoramaPlayer.get_status();        
        var l_totalDuration = l_panStatus[0];
        
        if (l_totalDuration <= 1)
        {
            return;
        }
        
        this.m_points[0].time = 0;  // always zero
        this.m_points[this.m_points.length-1].time = l_totalDuration; // video duration
        
        var i = 1;
        while (i < this.m_points.length)
        {
            if (this.m_points[i].time != 0)
            {
                if (startIX == -1 || startIX == i-1)
                {
                    startIX = i;
                }
                else
                {
                    // sync this portion of the route                    
                    var startTime = this.m_points[startIX].time
                    var journeyTime = this.m_points[i].time - startTime;
                    var cumulativeDistance = 0;
                    var journeyDistance = 0;
                    
                    for (j=startIX; j<i; j++)
                    {
                        journeyDistance += this.m_segmentList[j].m_distance;
                    }
                    
                    if (journeyDistance >= 1)
                    {                
                        for (j=startIX+1; j<i; j++)
                        {
                            cumulativeDistance += this.m_segmentList[j].m_distance;
                            this.m_points[j].time = startTime + (cumulativeDistance / journeyDistance) * journeyTime;
                        }
                    }
                    
                    startIX = -1;   // reset
                }
            }

        
            i++;
        }
        
        var text = "";
        for (var i=0; i<this.m_points.length; i++)
        {
            text +=  this.m_points[i].time + " ";
        }
    }
    
    this.m_syncChecked = true;
}

Gen.prototype.m_displayRoutes = function(p_visible)
{
    gen.m_visibleRoutes = [];
    
    if (!gen.m_overlaysOn && p_visible)   // if overlays are currently hidden
    {
        return;
    }

    var l_mapBounds = map.getBounds();
    
    for (var i in this.m_routeList)
    {
        var l_route = this.m_routeList[i];
        var l_overlay = l_route.m_overlay;
        
        if (l_overlay)
        {
            if (p_visible && l_mapBounds.intersects(l_route.m_bounds))
            {
                l_overlay.show();
                gen.m_visibleRoutes.push(l_route);
            }
            else
            {
                l_overlay.hide();
            }
        }
        else
        {
            if (!this.m_gridOn && l_mapBounds.intersects(l_route.m_bounds) && p_visible)
            {
                l_route.m_createOverlay();
            }
        }
    }
}

// display place markers on map according to category and filter settings
Gen.prototype.m_displayPlaces = function()
{
    var z = map.getZoom();
    var l_filter = this.m_placeFilterText;
    
    for (var i in this.m_placeList)
    {
        var l_place = this.m_placeList[i];
        var l_overlay = l_place.m_overlay;
        
        var l_placeVisible = false;
        if (l_place.m_category == this.m_placeCategory)
        {
            if (!l_filter || (l_place.m_nameLower.indexOf(l_filter) > -1))
            {
                if (l_filter || l_place.z <= z)    // // rank / z level test
                {            
                    l_placeVisible = true;
                }                
            }
            
            if (l_place.m_category == "city")
            {
                l_placeVisible = true;
            }
        }

        if (l_overlay)
        {
            if (l_placeVisible)
            {
                l_overlay.show();
            }
            else
            {
                l_overlay.hide();
            }
        }
        else
        {
            if (l_placeVisible)
            {
               l_place.m_createOverlay();
            }
        }
        
    }

}


