// =========================
//
// mainPage methods
// General functions and event handlers for PageTurn app.
//
// =========================

var wpfe;                    // wpfe object reference
var maxNumPages = 14;       // total pages available
var currentDownload = 0;    // Current page downloading
var downloader              // WPF/E downloader

function onMainPageLoaded(sender, eventArgs)
{
    wpfe = document.getElementById("wpfeobj");

    downloadAssets();
}

function downloadAssets() {
    downloader = wpfe.createObject("Downloader");
  	downloader.downloadProgressChanged = "javascript:downloadProgressChanged";
  	downloader.completed = "javascript:downloadCompleted";
  	
  	downloader.open("GET", "assets/page" + getTwoDigitInt(currentDownload) + ".jpg", true);
  	downloader.send();
}

function downloadProgressChanged(sender, args) {
    var progressRect = sender.findName("progressRect");
    progressRect.width = (((currentDownload - 1) + sender.downloadProgress) / maxNumPages) * 450;
}

function downloadCompleted(sender, args) {
    currentDownload++;
    if (currentDownload <= maxNumPages) {
        var progressText = sender.findName("progressText");
        progressText.text = "Downloading: page" + getTwoDigitInt(currentDownload) + ".jpg";
        
        downloader.open("GET", "assets/page" + getTwoDigitInt(currentDownload) + ".jpg", true);
  	    downloader.send();
    }
    else {
        // Hide progress UI
        var downloadUI = sender.findName("downloadUI");
        downloadUI.opacity = 0;
        
        // initialize dragging elements
        beginPageAnimation("showFold");

        // add pages and thumbnails
        addOddPages();
        addEvenPages();
        addThumbnails();
    }
}

function getTwoDigitInt(number)
{
  // if this number already has two digits, return the int part
  if ((number < 0) || (number >= 10))
    return Math.floor(number).toString();

  // otherwise, prepend zero
  return "0" + Math.floor(number);
}

//create and add the pages on the left hand side of the book
function addOddPages()
{
    //this is the template for all odd pages
    var oddStr =      "<Canvas x:Name='page0$0' xmlns='http://schemas.microsoft.com/client/2007' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'";
    oddStr = oddStr + "        MouseLeftButtonDown='javascript:oddPageMouseDown' MouseLeftButtonUp='javascript:oddPageMouseUp' MouseMove='javascript:oddPageMouseMove'>";
    oddStr = oddStr + "  <Canvas.RenderTransform>";
    oddStr = oddStr + "    <TransformGroup>";
    oddStr = oddStr + "      <RotateTransform x:Name='page$0Rotate' CenterX='0' CenterY='570' Angle='0'/>";
    oddStr = oddStr + "      <TranslateTransform x:Name='page$0Translate' X='0' Y='0'/>";
    oddStr = oddStr + "    </TransformGroup>";
    oddStr = oddStr + "  </Canvas.RenderTransform>";
    oddStr = oddStr + "  <Canvas.Clip>";
    oddStr = oddStr + "    <PathGeometry>";
    oddStr = oddStr + "      <PathFigure>";
    oddStr = oddStr + "        <LineSegment Point='0,570'/>";
    oddStr = oddStr + "        <LineSegment x:Name='page$0Point1' Point='0, 570'/>";
    oddStr = oddStr + "        <LineSegment x:Name='page$0Point2' Point='0, 570'/>";
    oddStr = oddStr + "        <LineSegment x:Name='page$0Point3' Point='0, 570'/>";
    oddStr = oddStr + "        <LineSegment Point='0,570'/>";
    oddStr = oddStr + "      </PathFigure>";
    oddStr = oddStr + "    </PathGeometry>";
    oddStr = oddStr + "  </Canvas.Clip>";
    oddStr = oddStr + "  <Image Source='assets/page$0.jpg'/>";
    oddStr = oddStr + "  <Rectangle Height='1000' Width='20' Opacity='0.6' x:Name='page$0FoldShadow'>";
    oddStr = oddStr + "    <Rectangle.RenderTransform>";
    oddStr = oddStr + "      <TransformGroup>";
    oddStr = oddStr + "        <RotateTransform x:Name='page$0FoldShadowRotate' CenterX='0' CenterY='0' Angle='0'/>";
    oddStr = oddStr + "        <TranslateTransform x:Name='page$0FoldShadowTranslate' X='0' Y='0'/>";
    oddStr = oddStr + "      </TransformGroup>";
    oddStr = oddStr + "    </Rectangle.RenderTransform>";
    oddStr = oddStr + "    <Rectangle.Fill>";
    oddStr = oddStr + "      <LinearGradientBrush StartPoint='0,0' EndPoint='1,0'>";
    oddStr = oddStr + "        <GradientStop Color='#00000000' Offset='0'/>";
    oddStr = oddStr + "        <GradientStop Color='#FF000000' Offset='1'/>";
    oddStr = oddStr + "      </LinearGradientBrush>";
    oddStr = oddStr + "    </Rectangle.Fill>";
    oddStr = oddStr + "  </Rectangle>";
    oddStr = oddStr + "</Canvas>";

    // if maxNumPages is odd, we will ignore the last page, so last odd is two behind
    var _lastOdd;
    if (((maxNumPages/2) - Math.floor(maxNumPages/2)) == 0)
      _lastOdd = maxNumPages - 1;
    else
      _lastOdd = maxNumPages - 2;

    for (var i=1; i<=_lastOdd; i = i+2)
    {
      // $0: two digit index of this page
      var newOddPageStr = oddStr.replace(/\$0/g, getTwoDigitInt(i));
      var newOddPage = wpfe.createFromXaml(newOddPageStr);
      wpfe.findName("oddPageCanvas").children.add(newOddPage);
    }
}

