﻿
var locArrX = new Array();
var locArrY = new Array();
var labelsX = new Array();
var labelsY = new Array();

var originalSize = 0;

var viewObjects = new Array();
var objectX;
var objectY;

var zoom = { Left:null, Right:null };

var annotationCurrPt;

var mouseButtonDown = 0;
var zoomDragging = 0;
var windowDragging = 0;
var legendCollapsed = 1;
var dataLoaded = 0;
var controlPressed = 0;
var selectedViewObject = -1;

var POINT_SERIES=0;
var POINT_INDEX=1;
var POINT_DATE=2;
var POINT_VALUE=3;
var POINT_UID=4;
var POINT_NOTE=5;
var POINT_TRACKID=6;

var PlotMargin = { Top:10, Right:70, Bottom:100, Left:85 };

var OverlayTracks;

var selectedCombinedTrack;

function TrackDataLoaded()
{
    var req = ActiveRequests["LoadTrackData"].Request;
    
    if( req.readyState == 4 && 
        req.status == 200 ) 
    {
        var sl = GetPlugin();
        sl.content.findName("plotCanvas").Children.Clear();
        
        var plotObj = sl.content.CreateFromXAML( req.responseText );
        
        var child = plotObj.Children.GetItem(0);
        
        var plotCanvas = sl.content.findName("plotCanvas");
        
        while( child != null )
        {
            plotObj.Children.Remove(child);
            plotCanvas.Children.Add( child );
            child = plotObj.Children.GetItem(0);
        }
        
        dataLoaded = 1;
        
        ClearLoadMessage();
        
        ClearViewObjects();
        
        GetPointData();
        
        if( originalSize == 1 )
            sl.content.findName("PlotButtonCanvas").visibility="Collapsed";
        else
            sl.content.findName("PlotButtonCanvas").visibility="Visible";
    } 
}

function ClearViewObjects()
{
    viewObjects = new Array();
}

function GetPlugin()
{
    return o("TrackSilverlightPlugin");
}

function ClearLoadMessage()
{
    var sl = GetPlugin();
    sl.content.findName("LoadMessage").visibility="Collapsed";
    sl.content.findName("plotCanvas").opacity="1.0";
    
    o("LoadMessagePanel").style.display="none";
}

function ShowLoadMessage()
{
    var sl = GetPlugin();
    sl.content.findName("LoadMessage").visibility="Visible";
    sl.content.findName("plotCanvas").opacity="0.2";
}

function GetPointTag(seriesId,pointId) 
{
   var ellipse = GetPoint(seriesId,pointId);
   
   if(ellipse) return ellipse["Tag"];
   else return "";
}

function GetPoint(seriesId,pointId)
{
    var sl = GetPlugin();
    return sl.content.findName("p" + seriesId + "-" + pointId)
}

function GetPointFromTag(tag)
{
    var arr = tag.split("|");
    return GetPoint(arr[POINT_SERIES],arr[POINT_INDEX]);
}

function GetPointData()
{ 
    var sl = GetPlugin();
  
    var s=0;
    var p=0;
    
    locArrX = new Array();
    locArrY = new Array();
    labelsX = new Array();
    labelsY = new Array();
    
    while( true )
    {
        var ptKey = s + "-" + p;
        
        var el = sl.content.findName( "p"+ptKey );
      
        if( el == null )
        {
            if( p == 0 ) break;
            
            s++; 
            p=0;
            continue;
        }
        
        var x = parseInt( el["Canvas.Left"] ) + parseInt( el["Width"] )/2;
        var y = parseInt( el["Canvas.Top"] ) + parseInt( el["Height"] )/2;
        
        if( p == 0 )
        {
            locArrX[s] = new Array();
            locArrY[s] = new Array();
            labelsX[s] = new Array();
            labelsY[s] = new Array();
        }
            
        locArrX[s][p]=x;
        locArrY[s][p]=y;
        
        var tmp = el.Tag.split("|");
        
        labelsX[s][p] = tmp[POINT_DATE];
        labelsY[s][p] = tmp[POINT_VALUE];
        //alert( x + " " + y );
        
        p++;
    }
    
}

function UpdatePlot()
{
    GetPlugin().source = GetApplicationRoot() + "/Viz/PlotXAML.aspx" + location.search; 
}

function LoadTrackData()
{
    dataLoaded = 1;
        
    GetPointData();
    
    ClearLoadMessage();
       
    o("TrackPlotDiv").style.height="";
}

