<?

// Set encoding and timezone
header("Content-type: text/plain");
date_default_timezone_set("America/Detroit");

// Print table header
printf("%6s %8s %8s %-60s %s\n", "", "Depart", "Arive", "", "Price");

// Display all routes from now to 53 days in the future
for($days = 1; $days < 53 + 2; $days++)
{
  display_schedule(get_bus_schedule("23", "9", strtotime("1 AM +$days days")));
}

// Display ASCII table of bus schedules
function display_schedule($schedules)
{
  $count = 1;
  foreach($schedules as $journey_id => $schedule)
  {
    printf("%6s %8s %8s %-60s %s\n",
      ($count == 1 ? date("M d", $schedule["depart"]) : ""),
      date("g:i A", $schedule["depart"]),
      date("g:i A", $schedule["arrive"]),
      str_repeat("$", $schedule["price"]),
      money_format("$%i", $schedule["price"]));
    $count++;
  }
}

// Retrieve a bus schedule on a certain day
function get_bus_schedule($origin, $dest, $date)
{
  $response = do_post_request(
    "http://www.megabus.com/us/index.php",
    array(
      "pax_standard" => "1",
      "promoCode" => "",
      "origin" => $origin,
      "dest" => $dest,
      "depart" => $date,
      "return" => "-1",
      "show_routes" => "1",
    ));
  preg_match_all("/outwardJourneyID\" value=\"([0-9]*)\" \/>.*\n" .
    ".*<span class=\"small_bold_blue\">([^<]*)<\/span>.*Depart (.*) ?<br \/>.*\n".
    ".*Arrive (.*) ?&nbsp;.*small_bold_blue\">([^<]*).*\n".
    ".*small_bold_blue\">([0-9]*) .* = \\$([0-9.]*)/", $response, $matches, PREG_SET_ORDER);
  foreach($matches as $match)
  {
    $schedules[$match[1]] = array(
      "depart" => strtotime($match[2], $date),
      "origin" => $match[3],
      "arrive" => strtotime($match[5], $date),
      "dest" => $match[4],
      "seats" => $match[6],
      "price" => $match[7] / $match[6]);
  }
  return $schedules;
}

// I didn't write this, I found it here: http://netevil.org/blog/2006/nov/http-post-from-php-without-curl
function do_post_request($url, $data, $optional_headers = null)
{
  $params = array("http" => array(
    "method" => "POST",
    "content" => http_build_query($data)));
  if ($optional_headers !== null)
    $params["http"]["header"] = $optional_headers;
  $ctx = stream_context_create($params);
  $fp = @fopen($url, "rb", false, $ctx);
  if (!$fp)
    throw new Exception("Problem with $url, $php_errormsg");
  $response = @stream_get_contents($fp);
  if ($response === false)
    throw new Exception("Problem reading data from $url, $php_errormsg");
  return $response;
}

?>