//create and add the pages on the right hand side of the book
function addEvenPages()
{
    //this is the template for all even pages
    var evenStr =    "<Canvas x:Name='page0$0' xmlns='http://schemas.microsoft.com/client/2007' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>";
    evenStr = evenStr + "  <Canvas.Clip>";
    evenStr = evenStr + "    <PathGeometry>";
    evenStr = evenStr + "      <PathFigure>";
    evenStr = evenStr + "        <LineSegment Point='0,0'/>";
    evenStr = evenStr + "        <LineSegment Point='0, 570'/>";
    evenStr = evenStr + "        <LineSegment x:Name='page$0Point1' Point='420, 570'/>";
    evenStr = evenStr + "        <LineSegment x:Name='page$0Point2' Point='420, 570'/>";
    evenStr = evenStr + "        <LineSegment x:Name='page$0Point3' Point='420, 0'/>";
    evenStr = evenStr + "        <LineSegment Point='0,0'/>";
    evenStr = evenStr + "      </PathFigure>";
    evenStr = evenStr + "    </PathGeometry>";
    evenStr = evenStr + "  </Canvas.Clip>";
    evenStr = evenStr + "  <Image Source='assets/page$0.jpg'/>";
    evenStr = evenStr + "</Canvas>";

    // if maxNumPages is odd, we will ignore the last page, so last odd is two behind
    var _lastEven;
    if (((maxNumPages/2) - Math.floor(maxNumPages/2)) == 0)
      _lastEven = maxNumPages;
    else
      _lastEven = maxNumPages - 1;

    for (var i=_lastEven; i>=0; i = i-2)
    {
      // $0: index of this page
      var newEvenPageStr = evenStr.replace(/\$0/g, getTwoDigitInt(i));
      var newEvenPage = wpfe.createFromXaml(newEvenPageStr);
      wpfe.findName("evenPageCanvas").children.add(newEvenPage);
    }
}

