var MARGIN = 40;

function Pnt()
{
    this.x = 0.0;
    this.y = 0.0;
    this.t = 0.0;
}

function DrawScale( x, y, l, scale, jg )
{
    oldColor = jg.color;
    oldStroke = jg.stroke;    
    jg.setColor( "black" );
    jg.setStroke( 3 );
    jg.drawLine( x, y, x + l, y );
    jg.setStroke( 1 );
    jg.drawLine( x, y, x, y - 3 );    
    jg.drawLine( x + l + 2, y, x + l + 2, y - 3 );        
    jg.drawString( scale, x + l + 2 + 15, y - 10 );        
    jg.setColor( oldColor );
    jg.setStroke( oldStroke );    
}

function DrawArrow( x0, y0, x1, y1, arrowLength, arrowWidth, jg )
{
    l = Math.sqrt( ( x1 - x0 )*( x1 - x0 ) + ( y1 - y0 )*( y1 - y0 ) );
    if ( arrowLength > l )
        arrowLength = l / 2;
    x2 = x0 + ( 1 - arrowLength / l ) * ( x1 - x0 ) ;
    y2 = y0 + ( 1 - arrowLength / l ) * ( y1 - y0 ) ;    
    alpha = Math.atan2( y1 - y0, x1 - x0 );
    x2a = arrowWidth * Math.cos( alpha + Math.PI / 2 );
    y2a = arrowWidth * Math.sin( alpha + Math.PI / 2 );    
    x2b = x2 - x2a;
    y2b = y2 - y2a;
    x2a = x2 + x2a;
    y2a = y2 + y2a;
    
    old = jg.stroke;
    jg.drawLine( x0, y0, x2, y2 );    
    jg.setStroke( 1 );
    jg.fillPolygon( Array( x2a,x2b,x1 ),  Array( y2a,y2b,y1 ) );
    jg.setStroke( old );    
    
}

function GetMin( a, b, c )
{
   var ret = 0;
    if ( a < b )
    {
        if ( a < c )
            ret = a;
        else
            ret = c;
    }
    else
    {
        if ( b < c )
            ret = b;
        else
            ret = c;
    }
    return ret;
}

function GetMax( a, b, c )
{
   var ret = 0;
    if ( a > b )
    {
        if ( a > c )
            ret = a;
        else
            ret = c;
    }
    else
    {
        if ( b > c )
            ret = b;
        else
            ret = c;
    }
    return ret;
}

function GetScreenBottomLeft( pntResult, pntScreenSize, pntModelWindowMin, pntModelWindowMax )
{
    var pntMin = new Pnt();
    var pntMax = new Pnt(); 
    pntMin.x = pntModelWindowMin.x;
    pntMin.y = pntModelWindowMin.y;    
    pntMax.x = pntModelWindowMax.x;
    pntMax.y = pntModelWindowMax.y;
    dWidth = pntMax.x - pntMin.x ;
    dHeight = pntMax.y - pntMin.y ;    
    dRatio = pntScreenSize.x / pntScreenSize.y;
    // Modify the target Model Window to fit exactly in the screen 
    if ( dWidth / dHeight > dRatio )
    {
        dNewHeight = dWidth / dRatio ;
        dHeightIncrease = ( dNewHeight - dHeight ) / 2 ;
        pntMin.y = pntMin.y - dHeightIncrease;
        pntMax.y = pntMax.y + dHeightIncrease;        
    }
    else if ( dWidth / dHeight < dRatio )
    {
        dNewWidth = dHeight * dRatio ;
        dWidthIncrease = ( dNewWidth - dWidth ) / 2 ;
        pntMin.x = pntMin.x - dWidthIncrease;
        pntMax.x = pntMax.x + dWidthIncrease;            
    }
    
        
    // set final values
    pntResult.t = pntScreenSize.x / ( pntMax.x - pntMin.x );
    pntResult.x = -pntMin.x;
    pntResult.y = -pntMin.y;  
}

