// Barebones WPFe Ink Sample, Gavin Gear (gaving)

var wpf;
var inkPresenter; // Corresponds to InkPresenter element in xaml
var newStroke = null; // The Stroke variable we’ll use here in mouse handlers
var currentColor="#FF000000"; //black
var currWidth=3; //default..narrow
var isEraser=false;
var StartLeft=0;
var EndLeft=150;
var StartPenTop=0;
var EndPenTop=63;
var BorderAnimation;
var isRecording;
var recordingTime=0;
var mystrokeCollectionXaml;
var persistenceXml;

function root_Loaded(sender, args) 
{
    wpf = document.getElementById("wpfobj");
    inkPresenter = sender.findname("inkPresenterElement");
}

// Capture mouse and create the stroke
function InkPresenterMouseDown(sender,args)
{
if (isRecording)
   RecordingMouseDown(sender,args);
else
{
if (isEraser==false)
  {
   inkPresenter.CaptureMouse();
   newStroke = wpf.content.createFromXaml('<Stroke/>');
   
   newStroke.StylusPoints.AddStylusPoints(args.GetStylusPoints(inkPresenter));
  newStroke.DrawingAttributes.Color=currentColor;
newStroke.DrawingAttributes.Width=currWidth;
newStroke.DrawingAttributes.OutlineColor="#FFFFFF";
inkPresenter.Strokes.Add(newStroke);
}
else
  {
 var sc = wpf.content.createFromXaml("<StrokeCollection/>");
    sc = inkPresenter.Strokes.HitTest(args.GetStylusPoints(inkPresenter));
    
    for (var i = 0; i < sc.Count; i++)
    {
      inkPresenter.Strokes.Remove(sc.GetItem(i));
    }

  }


   
}}

// Add the new points to the Stroke we’re working with
function InkPresenterMouseMove(sender,args)
{if (isRecording)
   RecordingMouseMove(sender,args);
else
{
   if (newStroke != null)
   {
      newStroke.StylusPoints.AddStylusPoints(args.GetStylusPoints(inkPresenter));
   }
}}

function InkPresenterMouseMovewithPen(sender,args)
{
   if (newStroke != null)
   {
      newStroke.StylusPoints.AddStylusPoints(args.GetStylusPoints(inkPresenter));
      var pen= sender.findname("pen");
      pen["Canvas.Left"] = args.getPosition(null).x - 10
       pen["Canvas.Top"] = args.getPosition(null).y - 150;
   }
}

// Release the mouse
function InkPresenterMouseUp(sender,args)
{if (isRecording)
   RecordingMouseUp(sender,args);
else

   newStroke = null;
}

//changeink
function ChangeColor(sender,args)
{
currObj=sender;
//currObj=sender.findName("ColorRect");
//width of entire rectangle
rectWidth=currObj.width;
//width per gradient stop
gradWidth=rectWidth/currObj.Fill.GradientStops.Count;
//current X position
currx= args.GetPosition(currObj).x
//current gradient stop
currGrad=(currObj.Fill.GradientStops.Count)-Math.round(currx/gradWidth);
if (currGrad==currObj.Fill.GradientStops.Count) currGrad-=1
//current color
currColor=BrowserColorConverter(currObj.Fill.GradientStops.GetItem(currGrad).Color);
currentColor=currColor+''; 

}

function ChangePen(sender,args)
{
StartPenTop=EndPenTop;
if (sender.Name=="PenNarrow")
  {
  currWidth=3;
  isEraser=false;
  EndPenTop=63;
  }
 if (sender.Name=="PenWide")
 {
 currWidth=10;
 isEraser=false;
  EndPenTop=26;
 }
if (sender.Name=="Eraser")
{
isEraser=true;
  EndPenTop=104;
}

//move ellipse over current pen
borderAnimation=sender.findName("MovePenBorderAni");

borderAnimation.from=StartPenTop;
borderAnimation.to=EndPenTop;
sender.findName("MovePenBorder").begin();

}

//redink
function RedInk(sender,args)
{
currentColor="#FFFF0000";
//also fire the storyboard trigger
//sender.findName("ButtonBorder")["Canvas.Left"]=0;
borderAnimation=sender.findName("MoveBorderAni");
StartLeft=EndLeft; //position of current
EndLeft=0; //postion of red
borderAnimation.from=StartLeft;
borderAnimation.to=EndLeft;
sender.findName("MoveBorder").begin();
}
//redink
function BlueInk(sender,args)
{
currentColor="#FF000080";
//also fire the storyboard trigger
borderAnimation=sender.findName("MoveBorderAni");
StartLeft=EndLeft; //position of current
EndLeft=75; //postion of navy
borderAnimation.from=StartLeft;
borderAnimation.to=EndLeft;
sender.findName("MoveBorder").begin();
//sender.findName("ButtonBorder")["Canvas.Left"]=75;
}
function BlackInk(sender,args)
{
currentColor="#FF000000";
//also fire the storyboard trigger

//sender.findName("ButtonBorder")["Canvas.Left"]=150;

borderAnimation=sender.findName("MoveBorderAni");
StartLeft=EndLeft; //position of current
EndLeft=150; //postion of black
borderAnimation.from=StartLeft;
borderAnimation.to=EndLeft;
sender.findName("MoveBorder").begin();
}
function ReplayInk(sender,args)
{
 newStroke = null;
sender.findName("ButtonGlower")["Canvas.Left"]=675;
sender.findName("GlowButton").begin();
 setStrokes();
 resetInkPlayback();
 timerStrokeCompleted(sender, args);
  
  newStroke = null;
}

