function Round( v, precision )
{
    precision = Math.pow(10,precision);
    return Math.round( v * precision ) / precision;
}

function Ang360( v )
{
    while( v > 360 )
        v = v - 360;
    while( v < 0 )
        v = v + 360;  
    return v;
}

function LongLat()
{
    this.sign = 1.0;
    this.degrees=0.0;
    this.minutes=0.0;
    this.seconds=0.0;
    this.cardinalPositive="";
    this.cardinalNegative="";    
}

function LongitudeCoord()
{
    c = new LongLat();
    c.cardinalPositive="E";
    c.cardinalNegative="W";        
    return c;
}

function LatitudeCoord()
{
    c = new LongLat();
    c.cardinalPositive="N";
    c.cardinalNegative="S";        
    return c;
}

function TimeCoord()
{
    c = new LongLat();
    c.cardinalPositive="HcL";
    c.cardinalNegative="Hz";        
    return c;
}

function DMSPoint()
{
    this.longitude = new LongitudeCoord();
    this.latitude = new LatitudeCoord();    
}

function GetMinutes( dms )
{
    return dms.sign * ( dms.degrees * 60 + dms.minutes + dms.seconds / 60 );
}

function GetDegrees( dms )
{
    return dms.sign * ( dms.degrees + dms.minutes / 60 + dms.seconds / 3600 );
}

function RoundDMS( dms, prec ) 
{    
    d = Round( dms.degrees, prec ) ;
    m = Round( dms.minutes, prec ) ;
    s = Round( dms.seconds, prec );

    while ( s >= 60 ) 
    {
        m = m + 1;
        s = s - 60;
    }
    while ( m >= 60 ) 
    {
        d = d + 1;
        m = m - 60;
    }

    dmsRet = dms;
    dmsRet.degrees = d ;
    dmsRet.minutes = m ;
    dmsRet.seconds = s ;
    return dmsRet;    
}

function SetDMS( degrees, dms ) 
{
    if ( degrees > 0 ) 
        dms.sign = 1;
    else
        dms.sign = -1;

    while( degrees >= 360 )
        degrees = degrees - 360;
    while( degrees <= -360 )
        degrees = degrees + 360;

    degrees = Math.abs(degrees)    ;
    dms.degrees = Math.floor( degrees );
    rest = ( degrees - dms.degrees ) * 60 ;
    dms.minutes = Math.floor( rest );
    dms.seconds = ( rest - dms.minutes ) * 60 ;
}

function SetQuadrantCourse( degrees, dms ) 
{
    while( degrees >= 360 )
        degrees = degrees - 360;
    while( degrees < 0 )
        degrees = degrees + 360;

    degreesAux = Round( degrees, 3 )
    
    dms.cardinalPositive = 0;
    dms.cardinalNegative = 0;
    
    if ( degreesAux == 0 || degreesAux == 360 )
    {
        SetDMS( 0, dms );
        dms.cardinalNegative = "";
        dms.cardinalPositive = "N";
    }
    else if ( degreesAux == 45 )
    {
        SetDMS( 0, dms );
        dms.cardinalPositive = "N";
        dms.cardinalNegative = "E";
    }
    else if ( degreesAux == 90 )
    {
        SetDMS( 0, dms );
        dms.cardinalPositive = "";
        dms.cardinalNegative = "E";
    }
    else if ( degreesAux == 135 )
    {
        SetDMS( 0, dms );
        dms.cardinalPositive = "S";
        dms.cardinalNegative = "E";
    }
    else if ( degreesAux == 180 )
    {
        SetDMS( 0, dms );
        dms.cardinalNegative = "";
        dms.cardinalPositive = "S";
    }
    else if ( degreesAux == 225 )
    {
        SetDMS( 0, dms );
        dms.cardinalNegative = "S";
        dms.cardinalPositive = "W";
    }
    else if ( degreesAux == 270 )
    {
        SetDMS( 0, dms );
        dms.cardinalPositive = "";
        dms.cardinalNegative = "W";    
    }
    else if ( degreesAux == 315 )
    {
        SetDMS( 0, dms );
        dms.cardinalPositive = "N";
        dms.cardinalNegative = "W";    
    }
    else if ( degrees > 0 && degrees < 90 )
    {
        SetDMS( degrees, dms );    
        dms.cardinalPositive = "N";    
        dms.cardinalNegative = "E";            
    }
    else if ( degrees > 90 && degrees < 180 )
    {
        SetDMS( 180 - degrees, dms );    
        dms.cardinalPositive = "S";    
        dms.cardinalNegative = "E";            
    }
    else if ( degrees > 180 && degrees < 270 )
    {
        SetDMS( degrees - 180, dms );    
        dms.cardinalPositive = "S";    
        dms.cardinalNegative = "W";                
    }
    else if ( degrees > 270 && degrees < 360 )
    {
        SetDMS( 360 - degrees, dms );    
        dms.cardinalPositive = "N";    
        dms.cardinalNegative = "W";                
    }
}