function OverlaySelectedTracks( baseTracks, listId )
{ 
    var arr = GetSelectedItems(listId);
    
    var baseTracksArr = baseTracks.split(",");
    
    if( arr.length > 10 )
    {
        alert( "A maximum of 10 tracks can be added to the plot.  Please select ten or fewer tracks and try again.");
        return;
    }
    
    OverlayTracks = new Array();
    
    for( var i=0; i<arr.length; i++ )
    {
        if( IndexOf( arr[i].value, baseTracksArr ) != -1 )
        {
            alert("Track #" + arr[i].value + " (" + arr[i].text + ") is already part of this track.  Please unselect this track and try again." );
            return;
        }
        
        OverlayTracks.push( { TrackId:arr[i].value, TrackName:arr[i].text } );
    }
    
    if( !OverlayTracks || OverlayTracks.length == 0 )
        return;
    
    var args = "c=";
    
    for( var i=0; i<OverlayTracks.length; i++ )
    {
        args += ( i==0 ? OverlayTracks[i].TrackId : ","+OverlayTracks[i].TrackId );
    }
    
    LoadTrackDataByRange(null,null,args);
    
    BuildOverlayLegend();
}

function PopulateOverlayLegend( colors )
{
    var str = "";
    
    if( !OverlayTracks )
        return;
        
    for( var i=0; i<OverlayTracks.length; i++ )
    {
        str += "<div style=\"font-size:100%;color:" + colors[i] + ";\"><b>+</b>" + OverlayTracks[i].TrackName + "</div>";
    }
    
    o('OverlayLegendDiv').innerHTML = str;
}

function ValidateOverlays()
{
    if( !OverlayTracks || OverlayTracks.length == 0 )
    {
        alert("Please add at least one plot before saving.");
        return;
    }
}

function SaveOverlays()
{
    ValidateOverlays();
    
    var name = o("OverlayCombinedTrackName").value;
    
    if( !name || 
        name.length == 0 )
    {
        alert("Please supply a name for the combined track you wish to create.");
        return;
    }
    
    var args = "";
    
    if( !OverlayTracks )
        return;
        
    for( var i=0; i<OverlayTracks.length; i++ )
    {
        args += args.length > 0 ? "," + OverlayTracks[i].TrackId : OverlayTracks[i].TrackId;
    }
    
    args = "name=" + name + "&combine=" + args + "&" + location.search.substring(1);
    
    var url = GetApplicationRoot() + "/MiscPages/ManageTracks.ashx";
    
    var req = CreateRequest( "SaveOverlays", url, args, SaveOverlaysComplete );
    req.Begin();
}

function SaveOverlaysToCombinedTrack()
{
    ValidateOverlays();
    
    var args = "";
    for( var i=0; i<OverlayTracks.length; i++ )
    {
        args += args.length > 0 ? "," + OverlayTracks[i].TrackId : OverlayTracks[i].TrackId;
    }
    
    args = "addToCombined=1&combine=" + args + "&" + location.search.substring(1);
    
    var url = GetApplicationRoot() + "/MiscPages/ManageTracks.ashx";
    
    var req = CreateRequest( "SaveOverlays", url, args, SaveOverlaysComplete );
    req.Begin();
}

function ClearOverlays()
{
    o('PlotWindowTrackList').selectedIndex=-1;
    o('OverlayLegendDiv').innerHTML = "";
    
    RestoreClick();
}

function SaveOverlaysComplete()
{
    var req = ActiveRequests["SaveOverlays"].Request;
    
    //alert(req.readyState + " " + req.status );
    
    if( req.readyState == 4) 
    {
        if( req.status == 200 )
        {
            var doc = req.responseXML;
        
            var elements = doc.getElementsByTagName("trackId");
        
            var trackId = parseInt(elements[0].firstChild.nodeValue);
            
            if( trackId > 0 )
                alert("A combined track has been created.");
            else
                alert("Track data saved.");
        }
        else
            alert("Failed to create combined track.  Please supply a unique name for each new track you create.");
    }
}

function LoadTrackDataByRange(tag1,tag2,args)
{
    var range = "";
    
    if( tag1 != null )
    {
        zoom.Left = tag1.split("|")[POINT_DATE];
        range += "d1=" + zoom.Left + "&";
    } else
        zoom.Left = null;
    
    if( tag2 != null )
    {
        zoom.Right = tag2.split("|")[POINT_DATE];
        range += "d2=" + zoom.Right;    
    } else
        zoom.Right = null;
    
    ShowLoadMessage();
    
    if( tag1 == null && tag2 == null )
        originalSize = 1;
    else
        originalSize = 0;
        
    var url = GetApplicationRoot() + "/Viz/PlotXAML.aspx";
    var args = location.search.substring(1) + ( range.length>0 ? "&" + range : "" ) + "&" + args;
    
    var req = CreateRequest( "LoadTrackData", url, args, TrackDataLoaded );
    req.Begin();
}

