<?php

  
# vim: wm=0:tw=0:ai:sw=2:fdm=marker
  # $Id: wb.php,v 0.60 2017/04/02 20:50:06 davidtg Exp $

  
$planes = array    ## {{{
  
(
    
'default' => 'N339BC',
    
'N339BC' => array    ## {{{
      
(
        
'nick' => 'Kitty',
        
'empty' => array('w'=>756.4,'m'=>16.47,'n'=>''),
        
'fuel' => array('w'=>144,'m'=>36.81,'n'=>''),
        
'FL' => array('w'=>200,'m'=>19.88,'n'=>''),
        
'FR' => array('w'=>175,'m'=>19.88,'n'=>''),
        
'BL' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        
'BR' => array('w'=>0,'m'=>0,'n'=>''),
        
'baggage' => array('w'=>0,'m'=>63,'n'=>'max 70'),
        
'hat' => array('w'=>10,'m'=>42.32,'n'=>'N/A'),
        
'normal' => array('gross'=>1320,'min'=>15,'max'=>30.5),
        
'utility' => array('gross'=>1320,'min'=>10,'max'=>21),
      ),    
## }}}    /* */
    
'N339BCx' => array    ## {{{
      
(
        
'nick' => 'Kitty (experimental)',
        
'empty' => array('w'=>756.5,'m'=>16.47,'n'=>''),
        
'fuel' => array('w'=>192,'m'=>36.81,'n'=>''),
        
'FL' => array('w'=>200,'m'=>19.88,'n'=>''),
        
'FR' => array('w'=>175,'m'=>19.88,'n'=>''),
        
'BL' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        
'BR' => array('w'=>0,'m'=>0,'n'=>''),
        
'baggage' => array('w'=>0,'m'=>63,'n'=>'max 70'),
        
'hat' => array('w'=>10,'m'=>42.32,'n'=>'N/A'),
        
'normal' => array('gross'=>1800,'min'=>15,'max'=>30.5),
        
'utility' => array('gross'=>1320,'min'=>10,'max'=>21),
      ),    
## }}}    /* */
    /* 'NC31845' => array    ## {{{
      (
        'nick' => 'Happy',
        'empty' => array('w'=>765.5,'m'=>18.3,'n'=>''),
        'fuel' => array('w'=>96,'m'=>-8,'n'=>''),
        'FL' => array('w'=>200,'m'=>21,'n'=>''),
        'FR' => array('w'=>175,'m'=>21,'n'=>''),
        'BL' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        'BR' => array('w'=>0,'m'=>0,'n'=>''),
        'baggage' => array('w'=>10,'m'=>48,'n'=>'max 70'),
        'hat' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        'normal' => array('gross'=>1250,'min'=>15.1,'max'=>21.2),
        'utility' => array('gross'=>1250,'min'=>13.9,'max'=>21.2),
      ),    ## }}}    /* */
    /* 'N12556' => array    ## {{{
      (
        'nick' => 'Penny',
        'empty' => array('w'=>1449.9,'m'=>38.31,'n'=>''),
        'fuel' => array('w'=>192,'m'=>47.81,'n'=>''),
        'FL' => array('w'=>165,'m'=>37,'n'=>''),
        'FR' => array('w'=>190,'m'=>37,'n'=>''),
        'BL' => array('w'=>165,'m'=>73,'n'=>''),
        'BR' => array('w'=>150,'m'=>73,'n'=>''),
        'baggage' => array('w'=>0,'m'=>95,'n'=>'B+H <= 125'),
        'hat' => array('w'=>10,'m'=>123,'n'=>'<= 50'),
        'normal' => array('gross'=>2300,'min'=>38.5,'max'=>47.3),
        'utility' => array('gross'=>1950,'min'=>35.0,'max'=>47.3),
      ),    ## }}}    /* */
    /* 'N37148' => array    ## {{{
      (
        'nick' => 'BlueBird',
        'empty' => array('w'=>1085,'m'=>86.65,'n'=>''),
        'fuel' => array('w'=>176,'m'=>81.5,'n'=>''),
        'FL' => array('w'=>200,'m'=>92,'n'=>''),
        'FR' => array('w'=>200,'m'=>92,'n'=>''),
        'BL' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        'BR' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        'baggage' => array('w'=>10,'m'=>119,'n'=>''),
        'hat' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        'normal' => array('gross'=>1675,'min'=>85.8,'max'=>88.9),
        'utility' => array('gross'=>1675,'min'=>85.8,'max'=>88.9),
      ),    ## }}}    /* */
    /* 'N37148a' => array    ## {{{
      (
        'nick' => 'BlueBird (actual)',
        'empty' => array('w'=>1207,'m'=>86.65,'n'=>''),
        'fuel' => array('w'=>176,'m'=>81.5,'n'=>''),
        'FL' => array('w'=>200,'m'=>92,'n'=>''),
        'FR' => array('w'=>200,'m'=>92,'n'=>''),
        'BL' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        'BR' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        'baggage' => array('w'=>10,'m'=>119,'n'=>''),
        'hat' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        'normal' => array('gross'=>1675,'min'=>85.8,'max'=>88.9),
        'utility' => array('gross'=>1675,'min'=>85.8,'max'=>88.9),
      ),    ## }}}    /* */
    /* 'N7282G' => array    ## {{{
      (
        'nick' => '',
        'empty' => array('w'=>1413,'m'=>36.7,'n'=>''),
        'fuel' => array('w'=>228,'m'=>47.8,'n'=>''),
        'FL' => array('w'=>165,'m'=>35.9,'n'=>''),
        'FR' => array('w'=>190,'m'=>35.9,'n'=>''),
        'BL' => array('w'=>120,'m'=>70,'n'=>''),
        'BR' => array('w'=>65,'m'=>70,'n'=>''),
        'baggage' => array('w'=>0,'m'=>94.4,'n'=>'B+H <= 125'),
        'hat' => array('w'=>10,'m'=>123,'n'=>'<= 50'),
        'normal' => array('gross'=>2300,'min'=>35.0,'max'=>40.3),
        'utility' => array('gross'=>1950,'min'=>35.0,'max'=>40.3),
      ),    ## }}}    /* */
    /* 'N12468' => array    ## {{{
      (
        'nick' => '',
        'empty' => array('w'=>1524,'m'=>40.36,'n'=>''),
        'fuel' => array('w'=>228,'m'=>47.81,'n'=>''),
        'FL' => array('w'=>165,'m'=>37,'n'=>''),
        'FR' => array('w'=>190,'m'=>37,'n'=>''),
        'BL' => array('w'=>120,'m'=>73,'n'=>''),
        'BR' => array('w'=>65,'m'=>73,'n'=>''),
        'baggage' => array('w'=>0,'m'=>95,'n'=>'B+H <= 125'),
        'hat' => array('w'=>10,'m'=>123,'n'=>'<= 50'),
        'normal' => array('gross'=>2550,'min'=>41.0,'max'=>47.3),
        'utility' => array('gross'=>1950,'min'=>35.0,'max'=>47.3),
      ),    ## }}}    /* */
    /* 'N711DM' => array    ## {{{
      (
        'nick' => 'DeltaDawn',
        'empty' => array('w'=>1517.48,'m'=>109.39,'n'=>''),
        'fuel' => array('w'=>312,'m'=>117,'n'=>''),
        'FL' => array('w'=>165,'m'=>112,'n'=>''),
        'FR' => array('w'=>190,'m'=>112,'n'=>''),
        'BL' => array('w'=>120,'m'=>142,'n'=>''),
        'BR' => array('w'=>65,'m'=>142,'n'=>''),
        'baggage' => array('w'=>0,'m'=>167,'n'=>''),
        'hat' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        'normal' => array('gross'=>2450,'min'=>114.5,'max'=>118.3),
        'utility' => array('gross'=>2030,'min'=>114.5,'max'=>118.3),
      ),    ## }}}    /* */
    /* 'N4015T' => array    ## {{{
      (
        'nick' => '',
        'empty' => array('w'=>1472.9,'m'=>100,'n'=>''),
        'fuel' => array('w'=>312,'m'=>117,'n'=>''),
        'FL' => array('w'=>165,'m'=>110,'n'=>''),
        'FR' => array('w'=>190,'m'=>110,'n'=>''),
        'BL' => array('w'=>120,'m'=>142,'n'=>''),
        'BR' => array('w'=>65,'m'=>142,'n'=>''),
        'baggage' => array('w'=>0,'m'=>167,'n'=>''),
        'hat' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        'normal' => array('gross'=>2450,'min'=>114.5,'max'=>118.3),
        'utility' => array('gross'=>2030,'min'=>114.5,'max'=>118.3),
      ),    ## }}}    /* */
    
'N7874x' => array    # Keena Pope    ## {{{
      
(
        
'nick' => 'Snoopy',
        
'empty' => array('w'=>1449.9,'m'=>38.31,'n'=>'m=38.31'),
        
'fuel' => array('w'=>228,'m'=>48.00,'n'=>'m=48.00'),
        
'FL' => array('w'=>165,'m'=>36,'n'=>'m=36'),
        
'FR' => array('w'=>190,'m'=>36,'n'=>''),
        
'BL' => array('w'=>0,'m'=>70,'n'=>'m=70'),
        
'BR' => array('w'=>0,'m'=>70,'n'=>''),
        
'baggage' => array('w'=>0,'m'=>95,'n'=>'B+H<= 120'),
        
'hat' => array('w'=>10,'m'=>123,'n'=>''),
        
'normal' => array('gross'=>2200,'min'=>40.4,'max'=>46.4),
        
'utility' => array('gross'=>1950,'min'=>37.4,'max'=>40.3),
      ),    
## }}}    /* */
    /* 'N172DP' => array    # Airwolf    ## {{{
      (
        'nick' => 'Airwolf 172RG',
        'empty' => array('w'=>1700.7,'m'=>40.14,'n'=>''),
        'fuel' => array('w'=>264,'m'=>48,'n'=>'max 62g'),
        'FL' => array('w'=>165,'m'=>37,'n'=>''),
        'FR' => array('w'=>155,'m'=>37,'n'=>''),
        'BL' => array('w'=>0,'m'=>73,'n'=>''),
        'BR' => array('w'=>0,'m'=>73,'n'=>''),
        'baggage' => array('w'=>0,'m'=>95,'n'=>'<=200'),
        'hat' => array('w'=>0,'m'=>115,'n'=>'<=50'),
        'normal' => array('gross'=>2650,'min'=>39.5,'max'=>46.5),
        'utility' => array('gross'=>1960,'min'=>36,'max'=>46.5),
      ),    ## }}}    /* */
    
'N2629Z' => array    ## {{{
      
(
        
'nick' => 'Skycatcher-PDK',
        
'empty' => array('w'=>858,'m'=>131,'n'=>''),
        
'fuel' => array('w'=>108,'m'=>143.3,'n'=>''),
        
'FL' => array('w'=>155,'m'=>142,'n'=>''),
        
'FR' => array('w'=>170,'m'=>142,'n'=>''),
        
'BL' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        
'BR' => array('w'=>0,'m'=>0,'n'=>'N/A'),
        
'baggage' => array('w'=>10,'m'=>155,'n'=>'(use for front)'),
        
'hat' => array('w'=>0,'m'=>190,'n'=>'(use for rear)'),
        
'normal' => array('gross'=>1320,'min'=>134.4,'max'=>136.8),
        
'utility' => array('gross'=>1050,'min'=>132.5,'max'=>136.8),
      ),    
## }}}
  
) ;    ## }}}

  
function printr($printme)                # standard pre/print_r/pre stuff    ## {{{
  