//create and add thumbnails to pageBrowser
function addThumbnails()
{
    // this is the template for all thumbnails, given the following variables
    // $0: thumbnail number (1,2,...,maxNumPages/2)
    // $1: Canvas.Left position of this thumb (n-6)*70 - 5
    // $2: UIElement corresponding to the left page of this thumbnail
    // $3: UIElement corresponding to the right page of this thumbnail

    base =        "<Canvas xmlns='http://schemas.microsoft.com/client/2007' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' Canvas.Top='42' Canvas.Left='$1' x:Name='thumb$0' Opacity='0.5'>";
    base = base + "  <Canvas.Triggers>";
    base = base + "    <EventTrigger RoutedEvent='Canvas.Loaded'>";
    base = base + "      <BeginStoryboard>";
    base = base + "        <Storyboard BeginTime='5' Duration='Forever' FillBehavior='Stop' x:Name='storyZoomIn$0'>";
    base = base + "          <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Storyboard.TargetProperty='ScaleX' Storyboard.TargetName='scale$0'>";
    base = base + "            <SplineDoubleKeyFrame KeySpline='0.7,0,0.4,1' Value='0.25' KeyTime='00:00:00.3'/>";
    base = base + "          </DoubleAnimationUsingKeyFrames>";
    base = base + "          <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Storyboard.TargetProperty='ScaleY' Storyboard.TargetName='scale$0'>";
    base = base + "            <SplineDoubleKeyFrame KeySpline='0.7,0,0.4,1' Value='0.25' KeyTime='00:00:00.3'/>";
    base = base + "          </DoubleAnimationUsingKeyFrames>";
    base = base + "          <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Storyboard.TargetProperty='Y' Storyboard.TargetName='pos$0'>";
    base = base + "            <SplineDoubleKeyFrame KeySpline='0.7,0,0.4,1' Value='-30' KeyTime='00:00:00.3'/>";
    base = base + "          </DoubleAnimationUsingKeyFrames>";
    base = base + "          <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Storyboard.TargetProperty='Opacity' Storyboard.TargetName='thumb$0'>";
    base = base + "            <SplineDoubleKeyFrame KeySpline='0.7,0,0.4,1' Value='1' KeyTime='00:00:00.3'/>";
    base = base + "          </DoubleAnimationUsingKeyFrames>";
    base = base + "        </Storyboard>";
    base = base + "      </BeginStoryboard>";
    base = base + "    </EventTrigger>";
    base = base + "  </Canvas.Triggers>";
    base = base + "  <Rectangle x:Name='thumbBackground$0' Height='44' Width='63' Fill='#37000000' Opacity='1' Canvas.Left='-31' Canvas.Top='-42'/>";
    base = base + "  <Canvas>";
    base = base + "    <Canvas.RenderTransform>";
    base = base + "      <TransformGroup>";
    base = base + "        <ScaleTransform x:Name='scale$0' ScaleX='0.07' ScaleY='0.07'/>";
    base = base + "        <TranslateTransform x:Name='pos$0' X='0' Y='0'/>";
    base = base + "      </TransformGroup>";
    base = base + "    </Canvas.RenderTransform>";
    base = base + "    <Rectangle x:Name='thumbOver$0' Height='630' Width='900' Fill='#66000000' Opacity='0' Canvas.Top='-600' Canvas.Left='-450'/>";
    base = base + "    $2";
    base = base + "    $3";
    base = base + "  </Canvas>";
    base = base + "</Canvas>";

    pageBrowser = wpfe.findName("pageBrowser");

    for (var i=0; i<=(maxNumPages/2); i++)
    {
      // $0: thumbnail number (1,2,...,maxNumPages/2)
      var thumbStr = base.replace(/\$0/g, i);
      // $1: Canvas.Left position of this thumb (n-6)*70 - 5
      thumbStr = thumbStr.replace(/\$1/g, i*70 + 42);

      // $2, $3: UIElements corresponding to the left and right pages, respectively, of this thumbnail
      // special case the cover thumbnail
      if (i == 0)
      {
        // the left page is blank, and the right page is the cover
        thumbStr = thumbStr.replace(/\$2/g, "");
        thumbStr = thumbStr.replace(/\$3/g, "<Image Height='570' Width='420' Source='assets/page00.jpg' Canvas.Top='-570' Canvas.Left='0'/>");
      }
      else
      {
        // populate left and right images
        thumbStr = thumbStr.replace(/\$2/g, "<Image Height='570' Width='420' Source='assets/page"+getTwoDigitInt(2*i-1)+".jpg' Canvas.Top='-570' Canvas.Left='-420'/>");
        thumbStr = thumbStr.replace(/\$3/g, "<Image Height='570' Width='420' Source='assets/page"+getTwoDigitInt(2*i)+".jpg' Canvas.Top='-570' Canvas.Left='0'/>");
      }

      var newThumb = wpfe.createFromXaml(thumbStr);
      pageBrowser.children.add(newThumb);

      new Thumbnail(wpfe.findName("thumb"+i));
    }
}