function RestoreClick()
{
    LoadTrackDataByRange(null,null);
}

function CanvasMouseEnter(sender,args) 
{
   SetMeanLineVisibility(sender, "Visible"); 
}

function CanvasKeyDown(sender,args)
{
    if( args.Ctrl &&
        IsViewLoaded() == false)
    {
        controlPressed = 1;
        GetPlugin().content.findName("plotCanvas").cursor="Hand";
    }
}

function CanvasKeyUp(sender,args)
{
    controlPressed = 0;
    sender.findName("plotCanvas").cursor="Default";
}

function SetMeanLineVisibility(canvas, visibility) 
{
    for( var i=0; i<10; i++ ) 
    {
        for( var j=0; j<3; j++ )
        {
            var line = canvas.findName("meanLine-" + i + "-" + j);
            if( line != null )
                line.visibility=visibility;
        }
    }
}

function BuildOverlayLegend()
{
    if( OverlayTracks.length == 0 )
        return;
        
    var url = GetApplicationRoot() + "/MiscPages/ManageTracks.ashx";
    
    if( locArrX.length == 0 )
        GetPointData();
        
    var colorOffset = locArrX.length > 1 ? locArrX.length : 0;
    
    var args = "colors=" + OverlayTracks.length + "&colorOffset=" + colorOffset;
   
    var req = CreateRequest( "GetPlotColors", url, args, GetPlotColorsComplete );
    req.Begin();
}

function GetPlotColorsComplete()
{
    var req = ActiveRequests["GetPlotColors"].Request;
    
    if( req.readyState == 4 && 
        req.status == 200 ) 
    {
        var doc = req.responseXML;
        
        var elements = doc.getElementsByTagName("color");
        
        var arr = new Array();
        
        for( var i=0; i<elements.length; i++ )
        {
            arr[i] = elements[i].firstChild.nodeValue;
        }
        
        PopulateOverlayLegend( arr );
    }
}

function SetAnnotationContent( i, j )
{
    var pointTag = GetPointTag( i, j );
    
    var nakedContent = o("AnnotationContentOnly");
    var inputPanel = o("AnnotationInput");
    
    if(  nakedContent == null ||
         inputPanel == null )
         return;
         
    if(pointTag &&
        inputPanel.style.visibility!="visible" &&
        nakedContent.style.visibility!="visible" )
    {
        var annotation = pointTag.split("|")[POINT_NOTE];
        
        var inputContent = o("AnnotationContent");
        
        if(annotation)
        {
            inputContent.innerHTML = annotation + "<hr/>"; 
            nakedContent.innerHTML = annotation;
            
            return true;
        } 
        else
        {
            inputContent.innerHTML = "";
            nakedContent.innerHTML = "";
        }
    }
    
    return false;
}

function TrackIsOwned()
{
    var el = o("TrackIsOwned");
    if( el == null ) return false;
    else return parseInt(el.value) > 0 ? true : false;
}

function ViewObjectMouseUp(sender, args)
{
    mouseButtonDown=0;
    zoomDragging=0;
}

function ViewObjectMouseDown(sender, args)
{
    // Only allow input behavior when a vew is not loaded
    //
    if( IsViewLoaded() )
        return;
    
    var i = parseInt(sender.name);
    var obj = viewObjects[i];
    
    selectedViewObject = i;
    
    ShowPlotAnnotationInput(obj.X,obj.Y);
    
    mouseButtonDown=0;
    zoomDragging=0;
}

function ViewObjectMouseEnter(sender,args)
{
}

function ViewObjectMouseLeave(sender,args)
{
}

// point mouse enter
function pme(sender, args)
{
    var mousePos = args.getPosition(null);
    
    var sl = GetPlugin();
    var ownerLabel = sl.content.findName("pointOwnerLabel");
    var ownerCanvas = sl.content.findName("pointOwnerCanvas");
    
    var owners = ownerLabel.tag.split("|");
    
    var tagValues = sender.tag.split("|");
    
    ownerLabel.text = owners[ parseInt( tagValues[POINT_SERIES] ) ];
    
    ownerCanvas["Canvas.Left"] = mousePos.x;
    ownerCanvas["Canvas.Top"] = mousePos.y - ownerCanvas.height;
    
    ownerCanvas.visibility = "Visible";
    
    sender.findName("ownerLabelStory").begin();
    
    if( IsGroupTrack() )
    {
        ToggleMemberVisibility( parseInt(tagValues[POINT_TRACKID]), true);
    }
    else if( IsCombinedTrack() )
    {
        ToggleCombinedTrackLegendLink( tagValues[POINT_TRACKID], 1 );
    }
}