function GetStoredStrokeCollection(sender,args)
{
//debugger;
sender.findName("ButtonGlower")["Canvas.Left"]=450;
sender.findName("GlowButton").begin();
    GetInkStrokes("inkPresenterElement");

    }    
    
        
        function DisplayRetrievedStrokes(ajaxstrokeCollection,currentElementName)
        {        
            //debugger;
        strokeCollection =  wpf.content.createFromXaml(ajaxstrokeCollection);
            var inkPres = wpf.content.findName(currentElementName);
              inkPres.Strokes = strokeCollection;

}

function GetStoredStrokeCollectionx(sender,args)
{

if (mystrokeCollectionXaml == null)
{
   //get xaml out of savedInk.xml, which is known by xml element in html
//      var persistenceXml = document.getElementById("persistenceFromServerXml");
//debugger;
LoadXML();

    if (persistenceXml != null && persistenceXml.documentElement != null)
              
            var inkdata = persistenceXml.documentElement.selectSingleNode("/InkCollection/Ink[@Number='1']");
            //var inkdata=SelectSingleNode(persistenceXml,"/InkCollection/Ink[@Number='1']");
            if (inkdata != null)
            {
               var strokeCollectionNode = inkdata.selectSingleNode("./strokeData/StrokeCollection");
              //var strokeCollectionNode = SelectSingleNode(inkdata,"./strokeData/StrokeCollection"); 
                if (strokeCollectionNode != null)
                {
                     mystrokeCollectionXaml = strokeCollectionNode.xml;
                     
                }
    }
    } 
            strokeCollection = 
                wpf.content.createFromXaml(mystrokeCollectionXaml);
                
            var inkPresenter = wpf.content.findName("inkPresenterElement");
            inkPresenter.Strokes = strokeCollection;
           

}
function ClearStrokes(sender,args)
{

sender.findName("ButtonGlower")["Canvas.Left"]=525;
sender.findName("GlowButton").begin();

            var inkPresenter = wpf.content.findName("inkPresenterElement");
            var strokeCollection;
            inkPresenter.Strokes.Clear();
}



function storeStrokes(sender,args)
{
sender.findName("ButtonGlower")["Canvas.Left"]=600;
sender.findName("GlowButton").begin();

            var inkPresenter = wpf.content.findName("inkPresenterElement");
            var strokeCollection;
           strokeCollection= inkPresenter.Strokes;
           if (strokeCollection.Count>0)
             {

    var xaml = "<StrokeCollection>";
    //debugger;
    if (strokeCollection != null)
    {
        for (var i = 0; i < strokeCollection.Count; i++)
        {
            var stroke = strokeCollection.GetItem(i);
            xaml += "<Stroke><Stroke.DrawingAttributes>";
            xaml += "<DrawingAttributes ";
            
            xaml += "Color='" + BrowserColorConverter(stroke.DrawingAttributes.Color) + "' ";
            xaml += "OutlineColor='" + BrowserColorConverter(stroke.DrawingAttributes.OutlineColor) + "' ";
            xaml += "Width='" + stroke.DrawingAttributes.Width + "' ";
            xaml += "Height='" + stroke.DrawingAttributes.Height + "' ";
            xaml += "/></Stroke.DrawingAttributes>";
            
            xaml += "<Stroke.StylusPoints>";
            for (var j = 0; j < stroke.StylusPoints.Count; j++)
            {
                var stylusPoint = stroke.StylusPoints.GetItem(j);
                xaml += "<StylusPoint X='" + roundToTwoDecimalPlaces(stylusPoint.X) + "' Y='" + roundToTwoDecimalPlaces(stylusPoint.Y) + "' />";
            }
            xaml += "</Stroke.StylusPoints></Stroke>";
        }
    }
    xaml += "</StrokeCollection>";
mystrokeCollectionXaml=xaml;
    //replace Ink Number1 with this data - which should be an updated version of the node
     
// var persistenceXml = document.getElementById("persistenceFromServerXml");
//       var inkdata = persistenceXml.documentElement.selectSingleNode("/InkCollection/Ink[@Number='1']");
//            if (inkdata != null)
//            {
//          
//                var strokeCollectionNode = inkdata.selectSingleNode("./strokeData/StrokeCollection");
//debugger;
//objText = persistenceXml.createTextNode(xaml);

//strokeCollectionNode.nodeValue=objText;
//strokeCollectionNode.replaceChild(objText,strokeCollectionNode.childNodes.item(0));
//strokeCollectionNode.text=objText.text;
//}

UpdateStoredInk(xaml);
}
    }
    
    //simple method to round a number