{
    print 
"<pre>\n" ;
    
print_r($printme) ;
    print 
"</pre>\n" ;
  } 
# printr    ## }}}

  
function stylesheet()    ## {{{
  
{
    
### there really should be a way to generate this instead of mostly duplicating it...
    
?>
    .wtheavy { color: red ; font-stye: bold ; }
    .wtok { color: green ; font-style: bold ; }
    @media screen    /* for regular display */
    {
      table tbody.scroll { overflow: auto ; height: 256px ; }
      table tbody.scroll tr { height: 1em }    /* IE bug workaround */
      .dirhr { width: 100% ; }
    }
    /* .hash .ie { text-align: center ; }    /* IE hack */
    /* .hash .ie { writing-mode: tb-rl ; filter: flipH() flipV() ; }    /* vertical text IE hack */
    .hash .c00 { background-color: #FFFFFF ; text-align: center ; vertical-align: top ; width: 3% ; }
    .hash .c01 { background-color: #CCFFFF ; text-align: center ; vertical-align: top ; width: 3% ; }
    .hash .c10 { background-color: #CCCCCC ; text-align: center ; vertical-align: top ; width: 3% ; }
    .hash .c11 { background-color: #88FFFF ; text-align: center ; vertical-align: top ; width: 3% ; }
    .hash .c02 { background-color: #FF8888 ; text-align: center ; vertical-align: top ; width: 3% ; }
    .hash .con { background-color: #88FF88 ; text-align: center ; vertical-align: top ; width: 3% ; }
    .hash .ced { background-color: #FFFF00 ; text-align: center ; vertical-align: top ; width: 3% ; }
    .break { page-break-after: always ; }
    .alldiv { border: thick brown solid ; height: 512px ; }
    .topdiv { border: thin red dashed ; height: 10% ; }
    .middiv { border: thin green dashed ; height: 89% ; }
    .mldiv { border: thin purple dotted ; width: 19% ; float: left ; overflow: auto ; height: 100% ; white-space: nowrap ; }
    .mmdiv { border: thin orange dotted ; width: 61% ; float: middle ; overflow: auto ; height: 100% ; }
    .mrdiv { border: thin blue dashed ; width: 19% ; float: right ; overflow: auto ; height: 100% ; white-space: nowrap ; }
    .highlink:hover { color: 000000 ; background-color : yellow ; }
    .nolink { text-decoration: none ; color: inherit ; }
    .label { font-size: small ; font-style: italic ; }
    .cols { column-count: 5 ; -moz-column-count: 5 ; column-gap: 5% ; -moz-column-gap: 5% ; }
    .dircols { border: none ; }
    .dirhead { width: 80% ; font-weight: bold ; border: solid ; }
    .box { border: thin solid ; }
    .bigger { font-size: 150% ; }
    .smaller { font-size: 84% ; }
    .dirwarn { color: red ; font-variant: small-caps ; }
    .dirname { font-size: small ; }
    .diraddr { font-size: small ; }
    .dirnum { font-size: small ; }
    .diremail { font-size: small ; }
    @media print    /* for diff settings on paper */
    {
      .topdiv { display: none ; }
      .mldiv { display: none ; }
      .mrdiv { display: none ; }
      .dirhr { display: none ; }
      .noprint { display: none ; }
    }
    <?php
  
}    ## }}}

  
function pickplane($planes)                # select a craft    ## {{{
  
{
    print 
"Pick your plane: \n" ;
    print 
"<select name='picker'>\n" ;
    foreach ( 
array_keys($planes) as $p )
    {
      if ( 
$p == 'default' )
        { continue ; }
      print 
"<option value='$p'" . ( $p == $planes['default'] ? ' selected' '' ) . ">$p. ( $planes[$p]['nick'] != '' " = {$planes[$p]['nick']}'' ) . "</option>\n" ;
    }
    print 
"</select>\n" ;
    print 
"<input type='submit' name='updates' value='Pick a plane'>\n" ;
  } 
# pickplane    ## }}}

  
function parseupdates($plane)                # parse our input updates    ## {{{
  
{
    foreach ( 
array_keys($_REQUEST['plane']) as $k )
    {
      foreach ( 
array_keys($_REQUEST['plane'][$k]) as $v )
      {
        
$plane[$k][$v] = $_REQUEST['plane'][$k][$v] ;
        if ( 
$k == 'fuel' )
          { 
$plane['fuel']['w'] = $plane['fuel']['g'] * ; }    # usually derived from weight
      
}
    }
    return(
$plane) ;
  } 
# parseupdates    ## }}}

  
function printform($plane)                # display the page for a given plane    ## {{{
  
{
    
# place settings    ## {{{
    
$m_empty round(($plane['empty']['w']*$plane['empty']['m']),0) ;
    
$m_fuel round(($plane['fuel']['w']*$plane['fuel']['m']),0) ;
    
$m_front round((($plane['FL']['w']+$plane['FR']['w'])*$plane['FL']['m']),0) ; $w_front $plane['FL']['w'] + $plane['FR']['w'] ;
    
$m_back round((($plane['BL']['w']+$plane['BR']['w'])*$plane['BL']['m']),0) ; $w_back $plane['BL']['w'] + $plane['BR']['w'] ;
    
$m_baggage round(($plane['baggage']['w']*$plane['baggage']['m']),0) ;
    
$m_hat round(($plane['hat']['w']*$plane['hat']['m']),0) ;
    
## }}}
    ## totals    ## {{{
    
$w_nofuel round($plane['empty']['w']+$plane['FL']['w']+$plane['FR']['w']+$plane['BL']['w']+$plane['BR']['w']+$plane['baggage']['w']+$plane['hat']['w'],0) ;
    
$m_nofuel $m_empty $m_front $m_back $m_baggage $m_hat ;
    
$g_nofuel round($m_nofuel/$w_nofuel,1) ;
    
$w_total $w_nofuel $plane['fuel']['w'] ; 
    
$m_total $m_empty $m_fuel $m_front $m_back $m_baggage $m_hat ;
    
$g_total round($m_total/$w_total,1) ;
    
$d_total $plane['normal']['gross'] - $w_total ;
    if ( 
$d_total )
      { 
$d_total "<span class='wtheavy'>$d_total</span>" ; }
    else
      { 
$d_total "<span class='wtok'>$d_total</span>" ; }
    
## }}}
    # table    ## {{{
    
print "<table border='1'>\n" ;
    print 
"<tr><th colspan='3'>INPUTS</th><th>Weight</th><th>Arm</th><th>Moment</th><th>notes</th></tr>\n" ;
    print 
"<tr><th>Empty (w/oil)</th><td></td><td></td><td>{$plane['empty']['w']}</td><td>{$plane['empty']['m']}</td><td>$m_empty</td><td>{$plane['empty']['n']}</td></tr>\n" ;
    print 
"<tr><th>Fuel(g)</th><td><input type='text' size='3' name='plane[fuel][g]' value='" round($plane['fuel']['w']/6) . "'></td><td></td><td>{$plane['fuel']['w']}</td><td>{$plane[fuel]['m']}</td><td>$m_fuel</td><td>{$plane['fuel']['n']}</td></tr>\n" ;
    print 
"<tr><th>Front</th><td><input type='text' size='3' name='plane[FL][w]' value='{$plane['FL']['w']}'></td><td><input type='text' size='3' name='plane[FR][w]' value='{$plane['FR']['w']}'></td><td>$w_front</td><td>{$plane[FR]['m']}</td><td>$m_front</td><td>{$plane['FL']['n']} {$plane['FR']['n']}</td></tr>\n" ;
    print 
"<tr><th>Rear</th><td><input type='text' size='3' name='plane[BL][w]' value='{$plane['BL']['w']}'></td><td><input type='text' size='3' name='plane[BR][w]' value='{$plane['BR']['w']}'></td><td>$w_back</td><td>{$plane[BR]['m']}</td><td>$m_back</td><td>{$plane['BL']['n']} {$plane['BR']['n']}</td></tr>\n" ;
    print 
"<tr><th>Baggage</th><td><input type='text' size='3' name='plane[baggage][w]' value='{$plane['baggage']['w']}'></td><td></td><td>{$plane['baggage']['w']}</td><td>{$plane[baggage]['m']}</td><td>$m_baggage</td><td>{$plane['baggage']['n']}</td></tr>\n" ;
    print 
"<tr><th>Hat Shelf</th><td><input type='text' size='3' name='plane[hat][w]' value='{$plane['hat']['w']}'></td><td></td><td>{$plane['hat']['w']}</td><td>{$plane[hat]['m']}</td><td>$m_hat</td><td>{$plane['hat']['n']}</td></tr>\n" ;
    print 
"<tr></tr>\n" ;
    print 
"<tr><th colspan='3'>Totals</th><td>$d_total</td><td></td><td>$m_total</td><td>(Max {$plane['normal']['gross']}{$plane['utility']['gross']}U)</td></tr>\n" ;
    print 
"<tr></tr>\n" ;
    print 
"<tr><td colspan='3'><input type='submit' name='updates' value='Recalculate'></td><th>Gross</th><th>CG</th><td></td><th>notes</th></tr>\n" ;
    print 
"<tr><th colspan='3'>Takeoff</th><td>$w_total</td><td>$g_total</td><td></td><td>&lt;={$plane['normal']['gross']} : {$plane['normal']['min']} - {$plane['normal']['max']}</td></tr>\n" ;
    print 
"<tr><th colspan='3'>Zero-Fuel</th><td>$w_nofuel</td><td>$g_nofuel</td><td></td><td>&lt;={$plane['utility']['gross']} : {$plane['utility']['min']} - {$plane['utility']['max']}</td></tr>\n" ;
    print 
"</table>\n" ;
    
## }}}
  
# printform    ## }}}

  
function getparams($params=array())            # get & calculate params/options info    ## {{{
  
{
    if ( 
file_exists('.htaccess') and preg_grep('@RewriteRule \^\(\.\*\\\/\)\?i\(\\\/\.\*\)\?\$@',file('.htaccess')) )    # RewriteRule ^(.*\/)?i(\/.*)?$    ## {{{
      
$params = array('i-mode' => 1) ; }        # use .htaccess to map http://.../i to this script?
    
else
      { 
$params = array('i-mode' => 0) ; }        # ... or not    ## }}}
    
$params['uriprefix'] = dirname($_SERVER['SCRIPT_NAME']) ;
    
$params['uriself'] = "{$params['uriprefix']}/" . ( @$params['i-mode'] == 'i' basename($_SERVER['SCRIPT_NAME']) ) ;
    
$params['urisuffix'] = str_replace($_SERVER['SCRIPT_NAME'],'',rtrim($_SERVER['PHP_SELF'],'/')) ;
    return 
$params ;
  } 
# getparams    ## }}}

  
$params getparams(array()) ;            # load up the params

  
if ( preg_match('@/css@',@$_SERVER['PATH_INFO']) )
    { 
stylesheet() ; exit ; }

  if ( 
preg_match('@/plane=([^/]*)@',@$_SERVER['PATH_INFO'],$matches) )    ## {{{
  
{
    foreach ( 
array_keys($planes) as $p )
    {
      if ( 
$p == 'default' )
        { continue ; }
      if ( 
strcasecmp($p,$matches[1]) == || strcasecmp($planes[$p]['nick'],$matches[1]) == )
        { 
$planes['default'] = $p ; }
    }
  } 
# match(/plane)    ## }}}

  
if ( @$_REQUEST['updates'] == 'Pick a plane' )
    { 
$planes['default'] = $_REQUEST['picker'] ; }

  if ( @
$_REQUEST['updates'] == 'Recalculate' )
  {
    
$planes['default'] = $_REQUEST['picker'] ;
    
$planes[$planes['default']] = parseupdates($planes[$planes['default']]) ;
  }

?>
<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN'>
<html>

  <head>    <!-- {{{ -->
    <meta http-equiv='content-type' content='text/html; charset=iso-8859-1'>
    <title>Weight & Balance Calculator</title>
    <style type='text/css'>
<?php stylesheet() # print "<link rel='stylesheet' type='text/css' href='" . $_SERVER['SCRIPT_NAME'] . "/css' />\n" ; ?>
    </style>
  </head>    <!-- }}} -->

  <body>    <!-- {{{ -->

    <center><h1>Weight & Balance Calculator</h1></center>

    <form method='post'>

<?php

  printform
($planes[$planes['default']]) ;

  
pickplane($planes) ;

?>

    </form>

  </body>    <!-- }}} -->

</html>