function CalcRbVb()
{
    Ihc = 0;
    Vef = 0;
    Vb = 0;
    Rc = new LongLat();
    Ref = new LongLat();
    Rb = new LongLat();
    
    // Get form data
    GetData( Rc, "DegC", "MinC", "", "" );
    GetData( Ref, "DegEf", "MinEf", "", "" );
    Ihc = GetSingleData( "Ihc" );
    Vef = GetSingleData( "Vef" );
    
    // Vector coord for Vef
    x1 = Vef * Math.cos( GetDegrees( Ref ) * Math.PI / 180 ); 
    y1 = Vef * Math.sin( GetDegrees( Ref ) * Math.PI / 180 );     
    
    // Vector coord for Ihc
    x2 = Ihc * Math.cos( GetDegrees( Rc ) * Math.PI / 180 ); 
    y2 = Ihc * Math.sin( GetDegrees( Rc ) * Math.PI / 180 );     
    // Calc Vb = Vef - Ihc
    x3 = x1 - x2 ;
    y3 = y1 - y2 ;

    if ( Math.abs( x3 ) < 0.001 && Math.abs( y3 ) < 0.001 ) 
    {
        // This case happens when Ihc = -Vef. This is an error, Vb should be infinite to be able to reach the destination point
        Vb = 0;
        Rb = 0;
    }
    else
    {
        Vb = Math.sqrt( x3 * x3 + y3 * y3 );
        ang = Math.atan2( y3, x3 )  * 180 / Math.PI;
        while( ang < 0 ) 
            ang = ang + 360;
        SetDMS( ang, Rb );
        // The following line is to round the result so it can be displayed correctly later
        SetDMS( Rb.degrees + Round( Rb.minutes + Rb.seconds / 60, 2 ) / 60, Rb ) ; 
    }
    
    // Fill in form results
    document.getElementById('Vb').value = Round( Vb, 5 );
    document.getElementById('DegB').value = Rb.degrees;    
    document.getElementById('MinB').value = Round( Rb.minutes + Rb.seconds / 60, 2 );        
    
    // show text
    document.getElementById('ResultPane').style.display = 'block';    
    document.getElementById('ProcRbVb').style.display = 'block';
    document.getElementById('ProcRefVef').style.display = 'none';    
    document.getElementById('ProcRbVef').style.display = 'none';
    
    // Create graphics    
    // Get max min points
    pnt1 = new Pnt();
    pnt2 = new Pnt();
    pnt0 = new Pnt();    
    pntResult = new Pnt();
    pntScreenSize = new Pnt();
    pntScreenOriginOffset = new Pnt();    
    pntModelWindowMin = new Pnt();
    pntModelWindowMax = new Pnt();
    
    pnt1.x = Vef * Math.cos( ( GetDegrees( Ref ) + 90 ) * Math.PI / 180 ) ;
    pnt1.y = Vef * Math.sin( ( GetDegrees( Ref ) + 90 )  * Math.PI / 180 ) ;    
    pnt2.x = Ihc * Math.cos( ( GetDegrees( Rc ) + 90 ) * Math.PI / 180 ) ;
    pnt2.y = Ihc * Math.sin( ( GetDegrees( Rc ) + 90 ) * Math.PI / 180 ) ;        
    pntModelWindowMin.y = GetMin( pnt1.y, pnt2.y, pnt0.y );    
    pntModelWindowMin.x = GetMin( pnt1.x, pnt2.x, pnt0.x );        
    pntModelWindowMax.y = GetMax( pnt1.y, pnt2.y, pnt0.y );    
    pntModelWindowMax.x = GetMax( pnt1.x, pnt2.x, pnt0.x );

    pntScreenSize.x = parseFloat( document.getElementById('Graph').style.width ) - MARGIN * 2;
    pntScreenSize.y = parseFloat( document.getElementById('Graph').style.height ) - MARGIN * 2;    
    pntScreenOriginOffset.x = MARGIN;
    pntScreenOriginOffset.y = MARGIN;    
    GetScreenBottomLeft( pntResult, pntScreenSize, pntModelWindowMin, pntModelWindowMax )    

    
    // Call jsGraphics() with no parameters if drawing within the entire document
    var jg = new jsGraphics("Graph");    // Use the "Canvas" div for drawing
    jg.clear();
    jg.paint(); 
    jg.setFont( 'verdana,geneva,helvetica,sans-serif', "16px", Font.PLAIN);
    //jg.drawRect((pntModelWindowMin.x + pntResult.x )*pntResult.t,
    //            (pntModelWindowMin.y + pntResult.y )*pntResult.t,
    //            (pntModelWindowMax.x-pntModelWindowMin.x )*pntResult.t,
    //            (pntModelWindowMax.y-pntModelWindowMin.y )*pntResult.t);

    arrowLength = 20;
    arrowHeight = 5;
    
    // Draw axis and scale
    jg.setStroke(1);
    jg.setColor("black"); 
    pntAxis0 = new Pnt();
    pntAxis0.x = pntScreenOriginOffset.x + pntScreenSize.x - (pnt0.x + pntResult.x )*pntResult.t;
    pntAxis0.y = pntScreenOriginOffset.y + pntScreenSize.y - (pnt0.y + pntResult.y )*pntResult.t;
    DrawArrow( pntAxis0.x,  
               pntAxis0.y, 
               pntAxis0.x, 
               MARGIN , arrowLength, arrowHeight, jg );
    jg.drawString( "N", pntAxis0.x - 6, MARGIN - 20);
    //DrawScale( 0, pntScreenSize.y + 1.8 * MARGIN, pntResult.t, "1'", jg )
    DrawScale( 0, 10, pntResult.t, "1'", jg );

    // Draw vectors
    jg.setStroke(2);    
    jg.setColor("orange");
    DrawArrow( pntScreenOriginOffset.x + pntScreenSize.x - (pnt0.x + pntResult.x )*pntResult.t,  
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt0.y + pntResult.y )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.x - (pnt2.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt2.y + pntResult.y )*pntResult.t, arrowLength, arrowHeight, jg );
    jg.setColor("magenta");
    DrawArrow( pntScreenOriginOffset.x + pntScreenSize.x - (pnt0.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt0.y + pntResult.y )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.x - (pnt1.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt1.y + pntResult.y )*pntResult.t, arrowLength, arrowHeight, jg );
    jg.setColor("red");
    DrawArrow( pntScreenOriginOffset.x + pntScreenSize.x - (pnt2.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.y - (pnt2.y + pntResult.y )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.x - (pnt1.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.y - (pnt1.y + pntResult.y )*pntResult.t, arrowLength, arrowHeight, jg );
    jg.paint(); 

}

function CalcRefVef()
{
    Ihc = 0;
    Vef = 0;
    Vb = 0;
    Rc = new LongLat();
    Ref = new LongLat();
    Rb = new LongLat();
    
    // Get form data
    GetData( Rc, "DegC", "MinC", "", "" );
    GetData( Rb, "DegB", "MinB", "", "" );
    Ihc = GetSingleData( "Ihc" );
    Vb = GetSingleData( "Vb" );
    // Vector coord for Vb
    x1 = Vb * Math.cos( GetDegrees( Rb ) * Math.PI / 180 ); 
    y1 = Vb * Math.sin( GetDegrees( Rb ) * Math.PI / 180 );     
    
    // Vector coord for Ihc
    x2 = Ihc * Math.cos( GetDegrees( Rc ) * Math.PI / 180 ); 
    y2 = Ihc * Math.sin( GetDegrees( Rc ) * Math.PI / 180 );     
    
    // Calc Vb = Vb +  Ihc
    x3 = x1 + x2 ;
    y3 = y1 + y2 ;
    
    if ( Math.abs( x3 ) < 0.001 && Math.abs( y3 ) < 0.001 ) 
    {
        // This case happens when Ihc = -Vef. This is an error, Vb should be infinite to be able to reach the destination point
        Vef = 0;
        Ref = 0;
    }
    else
    {
        Vef = Math.sqrt( x3 * x3 + y3 * y3 );
        ang = Math.atan2( y3, x3 )  * 180 / Math.PI;
        while( ang < 0 ) 
            ang = ang + 360;
        SetDMS( ang, Ref );
        // The following line is to round the result so it can be displayed correctly later
        SetDMS( Ref.degrees + Round( Ref.minutes + Ref.seconds / 60, 2 ) / 60, Ref ) ;         
    }

    // Fill in form results
    document.getElementById('Vef').value = Round( Vef, 5 );
    document.getElementById('DegEf').value = Ref.degrees;    
    document.getElementById('MinEf').value = Round( Ref.minutes + Ref.seconds / 60, 2 )  ;   

    //Show text
    document.getElementById('ResultPane').style.display = 'block';    
    document.getElementById('ProcRbVb').style.display = 'none';
    document.getElementById('ProcRefVef').style.display = 'block';    
    document.getElementById('ProcRbVef').style.display = 'none';        
    
    // Create graphics    
    // Get max min points
    pnt1 = new Pnt();
    pnt2 = new Pnt();
    pnt0 = new Pnt();    
    pntResult = new Pnt();
    pntScreenSize = new Pnt();
    pntScreenOriginOffset = new Pnt();    
    pntModelWindowMin = new Pnt();
    pntModelWindowMax = new Pnt();
    
    pnt1.x = Ihc * Math.cos( ( GetDegrees( Rc ) + 90 ) * Math.PI / 180 ) ;
    pnt1.y = Ihc * Math.sin( ( GetDegrees( Rc ) + 90 ) * Math.PI / 180 ) ;        
    pnt2.x = pnt1.x + Vb * Math.cos( ( GetDegrees( Rb ) + 90 ) * Math.PI / 180 ) ;
    pnt2.y = pnt1.y + Vb * Math.sin( ( GetDegrees( Rb ) + 90 )  * Math.PI / 180 ) ;    
    pntModelWindowMin.y = GetMin( pnt1.y, pnt2.y, pnt0.y );    
    pntModelWindowMin.x = GetMin( pnt1.x, pnt2.x, pnt0.x );        
    pntModelWindowMax.y = GetMax( pnt1.y, pnt2.y, pnt0.y );    
    pntModelWindowMax.x = GetMax( pnt1.x, pnt2.x, pnt0.x );
    pntScreenSize.x = parseFloat( document.getElementById('Graph').style.width ) - MARGIN * 2;
    pntScreenSize.y = parseFloat( document.getElementById('Graph').style.height ) - MARGIN * 2;    
    pntScreenOriginOffset.x = MARGIN;
    pntScreenOriginOffset.y = MARGIN;    
    GetScreenBottomLeft( pntResult, pntScreenSize, pntModelWindowMin, pntModelWindowMax )    

    
    // Call jsGraphics() with no parameters if drawing within the entire document
    var jg = new jsGraphics("Graph");    // Use the "Canvas" div for drawing
    jg.clear();
    jg.paint(); 
    jg.setFont( 'verdana,geneva,helvetica,sans-serif', "16px", Font.PLAIN)

    //jg.drawRect((pntModelWindowMin.x + pntResult.x )*pntResult.t,
    //            (pntModelWindowMin.y + pntResult.y )*pntResult.t,
    //            (pntModelWindowMax.x-pntModelWindowMin.x )*pntResult.t,
    //            (pntModelWindowMax.y-pntModelWindowMin.y )*pntResult.t);

    arrowLength = 20;
    arrowHeight = 5;
    
    // Draw axis and scale
    jg.setStroke(1);
    jg.setColor("black");
    pntAxis0 = new Pnt();
    pntAxis0.x = pntScreenOriginOffset.x + pntScreenSize.x - (pnt0.x + pntResult.x )*pntResult.t;
    pntAxis0.y = pntScreenOriginOffset.y + pntScreenSize.y - (pnt0.y + pntResult.y )*pntResult.t;
    DrawArrow( pntAxis0.x,  
               pntAxis0.y, 
               pntAxis0.x, 
               MARGIN , arrowLength, arrowHeight, jg );
    jg.drawString( "N", pntAxis0.x - 6, MARGIN - 20);
    //DrawScale( 0, pntScreenSize.y + 1.8 * MARGIN, pntResult.t, "1'", jg )
    DrawScale( 0, 10, pntResult.t, "1'", jg );
    
    // Draw vectors
    jg.setStroke(2);
    jg.setColor("orange");
    DrawArrow( pntScreenOriginOffset.x + pntScreenSize.x - (pnt0.x + pntResult.x )*pntResult.t,  
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt0.y + pntResult.y )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.x - (pnt1.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt1.y + pntResult.y )*pntResult.t, arrowLength, arrowHeight, jg );
    jg.setColor("magenta");
    DrawArrow( pntScreenOriginOffset.x + pntScreenSize.x - (pnt1.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt1.y + pntResult.y )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.x - (pnt2.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt2.y + pntResult.y )*pntResult.t, arrowLength, arrowHeight, jg );
    jg.setColor("red");
    DrawArrow( pntScreenOriginOffset.x + pntScreenSize.x - (pnt0.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.y - (pnt0.y + pntResult.y )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.x - (pnt2.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.y - (pnt2.y + pntResult.y )*pntResult.t, arrowLength, arrowHeight, jg );
    jg.paint(); 
}

function CalcRbVef()
{
    Ihc = 0;
    Vef = 0;
    Vb = 0;
    Rc = new LongLat();
    Ref = new LongLat();
    Rb = new LongLat();
    
    // Get form data
    GetData( Rc, "DegC", "MinC", "", "" );
    GetData( Ref, "DegEf", "MinEf", "", "" );
    Ihc = GetSingleData( "Ihc" );
    Vb = GetSingleData( "Vb" );
    alphaRc = Ang360( GetDegrees( Rc ) );    
    alphaRef = Ang360( GetDegrees( Ref ) ) ;
    
    // Vector coord for Ihc
    vIhc = new Pnt();
    vIhc.x = Ihc * Math.cos( alphaRc * Math.PI / 180 ); 
    vIhc.y = Ihc * Math.sin( alphaRc * Math.PI / 180 );     

    // C : x^2 + y^2 = r^2 (circle center is at the end of Ihc vector)
    // L : y = m x + b
    if ( Math.abs( alphaRef - 90 ) < 1E-6 || Math.abs( alphaRef - 270 ) < 1E-6 )
    {
        // vertical line
        x1 = -vIhc.x ;
        x2 = x1;
        aux = Vb * Vb - x1 * x1 ;
        if ( aux < 0 ) 
        {
            document.getElementById('ResultPane').style.display = 'none';    
            alert( "No se ha podido encontrar una solución" );
            return;
        }
        y1 = Math.sqrt( aux );
        y2 = -y1;
    }
    else
    {
        m = Math.tan( alphaRef * Math.PI / 180 ) ;
        b = (-vIhc.y) - m * (-vIhc.x) ;
        r = Vb;
        
        // y^2 + x^2 = r^2; (mx + b)^2 + x^2 ) = r^2;   (1+m^2)x^2  + 2mb x + b^2 - r^2 = 0
        aux = 4*m*m*b*b - 4*(b*b-r*r)*(1+m*m);
        if ( aux < 0 ) 
        {
            document.getElementById('ResultPane').style.display = 'none';            
            alert( "No se ha podido encontrar una solución" );
            return;
        }
        x1 = ( -2*m*b + Math.sqrt( aux ) )/ ( 2 * ( 1+m*m ) ) ;
        y1 = m*x1 + b;
        x2 = ( -2*m*b - Math.sqrt( aux ) )/ ( 2 * ( 1+m*m ) ) ;
        y2 = m*x2 + b;
    }
    // Move back to the origin (not the cicle center)
    x1 = x1 + vIhc.x;
    x2 = x2 + vIhc.x;    
    y1 = y1 + vIhc.y;
    y2 = y2 + vIhc.y;    

     //Calculate the valid point (the one on the side of Ref, -> dot product positive)
    xAux = Math.cos( alphaRef * Math.PI / 180 ) ;
    yAux = Math.sin( alphaRef * Math.PI / 180 ) ;
    
    pntSolution = new Pnt(); 
    if( xAux * x1 + yAux * y1 > 0 )
    {
        pntSolution.x = x1 ;
        pntSolution.y = y1 ;        
    }
    else
    {
        pntSolution.x = x2 ;
        pntSolution.y = y2 ;        
    }
    
    Vef = Math.sqrt( pntSolution.y * pntSolution.y + pntSolution.x * pntSolution.x );    
    alphaRb = Ang360( Math.atan2( pntSolution.y - vIhc.y, pntSolution.x - vIhc.x ) * 180 / Math.PI );
    SetDMS( alphaRb, Rb );
    // The following line is to round the result so it can be displayed correctly later
    SetDMS( Rb.degrees + Round( Rb.minutes + Rb.seconds / 60, 2 ) / 60, Rb ) ;         

    // Fill in form results
    document.getElementById('Vef').value = Round( Vef, 5 );
    document.getElementById('DegB').value = Rb.degrees;    
    document.getElementById('MinB').value = Round( Rb.minutes + Rb.seconds / 60, 2 )  ;   
    
    
    
    //Show text
    document.getElementById('ResultPane').style.display = 'block';    
    document.getElementById('ProcRbVb').style.display = 'none';
    document.getElementById('ProcRefVef').style.display = 'none';    
    document.getElementById('ProcRbVef').style.display = 'block';        
    


    // Create graphics    
    // Get max min points
    pnt1 = new Pnt();
    pnt2 = new Pnt();
    pnt0 = new Pnt();
    pntRef = new Pnt();
    pntIntersec1Incr = new Pnt();
    pntIntersec2Incr = new Pnt();    
    pntResult = new Pnt();
    pntScreenSize = new Pnt();
    pntScreenOriginOffset = new Pnt();    
    pntModelWindowMin = new Pnt();
    pntModelWindowMax = new Pnt();
    
    pnt1.x = Ihc * Math.cos( ( GetDegrees( Rc ) + 90 ) * Math.PI / 180 ) ;
    pnt1.y = Ihc * Math.sin( ( GetDegrees( Rc ) + 90 ) * Math.PI / 180 ) ; 
    pnt2.x = Vef * Math.cos( ( GetDegrees( Ref ) + 90 ) * Math.PI / 180 ) ;
    pnt2.y = Vef * Math.sin( ( GetDegrees( Ref ) + 90 ) * Math.PI / 180 ) ; ;
    pntRef.x = Vef * 1.30 * Math.cos( ( GetDegrees( Ref ) + 90 ) * Math.PI / 180 ) ;
    pntRef.y = Vef * 1.30 * Math.sin( ( GetDegrees( Ref ) + 90 ) * Math.PI / 180 ) ; ;
    pntIntersec1Incr.x = Math.cos( ( GetDegrees( Rb ) ) * Math.PI / 180 ) ;
    pntIntersec1Incr.y = Math.sin( ( GetDegrees( Rb ) ) * Math.PI / 180 ) ; ;
    pntIntersec2Incr.x = Math.cos( ( GetDegrees( Rb ) + 180 ) * Math.PI / 180 ) ;
    pntIntersec2Incr.y = Math.sin( ( GetDegrees( Rb ) + 180 ) * Math.PI / 180 ) ; ;


    pntModelWindowMin.y = GetMin( pnt1.y, pnt2.y, pnt0.y );    
    pntModelWindowMin.x = GetMin( pnt1.x, pnt2.x, pnt0.x );        
    pntModelWindowMax.y = GetMax( pnt1.y, pnt2.y, pnt0.y );    
    pntModelWindowMax.x = GetMax( pnt1.x, pnt2.x, pnt0.x );
    pntScreenSize.x = parseFloat( document.getElementById('Graph').style.width ) - MARGIN * 2;
    pntScreenSize.y = parseFloat( document.getElementById('Graph').style.height ) - MARGIN * 2;    
    pntScreenOriginOffset.x = MARGIN;
    pntScreenOriginOffset.y = MARGIN;    
    GetScreenBottomLeft( pntResult, pntScreenSize, pntModelWindowMin, pntModelWindowMax )    

    
    // Call jsGraphics() with no parameters if drawing within the entire document
    var jg = new jsGraphics("Graph");    // Use the "Canvas" div for drawing
    jg.clear();
    jg.paint(); 
    jg.setFont( 'verdana,geneva,helvetica,sans-serif', "16px", Font.PLAIN)

    //jg.drawRect((pntModelWindowMin.x + pntResult.x )*pntResult.t,
    //            (pntModelWindowMin.y + pntResult.y )*pntResult.t,
    //            (pntModelWindowMax.x-pntModelWindowMin.x )*pntResult.t,
    //            (pntModelWindowMax.y-pntModelWindowMin.y )*pntResult.t);

    arrowLength = 20;
    arrowHeight = 5;
    
    // Draw axis and scale
    jg.setStroke(1);
    jg.setColor("black");
    pntAxis0 = new Pnt();
    pntAxis0.x = pntScreenOriginOffset.x + pntScreenSize.x - (pnt0.x + pntResult.x )*pntResult.t;
    pntAxis0.y = pntScreenOriginOffset.y + pntScreenSize.y - (pnt0.y + pntResult.y )*pntResult.t;
    DrawArrow( pntAxis0.x,  
               pntAxis0.y, 
               pntAxis0.x, 
               MARGIN , arrowLength, arrowHeight, jg );
    jg.drawString( "N", pntAxis0.x - 6, MARGIN - 20);
    //DrawScale( 0, pntScreenSize.y + 1.8 * MARGIN, pntResult.t, "1'", jg )
    DrawScale( 0, 10, pntResult.t, "1'", jg );    
    
    // Draw vectors
    jg.setStroke(2);
    jg.setColor("orange");
    DrawArrow( pntScreenOriginOffset.x + pntScreenSize.x - (pnt0.x + pntResult.x )*pntResult.t,  
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt0.y + pntResult.y )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.x - (pnt1.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt1.y + pntResult.y )*pntResult.t, arrowLength, arrowHeight, jg );  
                 jg.setColor("magenta");
    DrawArrow( pntScreenOriginOffset.x + pntScreenSize.x - (pnt0.x + pntResult.x )*pntResult.t,  
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt0.y + pntResult.y )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.x - (pnt2.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt2.y + pntResult.y )*pntResult.t, arrowLength, arrowHeight, jg );
    // Draw Ref line
    jg.setStroke(this.DOTTED);
    jg.drawLine( pntScreenOriginOffset.x + pntScreenSize.x - (pnt0.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.y - (pnt0.y + pntResult.y )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.x - (pntRef.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.y - (pntRef.y + pntResult.y )*pntResult.t );  
                 jg.setStroke(2);
    jg.setColor("red");
    DrawArrow( pntScreenOriginOffset.x + pntScreenSize.x - (pnt1.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt1.y + pntResult.y )*pntResult.t, 
                 pntScreenOriginOffset.x + pntScreenSize.x - (pnt2.x + pntResult.x )*pntResult.t, 
                 pntScreenOriginOffset.y + pntScreenSize.y - (pnt2.y + pntResult.y )*pntResult.t, arrowLength, arrowHeight, jg );
    // Draw arc intersection
    jg.setColor("blue");    
    jg.drawLine( pntScreenOriginOffset.x + pntScreenSize.x - (pnt2.x + pntResult.x )*pntResult.t + pntIntersec1Incr.x * 15, 
                 pntScreenOriginOffset.x + pntScreenSize.y - (pnt2.y + pntResult.y )*pntResult.t + pntIntersec1Incr.y * 15, 
                 pntScreenOriginOffset.x + pntScreenSize.x - (pnt2.x + pntResult.x )*pntResult.t + pntIntersec2Incr.x * 15, 
                 pntScreenOriginOffset.x + pntScreenSize.y - (pnt2.y + pntResult.y )*pntResult.t + pntIntersec2Incr.y * 15 );
    
    
    jg.paint(); 
    
}