function ToggleCombinedTrackLegendLink( trackId, highlight )
{
    if( selectedCombinedTrack &&
        o('legendLink-' + selectedCombinedTrack))
        o('legendLink-' + selectedCombinedTrack).style.textDecoration = "";
        
    selectedCombinedTrack = trackId;
    
    if( o('legendLink-' + trackId) )
        o('legendLink-' + trackId).style.textDecoration = highlight ? "underline" : "";
}

// point mouse leave
function pml(sender, args)
{
    var sl = GetPlugin();
    var canvas = sl.content.findName("pointOwnerCanvas");
    canvas.visibility = "Collapsed";
    
    var tagValues = sender.tag.split("|");
    
    if( IsGroupTrack() ) 
    {
        ToggleMemberVisibility( parseInt(tagValues[POINT_TRACKID]), false);
    } 
    else if( IsCombinedTrack() )
    {
        ToggleCombinedTrackLegendLink( tagValues[POINT_TRACKID], 0 );
    }
}

// 
// Handle a mouse move event for the plot canvas
//
function CanvasMouseMove(sender, args) 
{
    // If there is no data, ignore the event
    //
    if( dataLoaded == 0 ||
        locArrY.length == 0 )
        return;
        
    if( selectedViewObject >= 0 )
        return;
    
    var mousePos = args.getPosition(null);
        
    //MoveLegend(sender,args);
    
    // Update the position of the zoom selection rectangle
    //
    UpdateZoomRectangle(sender,args);
    
    // If we are dragging an object, don't show the value indicators
    //
    if( windowDragging > 0 ||
        mouseButtonDown > 0 )
        return;
        
    // Get the nearest point
    //
    var loc = GetNearestPoint( mousePos.x, mousePos.y );
    
    // Show annotations
    //
    SetAnnotationContent( loc.SeriesId, loc.PointId );
    
    // Show the value indicators
    //
    ShowValueIndicators( sender, loc.SeriesId, loc.PointId );
    
    // Show combined track legend highlight
    // foo
    if( IsCombinedTrack() )
    {
        var tag = GetPointTag( loc.SeriesId, loc.PointId );
        var tagValues = tag.split("|");
        var trackId = tagValues[ POINT_TRACKID ];
        
        ToggleCombinedTrackLegendLink( trackId, 1 );
    }
}

function ShowValueIndicators( sender, seriesId, pointId )
{
    var x = locArrX[seriesId][pointId];
    var y = locArrY[seriesId][pointId];
    
    var animV = 0;
    var animH = 0;
       
    var vLine = sender.findName("animVLine");
    
    if( vLine["X1"] != x )
        animV = 1;
    
    vLine.visibility = "Visible";
    vLine["X1"] = x;
    vLine["Y1"] = PlotSize.Height - PlotMargin.Bottom;
    vLine["X2"] = x;
    vLine["Y2"] = y;  
    
    var hLine = sender.findName("animHLine");
    
    if( hLine["Y1"] != y )
        animH = 1;
        
    hLine.visibility = "Visible";
    hLine["X1"] = PlotMargin.Left;
    hLine["X2"] = x;
    hLine["Y1"] = y;
    hLine["Y2"] = y;
    
    if( animH > 0 )
        sender.findName("hLineStory").begin();
        
    if( animV > 0 )
        sender.findName("vLineStory").begin();
        
    var xLbl = sender.findName("animLabelX");
    var yLbl = sender.findName("animLabelY");
    
    xLbl.visibility="Visible";
    yLbl.visibility="Visible";
    
    xLbl.text = labelsX[seriesId][pointId];
    yLbl.text = labelsY[seriesId][pointId];
    
    xLbl["Canvas.Top"] = PlotSize.Height - PlotMargin.Bottom - 15;
    xLbl["Canvas.Left"] = x + 5;
    yLbl["Canvas.Top"] = y;
    yLbl["Canvas.Left"] = PlotMargin.Left + 5;
    
    var currPt = sender.findName("animCurrPt");
    currPt["Canvas.Top"] = y-6;
    currPt["Canvas.Left"] = x-6;
    currPt.visibility="Visible";
    
    if( animV > 0 ) 
    {
        sender.findName("currPtStory").begin();
        sender.findName("currPtStory2").begin();
    }

}

