
// This javascript file is part of www.chooseclimate.org/flying
// The copyright of this script belongs to Ben Matthews
// First created in 1999, updated 2007 (for modern browsers)
// Contact: ben AT chooseclimate.org


//global variables 
var setfrom=true 
var atx=0;var aty=0 
var fx=0; var fy=0;var tx=0;var ty=0 
var wedge=169; var nedge=-84; var sedge=76 
//north south and west limits of map (degrees), note south and west are postitive. Assume east edge=west edge! 
var distance=0 ;var fuelperpass=0 
var dxr=0; var fyr=0; var tyr=0; var theta=0 
var imginfo=""; var clikinfo=""; var newdots=0; var totdots=100; var chinfo="";


//*********************** referencing shortcuts ***********    
function get(id) { return document.getElementById(id) }

//******************* handle clicks etc ****************


//functions xp and yp convert event x / y into lat / long
function xp(event) { 
    x=(360*(event.clientX-(2+get("worldmap").offsetLeft-document.body.scrollLeft))/get("worldmap").width)-wedge 
    if (x>180) x-=360 
    if (x<-180) x+=360 
    return x
}

function yp(event) {
    y=(((event.clientY-(get("worldmap").offsetTop-document.body.scrollTop))/300)*(sedge-nedge))+nedge 
    return y
}

function movemouse(event) {
    get("longitude").value=longname(xp(event)," ")
    get("latitude").value=latname(yp(event)," ")
}

function leavemap() {
    get("longitude").value=""
    get("latitude").value="" 
}

function clickmap(event) {
    if (setfrom) {
        fx = xp(event) ; fy = yp(event);
        move("star1", event)
        get("fromlong").value =longname(fx," ")
        get("fromlat").value =latname(fy," ")
    }
    else {
        tx = xp(event) ; ty = yp(event) ;
        move("star2", event)
        get("tolong").value=longname(tx," ")
        get("tolat").value=latname(ty," ")
    }
    setfrom =!setfrom
    if (tx!=0) {
        distance=calcdist()
        get("greatcircle").value=distance
        fuel()
        flight()
    }
} 

function move(item, event) {
    item=get(item);
    item.style.visibility="hidden";
    item.style.left =event.clientX -12
    item.style.top =event.clientY-12 + document.body.scrollTop
    item.style.visibility="visible";
}

//**************** draw flight path ************

function flight() {
    
    for (nd=0;nd<totdots;nd+=1) {  get("dot"+nd).style.visibility="hidden"   }
    
    if (dxr!=0) usefulangle=Math.atan((Math.cos(dxr)-(Math.cos(tyr)/Math.cos(fyr)))/Math.sin(dxr)); 
    else usefulangle=0
    
    direction=(fx-tx)/Math.abs(fx-tx)
    if (Math.abs(tx-fx)>180) {
        direction=-direction
        if (fx>tx) {
            usefulangle=-usefulangle
        }
    }
    oldangle=usefulangle
    
    wmwidth=get("worldmap").width
    wmheight=get("worldmap").height
    
    howmanydots=Math.floor(theta*totdots/Math.PI)-1 
    for (nd=-1; nd<howmanydots; nd+=1) {
        deltatheta=Math.PI*nd/totdots
        
        fractop=Math.sin(tyr)*(Math.sin(deltatheta)-2*Math.cos((theta/2)-deltatheta)*Math.sin(theta/2))-Math.sin(fyr)*Math.sin(deltatheta)
        movinglatitude=Math.asin(-fractop/Math.sin(theta))
        frac2=(Math.cos(tyr)*Math.cos(usefulangle)/(Math.cos(movinglatitude)*(Math.cos(deltatheta)-Math.tan((theta/2)-deltatheta)*Math.sin(deltatheta))))
        anotherangle=Math.acos(frac2)
        
        if (dxr!=0) {
            longsign=direction*(Math.abs(anotherangle-oldangle)/(anotherangle-oldangle))
            oldangle=anotherangle
            deltalongitude=((longsign*anotherangle)-usefulangle)
        }
        else deltalongitude=0
        
        if (nd>=0) { //skip first dot  to set the oldangle correctly
            
            dotx=(wedge+tx+(deltalongitude*180/Math.PI))*(wmwidth/360)
            if (dotx>wmwidth) dotx-=wmwidth 
            if (dotx<0) dotx+=wmwidth 
            
            doty=((movinglatitude*180/Math.PI)-nedge)*(wmheight/(sedge-nedge))
            
            dot=get("dot"+nd);
            dot.style.left=dotx+get("worldmap").offsetLeft -2
            dot.style.top=doty+get("worldmap").offsetTop-2
            dot.style.visibility="visible"
        }
        
    }//end of nd loop
} //end of flight function