function GetQuadrantCourseString( dms ) 
{
    if( dms.degrees == 0 && dms.minutes == 0 && dms.seconds == 0 ) 
        sRet =  dms.cardinalPositive + dms.cardinalNegative ;
    else
        sRet =  dms.cardinalPositive + dms.degrees + "&deg;" + Round( dms.minutes + dms.seconds / 60, 3 ) + "'" + dms.cardinalNegative ;

    return sRet ;    
}

function GetDMString( dms ) 
{
    sRet = "";

    d = dms.degrees ;
    ms = Round( ( dms.minutes + dms.seconds / 60 ), 3 );
    while ( ms >= 60 ) 
    {
        d = d + 1;
        ms = ms - 60;
    }
    
    sRet =  d + "&deg;" + ms + "'";    

    if ( dms.cardinalPositive != "" && dms.cardinalNegative != "" ) 
    {
        if ( dms.sign > 0 ) 
            sRet = sRet + dms.cardinalPositive;
        else
            sRet = sRet + dms.cardinalNegative;
    }
    else if ( dms.sign < 0 )
        sRet = "&ndash;" + sRet ;

    return sRet;
}

function GetDMSString( dms ) 
{
    sRet = "";

    dmsNew = RoundDMS( dms, 3 );
    d = dmsNew.degrees;
    m = dmsNew.minutes;
    s = dmsNew.seconds;

    sRet = d + "&deg;" + m + "'" + s + "\"" ;    
    
    if ( dms.cardinalPositive != "" && dms.cardinalNegative != "" ) 
    {
        if ( dms.sign > 0 ) 
            sRet = sRet + dms.cardinalPositive;
        else
            sRet = sRet + dms.cardinalNegative;
    }
    else if ( dms.sign < 0 )
        sRet = "&ndash;" + sRet ;

    return sRet;
}

function GetHMString( dms ) 
{
    sRet = "";

    d = dms.degrees ;
    ms = Round( ( dms.minutes + dms.seconds / 60 ), 3 );
    while ( ms >= 60 ) 
    {
        d = d + 1;
        ms = ms - 60;
    }
    
    sRet =  d + "h" ;
    if( ms < 10 ) 
        sRet = sRet + "0" + ms + "'";    
    else
        sRet = sRet + ms + "'";            

    if ( dms.sign < 0 )
        sRet = "&ndash;" + sRet ;

    return sRet;
}

function GetHMSString( dms ) 
{
    sRet = "";

    dmsNew = RoundDMS( dms, 3 );
    d = dmsNew.degrees;
    m = dmsNew.minutes;
    s = dmsNew.seconds;

    sRet = d + "h" + m + "'" + s + "\"" ;    

    if ( dms.sign < 0 )
        sRet = "&ndash;" + sRet ;
    
    return sRet;
}

function GetData( dms, sDegId, sMinId, sSecId, sNegativeCardinalId ) 
{
    var sign=1, d = 0, m = 0, s = 0, c = ""
    d = GetSingleData( sDegId ) ;
    if( d < 0 ) 
    {
        d = -d;
        sign = -1;
    }
    m = GetSingleData( sMinId ) ;
    s = GetSingleData( sSecId ) ;
    if ( sNegativeCardinalId != "" )
    {
        if( document.getElementById(sNegativeCardinalId).checked )
        {
            sign = -sign;
        }
    }
    if ( Math.round( d ) != d || Math.round( m ) != m || Math.round( s ) != s || sign == -1 ) 
    {
        SetDMS( sign * ( d + m / 60 + s / 3600 ), dms );
        dms.seconds = Round( dms.seconds, 6 ) ;
    }
    else
    {
        dms.degrees = d;
        dms.minutes = m;
        dms.seconds = s;
        dms.sign = sign;        
    }
}

function SetData( dms, sDegId, sMinId, sSecId, sNegativeCardinalId, sPositiveCardinalId ) 
{
    dmsNew = RoundDMS( dms, 3 );
    SetSingleData( sDegId, dmsNew.degrees );
    SetSingleData( sMinId, dmsNew.minutes );
    SetSingleData( sSecId, dmsNew.seconds );
    if ( sNegativeCardinalId != "" )
    {
        document.getElementById( sNegativeCardinalId ).checked = ( dmsNew.sign < 0 ) ;
    }
    if ( sPositiveCardinalId != "" )
    {
        document.getElementById( sPositiveCardinalId ).checked = ( dmsNew.sign > 0 ) ;
    }    
}

function GetSingleData( sId ) 
{
    var v = 0.0;
    if ( sId != "" )
    {
        s = document.getElementById( sId ).value;
        if( s != "" )
            v = parseFloat( s );
    }
    return v;
}

function SetSingleData( sId, sValue ) 
{
    if ( sId != "" )
    {
        document.getElementById( sId ).value = sValue;
    }
}