//
// Handle a mouse down event for the plot canvas
//
function CanvasMouseDown(sender,args)
{
    if( locArrY.length == 0 )
        return;
        
    // Display the zoom selection rectangle
    //
    var rect = sender.findName("zoomRect");
    rect.visibility="Visible";
    rect.width=0; 
    rect.height=0;
    rect["Canvas.Left"] = args.getPosition(null).x;
    
    // Set the zoom dragging variable to the current X position
    //
    mouseButtonDown = args.getPosition(null).x;
}

function EditWiki()
{
    o("wikiContent").style.display="none";
    o("wikiEditButton").style.display="none";
    o("wikiEditSection").style.display="block";
}

function CancelWikiEdit()
{
    o("wikiContent").style.display="block";
    o("wikiEditButton").style.display="block";
    o("wikiEditSection").style.display="none";
}

function AddTag(id)
{
    var txt = o(id).value;
    var tagUrl = GetApplicationRoot() + "/MiscPages/ManageTags.ashx" + location.search;
    
    var request = CreateRequest( "AddTag", tagUrl, "a=" + encodeURIComponent(txt), AddTagComplete );
    request.Begin();
    
    o("AddTagButton").value = "Saving...";
}

function DeleteTag(tag)
{
    var tagUrl = GetApplicationRoot() + "/MiscPages/ManageTags.ashx" + location.search; 
    var req = CreateRequest( "DeleteTag", tagUrl, "d=" + encodeURIComponent(tag), DeleteTagComplete );
    req.Begin();
}

function DeleteTagComplete()
{
    var req = ActiveRequests["DeleteTag"].Request;
    
    if( req.readyState == 4 && 
        req.status == 200 ) 
    {
        var doc = req.responseXML;
        
        var elements = doc.getElementsByTagName("tag");
        
        var tagStr = "";
        
        for( var i=0; i<elements.length; i++ )
        {
            if( tagStr.length > 0 )
                tagStr += ", ";
                
            tagStr +=  GetTagLink( elements[i].firstChild.nodeValue );
        }
        
        o("TagListDiv").innerHTML = tagStr;
    }
}

function GetTagLink(tagText)
{
    return "<a href=\"" + GetApplicationRoot() + "/MiscPages/Search.aspx?t=" +
                    tagText + "\">" + tagText + "</a>" +
                    "<a href=\"javascript:DeleteTag('" + tagText + 
                    "')\" class=\"tag-deleteTagLink\" title=\"Delete Tag\">[x]</a>";
}
                    
function AddTagComplete()
{
    var req = ActiveRequests["AddTag"];
    
    if( !req )
        return;
        
    if( req.Request.readyState == 4 )
    {
        o("AddTagButton").value = "Add Tags";
        o("TagInputTextBox").value = "";
    }
    
    if( req.Request.readyState == 4 && 
        req.Request.status == 200 ) 
    {
        var doc = req.Request.responseXML;
        
        var elements = doc.getElementsByTagName("tag");
        
        var tagStr = "";
        
        for( var i=0; i<elements.length; i++ )
        {
            if( tagStr.length > 0 )
                tagStr += ", ";
                
            tagStr += GetTagLink( elements[i].firstChild.nodeValue );
        }
        
        o("TagListDiv").innerHTML = tagStr;
        
        ActiveRequests["AddTag"] = null;
    }
}

function AddAnnotationComplete()
{
    var req = ActiveRequests["AddAnnotation"].Request;
    
    if( req.readyState == 4 && 
        req.status == 200 ) 
    {
        var textbox = o("AnnotationTextbox");
        
        if(annotationCurrPt) 
        {
            var point = GetPointFromTag(annotationCurrPt);
         
            if(point)
            {
                var arr = point["Tag"].split("|");
                var prevTag = arr[POINT_NOTE];
                arr[POINT_NOTE] = textbox.value;
                point["Tag"] = arr.join("|");
                
                if( textbox.value.length > 0 ) 
                {
                    point["Stroke"].Color = "Yellow";
                    point["StrokeThickness"] = "2";
                } 
                else
                {
                    point["StrokeThickness"] = "4";
                    point["Stroke"].Color = "Transparent";
                }
            }
        }
        
        textbox.value = "";
    }
}

function SubmitAnnotation()
{
    var textbox = o("AnnotationTextbox");
    
    if( CheckIllegalMarkup( textbox.value ) )
    {
        alert( "Annotations may not contain markup." );
        return;
    }
    
    var url = GetApplicationRoot() + "/MiscPages/ManageAnnotations.ashx" + location.search;
    var args = "a=1&tag=" + annotationCurrPt + "&at=" + encodeURIComponent(textbox.value);
    
    var req = CreateRequest( "AddAnnotation", url, args, AddAnnotationComplete );
    req.Begin();
   
    HideElement("AnnotationInput");
}