// @x1: point where the bottom edges of the odd and even pages intersect, in even page coordinates.  Ranges from 0 to 420.
function updateScene(oddPageNumber, x1)
{
  // variables related to odd page
  var oddPoint1 = wpfe.findName("page" + getTwoDigitInt(oddPageNumber) + "Point1");
  var oddPoint2 = wpfe.findName("page" + getTwoDigitInt(oddPageNumber) + "Point2");
  var oddPoint3 = wpfe.findName("page" + getTwoDigitInt(oddPageNumber) + "Point3");
  var oddRotate = wpfe.findName("page" + getTwoDigitInt(oddPageNumber) + "Rotate");
  var oddTranslate = wpfe.findName("page" + getTwoDigitInt(oddPageNumber) + "Translate");
  var foldShadow = wpfe.findName("page" + getTwoDigitInt(oddPageNumber) + "FoldShadow");
  var foldShadowRotate = wpfe.findName("page" + getTwoDigitInt(oddPageNumber) + "FoldShadowRotate");
  var foldShadowTranslate = wpfe.findName("page" + getTwoDigitInt(oddPageNumber) + "FoldShadowTranslate");
  var shadowBehindPage01 = wpfe.findName("shadowBehindPage01");

  // variables related to the even page
  var evenPoint1 = wpfe.findName("page" + getTwoDigitInt(oddPageNumber-1) + "Point1");
  var evenPoint2 = wpfe.findName("page" + getTwoDigitInt(oddPageNumber-1) + "Point2");
  var evenPoint3 = wpfe.findName("page" + getTwoDigitInt(oddPageNumber-1) + "Point3");
  var shadowOnEvenPage = wpfe.findName("shadowOnEvenPage");

  // _alpha: angle between horizontal axis and bottom edge of odd page.
  //         this can be any function of x1.
  var _alpha = 90/420*x1;

  // update point 1 of even page
  evenPoint1.point = x1 + ",570";
  var shadowStr = x1 + ",570 ";
  shadowStr += Math.min((x1 + 30), 420)  + ",570 ";

  // _leftEdgeAngle: angle between horizontal axis and left edge of odd page
  var _leftEdgeAngle = 90 - _alpha;
  var _bottomLeftCornerX = x1 - Math.cos(_alpha*Math.PI/180) * (420 - x1);
  var _bottomLeftCornerY = Math.sin(_alpha*Math.PI/180) * (420 - x1);

  // update odd page's rotate and translate transform
  oddRotate.angle = _alpha;
  oddTranslate.x = 420 + _bottomLeftCornerX;
  oddTranslate.y = (-1) * _bottomLeftCornerY;

  // how much of the odd page's left edge can be seen
  var _visibleLeftEdgeHeight = (420 - _bottomLeftCornerX) / Math.cos(_leftEdgeAngle*Math.PI/180);

  // if the top left corner can be seen
  if (_visibleLeftEdgeHeight >= 570)
  {
    // height between top left corner of the odd page and top edge of the even page
    var _topLeftCornerY = _bottomLeftCornerY + Math.sin(_leftEdgeAngle*Math.PI/180)*570;

    // _visibleTopEdgeWidth: width of top edge of odd page that is visible
    var _visibleTopEdgeWidth;
    // _x2: x coordinate of the point where top edges of odd and even pages intersect
    var _x2;

    if (_topLeftCornerY > 570)
    {
      _visibleTopEdgeWidth = (_topLeftCornerY - 570) / Math.sin(_alpha*Math.PI/180);
      _x2 = _bottomLeftCornerX + Math.cos(_leftEdgeAngle*Math.PI/180)* 570 + (_topLeftCornerY - 570)/Math.tan(_alpha*Math.PI/180);
    }
    else
    {
      _visibleTopEdgeWidth = 420;
      _x2 = 0;
    }

    oddPoint1.point = "0, 0";
    oddPoint2.point = _visibleTopEdgeWidth + ", 0";

    // update foldShadow properties
    var _foldAngle = 90 - (180/Math.PI)*Math.atan(570/(420 - x1 - _visibleTopEdgeWidth));
    foldShadowRotate.angle = (-1) * _foldAngle;

    // need to adjust the position of the foldShadow so that it covers the entire folded edge
    var _foldShadowAdjustment = 40;
    foldShadowTranslate.x = _visibleTopEdgeWidth - 20 * Math.cos(_foldAngle*Math.PI/180) - _foldShadowAdjustment*Math.cos((90 - _foldAngle)*Math.PI/180);
    foldShadowTranslate.y =  20 * Math.sin(_foldAngle*Math.PI/180) - _foldShadowAdjustment*Math.sin((90 - _foldAngle)*Math.PI/180);;

    evenPoint2.point = _x2 + ",0";
    evenPoint3.point = _x2 + ",0";

    shadowStr += Math.min((_x2+10), 420) + ",0 " + _x2 + ",0";

  }
  // if the top left corner cannot be seen
  else
  {
    // update points of the odd page, which are both the same
    oddPoint1.point = "0, " + (570 - _visibleLeftEdgeHeight);
    oddPoint2.point = "0, " + (570 - _visibleLeftEdgeHeight);

    // update points of the even page
    var _y2 = 570 - _bottomLeftCornerY - (420 - _bottomLeftCornerX) * Math.tan(_leftEdgeAngle*Math.PI/180);
    evenPoint2.point = "420," + _y2 ;
    evenPoint3.point = "420,0";

    // update shadow string on top of the even page
    shadowStr += "420," + _y2 + " 420," + _y2;

    // update foldShadow properties
    var _foldAngle = 90 - (180/Math.PI)*Math.atan(_visibleLeftEdgeHeight/(420 - x1));
    foldShadowRotate.angle = (-1) * _foldAngle;
    foldShadowTranslate.x = (-1) * 20 * Math.cos(_foldAngle*Math.PI/180) ;
    foldShadowTranslate.y =  (570 - _visibleLeftEdgeHeight) +  20 * Math.sin(_foldAngle*Math.PI/180) ;
  }

  oddPoint3.point = (420 - x1) + ", 570";
  shadowOnEvenPage.points = shadowStr;

  //
  if (x1 < 15)
  {
    shadowOnEvenPage.opacity = 0.25*(x1/15);
    foldShadow.opacity = 0.6*(x1/15);
    if (oddPageNumber > 1) {  shadowBehindPage01.opacity = 0.8; }
    else {  shadowBehindPage01.opacity = 0.8 - 0.8*(x1/15); }
  }
  else
  {
    shadowOnEvenPage.opacity = 0.25;
    foldShadow.opacity = 0.6;
    if (oddPageNumber > 1) {  shadowBehindPage01.opacity = 0.8; }
    else {  shadowBehindPage01.opacity = 0; }
  }
}