function roundToTwoDecimalPlaces(number)
{
    var wholeNumber = Math.floor(number);
    var fraction = number - wholeNumber;
    fraction *= 100;
    fraction = Math.round(fraction);
    fraction /= 100;
    return wholeNumber + fraction; 
}

// Since silverlight colors are represented as signed integers (but can not be parsed that way)
// we need to get the RGB hex string for the color
function convertColorToHexString(c)
{
        // Note: there's an issue where saving a color to a string yeilds a signed int 
        var hexString1 = ((c & 0xFF0000) >> 16).toString(16);
        if(hexString1.length == 1)
        {
            hexString1 = "0" + hexString1;
        }
        
        var hexString2 = ((c & 0xFF00) >> 8).toString(16);
        if(hexString2.length == 1)
        {
            hexString2 = "0" + hexString2;
        }
        
        var hexString3 = (c & 0xFF).toString(16);
        if(hexString3.length == 1)
        {
            hexString3 = "0" + hexString3;
        }
 
        return "#" + hexString1 + hexString2 + hexString3;
}

function BrowserColorConverter(jscolorvalue)
{
//debugger;
var hex=convertColorToHexString(jscolorvalue);
//if(navigator.userAgent.indexOf("Firefox")!=-1 || navigator.userAgent.indexOf("Safari")!=-1)
// return 4294967296 + jscolorvalue;
// else
 return hex;
}
function PathCheckBox(sender, args)
{
   if (sender.findName("PathCheckBox").Text=="unchecked")
      {
        sender.findName("1Check").Stroke="black"; 
        sender.findName("2Check").Stroke="black";
        sender.findName("PathCheckBox").Text="checked" 
          }
             else
                {      
                sender.findName("1Check").Stroke="White";
                sender.findName("2Check").Stroke="White";
                sender.findName("PathCheckBox").Text="unchecked"   }}
function RecordClicked(sender,args)
{
newStroke=null;
   if (isRecording)
   {
   isRecording=false;
   sender.findName("UnglowRecordButton").begin();
}
else
{
isRecording=true;
recordingTime=0;
recordingStart=time;
sender.findName("GlowRecordButton").begin();
}
}                


function LoadXML()
{

//debugger;

if (window.ActiveXObject)
  {
  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  xmlDoc.async=false;
  xmlDoc.load("SavedInk.xml");
persistenceXml=xmlDoc;
  }
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation &&
document.implementation.createDocument)
  {
  xmlDoc=document.implementation.createDocument("","",null);
  xmlDoc.load("SavedInk.xml");
persistenceXml=xmlDoc;  
  }
else
  {
  alert('Your browser cannot handle this script');
  }
  
}

//helper function for selectsinglenode so FireFox can deal withit
//courtesy of Scott Sargent http://weblogs.asp.net/ssargent/archive/2007/01/25/selectsinglenode-and-firefox.aspx

    function SelectSingleNode(xmlDoc, elementPath)
    {
        if(window.ActiveXObject)
        {
            return xmlDoc.selectSingleNode(elementPath);
        }
        else
        {
//           var xpe = new XPathEvaluator();
//           var nsResolver = xpe.createNSResolver( xmlDoc.ownerDocument == null ? xmlDoc.documentElement : xmlDoc.ownerDocument.documentElement);
//           var results = xpe.evaluate(elementPath,xmlDoc,nsResolver,XPathResult.FIRST_ORDERED_NODE_TYPE, null);
//           return results.singleNodeValue; 

  var oEvaluator = new XPathEvaluator();
    var oResult = oEvaluator.evaluate(elementPath, xmlDoc, null, 
		XPathResult.FIRST_ORDERED_NODE_TYPE, null);
	if (oResult != null) {
        return oResult.singleNodeValue;
    } else {
        return null;
    }              

        }
    }

// mozXPath [http://km0ti0n.blunted.co.uk/mozxpath/] km0ti0n@gmail.com
// Code licensed under Creative Commons Attribution-ShareAlike License 
// http://creativecommons.org/licenses/by-sa/2.5/
if( document.implementation.hasFeature("XPath", "3.0") )
{
	XMLDocument.prototype.selectNodes = function(cXPathString, xNode)
	{
		if( !xNode ) { xNode = this; } 

		var oNSResolver = this.createNSResolver(this.documentElement)
		var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
		var aResult = [];
		for( var i = 0; i < aItems.snapshotLength; i++)
		{
			aResult[i] =  aItems.snapshotItem(i);
		}
		
		return aResult;
	}
	XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode)
	{
		if( !xNode ) { xNode = this; } 

		var xItems = this.selectNodes(cXPathString, xNode);
		if( xItems.length > 0 )
		{
			return xItems[0];
		}
		else
		{
			return null;
		}
	}

	Element.prototype.selectNodes = function(cXPathString)
	{
		if(this.ownerDocument.selectNodes)
		{
			return this.ownerDocument.selectNodes(cXPathString, this);
		}
		else{throw "For XML Elements Only";}
	}

	Element.prototype.selectSingleNode = function(cXPathString)
	{	
		if(this.ownerDocument.selectSingleNode)
		{
			return this.ownerDocument.selectSingleNode(cXPathString, this);
		}
		else{throw "For XML Elements Only";}
	}

}