function SaveViewComplete()
{
    var req = ActiveRequests["SaveView"].Request;
    
    if( req.readyState == 4 && 
        req.status == 200 ) 
    {
        var doc = req.responseXML;
        
        if( doc.documentElement.childNodes.length == 0 )
            return;
        
        if( doc.documentElement.tagName == "error")
        {
            alert( doc.documentElement.firstChild.nodeValue );      
        } 
        else if( doc.documentElement.tagName == "success")
        {
            var viewId = parseInt(doc.documentElement.firstChild.nodeValue);
            document.location.href = document.location.href + "&v=" + viewId;
        }
        
        o("SaveViewButton").disabled = "";
    }
}

function IsViewLoaded()
{
    return document.location.search.indexOf("v=") >= 0;
}

function SaveView()
{
    var viewName = o("SaveViewName").value;
    
    if( viewName.length == 0 )
    {
        alert("A finding name is required.");
        return;
    }
    
    if( viewObjects.length == 0 )
    {
        alert("The finding is empty.  You must add at least one item to the finding before saving.");
        return;
    }
    
    var url = GetApplicationRoot() + "/MiscPages/ManageViews.ashx" + location.search;
    
    var xaml = "<viewObjects>";
    for( var i=0; i<viewObjects.length; i++ )
    {
        xaml += GetViewObjectXaml(viewObjects[i]);
    }
    xaml += "</viewObjects>";
    
    var plugin = GetPlugin();
    var rangeTag = plugin.content.findName("plotCanvas").tag;
    
    var rangeDates = new Array();
    
    if( rangeTag.length > 1 )
    {
        rangeDates = rangeTag.split("|");
    }
    
    if( zoom.Left == null )
        zoom.Left = rangeDates[0];
        
    if( zoom.Right == null )
        zoom.Right = rangeDates[1];
    
    o("SaveViewButton").disabled = "disabled";
    
    var args = "d1=" + zoom.Left + "&" +
                    "d2=" + zoom.Right + "&" +
                    "viewName=" + viewName + "&" +
                    "xaml=" + encodeURIComponent(xaml);
       
    var req = CreateRequest( "SaveView", url, args, SaveViewComplete );
    req.Begin();
}

// pmu = point mouse up
//
function pmu( sender, args )
{
    var mousePos = args.getPosition(null);
    
    var sl = GetPlugin();
    
    HideElement("AnnotationInput");
    HideElement("AnnotationContentOnly");
    
    var tagValues = sender.tag.split("|");
    
    var seriesId = tagValues[POINT_SERIES];
    var pointId = tagValues[POINT_INDEX];
    
    annotationCurrPt = GetPointTag(seriesId,pointId);
    
    if( SetAnnotationContent( seriesId,pointId ) == true ||
        TrackIsOwned() )
        ShowAnnotationInput(locArrX[seriesId][pointId]+1,locArrY[seriesId][pointId]+1);
}

function CanvasMouseUp(sender, args)
{
    if( locArrY.length == 0 )
        return;
    
    var rect = sender.findName("zoomRect");
    
    var x = args.getPosition(null).x;
    var y = args.getPosition(null).y;
    
    var n1 = GetNearestX( x - rect.width );
    var n2 = GetNearestX( x );   
    
    // If we were dragging a zoom selection box, handle the zoom
    //
    if( zoomDragging > 0 )
    {   
        if( rect.width > 0 ) 
        {
            var s1 = GetNearestSeries( x-rect.Width, n1 );
            var s2 = GetNearestSeries( x, n2 );
       
            LoadTrackDataByRange(GetPointTag(s1,n1[s1]),GetPointTag(s2,n2[s2]));
        }
    } 
    else 
    {
        // custom objects
        //
        if( controlPressed > 0 )
            ShowPlotAnnotationInput(x,y);
    }
            
    windowDragging=0;
    mouseButtonDown=0;
    zoomDragging = 0;
    
    rect.visibility="Collapsed";
}

function GetNearestPoint( x, y ) 
{
    var n = GetNearestX(x);
    var min = -1;
    var mini = 0;
    
    for( var i=0; i<n.length; i++ )
    {
        var dx = locArrX[i][n[i]]-x;
        var dy = locArrY[i][n[i]]-y;
        var d = Math.pow(dx,2) + Math.pow(dy,2);
        
        if( min<0 ||
            d < min )
        {
            min = d;
            mini = i;
        }  
    }
    
    var result = new Object();
    result.SeriesId = mini;
    result.PointId = n[mini];
    
    return result;
}