//**************** write lat / long as text ************

function longname(xpl, gap) {  
    abslong=Math.abs(xpl)  
    degrees=Math.floor(abslong); minutes=Math.round((abslong-degrees)*60)  
    if (degrees<100) degrees=" "+gap+degrees; if (degrees<10) degrees=" "+gap+degrees  
    if (minutes<10) minutes=" "+gap+minutes  
    longstring=degrees+"°"+gap+minutes+"'"  
    if (xpl<0) longstring=longstring+gap+"W" ;else longstring=longstring+gap+"E"  
    return longstring 
}

function latname(ypl, gap) {  
    abslat=Math.abs(ypl)  
    degrees=Math.floor(abslat); minutes=Math.round((abslat-degrees)*60)  
    if (degrees<10) degrees=" "+gap+degrees  
    if (minutes<10) minutes=" "+gap+minutes  
    latstring=degrees+"°"+gap+minutes+"'"  
    if (ypl<0) latstring=latstring+gap+"N" ;else latstring=latstring+gap+"S"  
    return latstring  
}

//****************** great circle  distance ********************

function calcdist() {
    radius=6370 //radius of earth in km (between equatorial and polar values) 
    dxr=(fx-tx)*Math.PI/180
    if (dxr>Math.PI) dxr=(2*Math.PI)-dxr
    fyr=fy*Math.PI/180 ; tyr=ty*Math.PI/180
    
    costheta=(Math.cos(fyr)*Math.cos(tyr)*Math.cos(dxr))+(Math.sin(fyr)*Math.sin(tyr))
    theta=Math.acos(costheta)
    return Math.round(radius*theta) 
} 


//********************* fuel use *********************
function fuel() {
    distance=get("greatcircle").value
    cruisedist=distance-250
    cruisefuel=cruisedist*10.1
    takeofflandfuel=7840
    busfac=get("seattype").options[get("seattype").selectedIndex].value
    passengers=370*(get("occupancy").value/100)*busfac
    singretfac=get("singret").options[get("singret").selectedIndex].value
    fuelperpass=(cruisefuel+takeofflandfuel)*singretfac/passengers
    get("fuel").value=Math.round(fuelperpass)
    co2perpass=fuelperpass*(44/12)*(156/184)
    gwiperpass=3*co2perpass
    get("co2only").value=Math.round(co2perpass)
    get("gwi").value=Math.round(gwiperpass)
    calchm()
    context()
}

function changeit() {
    fuel()
}


//****************** calc howmuch carbon *************************
function calchm(){
    get("fuelkilo").value=Math.round(fuelperpass)
    //assume kerosene=c13h28 weight=184 
    moles=(fuelperpass/184)*1000
    molesc=moles*13
    aircolm2=molesc/((365/1000000)*(101325/9.8)*(1000/29))
    get("aircol").value=Math.round(aircolm2)
    get("bodyweight").value=Math.round(10*fuelperpass/68)/10
    get("fvol").value=Math.round(fuelperpass/0.756)
    energykwh=8750*moles/3600
    get("energy").value=Math.round(energykwh)
    get("bulbs").value=Math.round(energykwh/518.4)
    get("food").value=Math.round(8750*moles/3650000)
    get("petrol").value=Math.round(0.571*fuelperpass/0.756)
    get("treeheight").value=Math.round(Math.pow((6*fuelperpass/0.756),0.3333))
}

function context(){
    tonc=fuelperpass*(96/114)/1000
    yearbudg=tonc/0.4 
    get("tonc").value=(Math.round(tonc*100)/100)
    get("yearbudg").value=(Math.round(yearbudg*100)/100)
}

//*************  checkold **********
function checkold() {
 if (document.layers || !(document.getElementById)) document.write("This script cannot function, because you have a very old web browser that does not support modern HTML DOM standards. Please use a modern browser such as Firefox, IE7, Safari, Konqueror etc. ")    
}

// **********************************************