function ShowAnnotationInput(x,y)
{
    var div;
    
    if( TrackIsOwned() &&
        IsGroupTrack() == false &&
        IsCombinedTrack() == false)
        div = o("AnnotationInput");
    else
        div = o("AnnotationContentOnly");
        
    var pos = GetPluginLocation();
    
    div.style.visibility = "visible";
    div.style.left = pos.left + x + "px";
    div.style.top = pos.top + y + "px";
}

function ShowPlotManagerWindow()
{
    if( IsGroupTrack()  )
    {
        alert( "Track overlays are currently unavailable for group tracks." );
        return;
    }
    
    var pos = GetPluginLocation();
    
    RestoreClick();
    
    if( IsCombinedTrack() == false )
    {
        if( o('SaveToCurrentDiv') )
            o('SaveToCurrentDiv').style.display = "none";
    }
    else
    {
        if( o('SaveAsNewDiv') ) 
            o('SaveAsNewDiv').style.display = "none";
    }
        
    var w=o('PlotManagerWindow');
    
    w.style.left = pos.left + 650 + "px";
    w.style.top = pos.top + 5 + "px";
    
    w.style.display="block";
    
    
}

function ShowPlotAnnotationInput(x,y)
{
    var div = o("PlotAnnotationInput");
  
    if( selectedViewObject >= 0 )
    {
        o("PlotAnnotationTextbox").value = viewObjects[selectedViewObject].Content;        
    }
    
    var pos = GetPluginLocation();
    
    div.style.left = pos.left + x + "px";
    div.style.top = pos.top + y + "px";
    div.style.visibility = "visible";
    
    objectX = x;
    objectY = y;
}

function SaveFindingClick()
{
    var panel = o("SaveViewPanel");
    panel.style.display="block";
}

function CancelSaveView()
{
    o("SaveViewPanel").style.display="none";
}

function SubmitPlotAnnotation()
{
    var obj;
    var sl = GetPlugin();
    var plotCanvas = sl.content.findName("plotCanvas");
    var inputText = o("PlotAnnotationTextbox").value;
    
    var cleanup = /[<>"#@&]/g;
    inputText = inputText.replace(cleanup," ");
    
    if( selectedViewObject >= 0 )
    {
        obj = viewObjects[selectedViewObject];
        obj.Content = inputText;
        
        var xamlObj = sl.content.findName(obj.Id+"");
        xamlObj.text = obj.Content+"";
    }
    else 
    {
        obj = new Object();
        obj.Id = viewObjects.length;
        obj.Y = objectY;
        obj.X = objectX;
    
        // Rectangle hack
        //
        var pattern = /^box (\d+) (\d+) (#?\w+)/;
        var result = inputText.match(pattern);
        if( result != null )
        {
           obj.Type="Rectangle";
           obj.Width = parseInt(result[1]);
           obj.Height = parseInt(result[2]);
           obj.Color = result[3];
        } 
        else 
        {
            obj.Type = "TextBlock";
            obj.Content = inputText;
        }
        
        viewObjects[viewObjects.length] = obj;
        
        var textObj = sl.content.CreateFromXAML( GetViewObjectXaml(obj) );  
          
        plotCanvas.Children.Add(textObj);
    }
    
    HideElement("PlotAnnotationInput");
    
    // Show the save icon...
    //
    o("ctl00_cphMainContent_usrTrack_saveFindingIcon").style.display="inline";
    
    // hide help, in case it is open
    o("PlotHelpDiv").style.display = "none";
    
    mouseButtonDown = 0;
    selectedViewObject = -1;
}

function CloseInput( id )
{
    mouseButtonDown=0;
    HideElement(id);
}

function GetViewObjectXaml( obj )
{
    var xaml = null;
    
    if( obj.Type == "TextBlock" )
    {
        xaml = "<TextBlock " +
                "xmlns=\"http://schemas.microsoft.com/client/2007\" " +
                "xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" " +
                "MouseEnter=\"ViewObjectMouseEnter\" " +
                "MouseLeave=\"ViewObjectMouseLeave\" " +
                "MouseLeftButtonDown=\"ViewObjectMouseDown\" " +
                "MouseLeftButtonUp=\"ViewObjectMouseUp\" " +
                "TextWrapping=\"Wrap\" " +
                "Width=\"200\" " +
                "FontSize=\"10\" "+
                "Foreground=\"Red\" " +
                "Text=\"" + obj.Content + "\" " +
                "Canvas.Top=\"" + obj.Y + "\" " +
                "Canvas.Left=\"" + obj.X + "\" " +
                "x:Name=\"" + obj.Id + "\" " +
                "></TextBlock>";
    }
    else if( obj.Type == "Rectangle" )
    {
        xaml = "<Rectangle " +
                "xmlns=\"http://schemas.microsoft.com/client/2007\" " +
                "xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" " +
                "x:Name=\"" + obj.Id + "\" " +
                "Stroke=\"" + obj.Color + "\" " +
                "StrokeThickness=\"" + "2" + "\" " +
                "Width=\"" + obj.Width + "\" " +
                "Height=\"" + obj.Height + "\" " +
                "Canvas.Top=\"" + obj.Y + "\" " +
                "Canvas.Left=\"" + obj.X + "\" " +
                "></Rectangle>";
    }
    
    return xaml;
}

function HighlightPlotLine( trackId, highlight )
{
    var sl = GetPlugin();
    var line = sl.content.findName("line-"+trackId);
    
    if(line)
    {
        line.strokeThickness = highlight ? "3" : "1";
        
        // redraw hack
        line["Visibility"] = "Collapsed";
        line["Visibility"] = "Visible";
    }
}

function ToggleMemberVisibility( trackId, show ) 
{
    var line = GetPlugin().content.findName("line-"+trackId);  
    if(line)
        line.Visibility = show ? "Visible" : "Collapsed";      
}

function GetPluginLocation()
{
    return GetElementPosition("TrackPlotDiv");
}

function LegendBarMouseButtonDown(sender,args)
{
    var legend = sender.findName("legendCanvas");
    legend.opacity="0.5";
    
    windowDragging=args.getPosition(null).x - legend["Canvas.Left"];
    
    if( windowDragging < 0 )
        windowDragging=0;
    
    sender.findName("plotCanvas").cursor="Hand";
}

function LegendBarMouseButtonUp(sender,args)
{
    windowDragging=0;
    sender.findName("legendCanvas").opacity="1.0";
    sender.findName("plotCanvas").cursor="Default";
}

function MoveLegend(sender,args)
{
    if(windowDragging > 0)
    {
        var legend = sender.findName("legendCanvas");
        legend["Canvas.Left"] = args.getPosition(null).x - windowDragging;
        legend["Canvas.Top"] = args.getPosition(null).y;
    }
}

function UpdateZoomRectangle(sender,args)
{
    if(mouseButtonDown > 0)
    {
        var rect = sender.findName("zoomRect");
        
        var rectX = rect["Canvas.Left"];
        var rectY = rect["Canvas.Top"];
        
        rect["Width"]=args.getPosition(null).x - rectX;
        rect["Height"]= PlotSize.Height - PlotMargin.Bottom; //args.getPosition(null).y - rectY;
        
        if( rect["Width"] > 1 )
            zoomDragging = 1;
            
    }
}

function CanvasMouseLeave(sender, args )
{
    sender.findName("animVLine").Visibility = "Collapsed";
    sender.findName("animHLine").Visibility = "Collapsed";
    
    sender.findName("animLabelX").Visibility="Collapsed";
    sender.findName("animLabelY").Visibility="Collapsed";
    
    if( o("AnnotationInput").style.visibility!="visible" )
        sender.findName("animCurrPt").Visibility="Collapsed";
    
    SetMeanLineVisibility(sender, "Collapsed");
    
    if( selectedCombinedTrack )
        ToggleCombinedTrackLegendLink( selectedCombinedTrack, 0 );
}

function GetNearestX( x )
{

    if( locArrX.length == 0 )
        GetPointData();
        
    var n = new Array(locArrX.length);
    
    for( var i=0; i<locArrX.length; i++ ) 
    {
        if( locArrX[i].length == 1 )
        {
            n[i] = 0;
            continue;
        }
        
        for( var j=0; j<locArrX[i].length; j++ ) 
        {
            if( j == locArrX[i].length-1 ) 
            {
                n[i]=j;
                break;
            }
            
            var diff = Math.abs(locArrX[i][j]-x);
            var diffNext = Math.abs(locArrX[i][j+1]-x);
            
            if( diff < diffNext ) 
            {
                n[i]=j;
                break;
            }     
        }
    }
    
    return n;
    
}

function GetNearestSeries( x, nearestX )
{
    var min = -1;
    var s = 0;
    
    for( var i=0; i<nearestX.length; i++ )
    {
        var tmp = locArrX[i][nearestX[i]];
        if( min < 0 ||
            Math.abs( tmp-x ) < min )
        {
            min = Math.abs(tmp-x);
            s = i;
        }
    }
    
    return s;
}


