Add query to collate routes serviced at a stop
Add query to collate routes serviced at a stop

--- a/common.inc.php
+++ b/common.inc.php
@@ -4,7 +4,10 @@
 $cloudmadeAPIkey="daa03470bb8740298d4b10e3f03d63e6";
 $googleMapsAPIkey="ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q";
 $otpAPIurl = 'http://localhost:8080/opentripplanner-api-webapp/';
-if (isDebug()) error_reporting(E_ALL ^ E_NOTICE);
+$owaSiteID = 'fe5b819fa8c424a99ff0764d955d23f3';
+//$debugOkay = Array("session","json","phperror","other");
+$debugOkay = Array("session","json","phperror");
+if (isDebug("phperror")) error_reporting(E_ALL ^ E_NOTICE);
 
 // SELECT array_to_string(array(SELECT REPLACE(name_2006, ',', '\,') as name FROM suburbs order by name), ',')
 $suburbs = explode(",","Acton,Ainslie,Amaroo,Aranda,Banks,Barton,Belconnen,Bonner,Bonython,Braddon,Bruce,Calwell,Campbell,Chapman,Charnwood,Chifley,Chisholm,City,Conder,Cook,Curtin,Deakin,Dickson,Downer,Duffy,Dunlop,Evatt,Fadden,Farrer,Fisher,Florey,Flynn,Forrest,Franklin,Fraser,Fyshwick,Garran,Gilmore,Giralang,Gordon,Gowrie,Greenway,Griffith,Gungahlin,Hackett,Hall,Harrison,Hawker,Higgins,Holder,Holt,Hughes,Hume,Isaacs,Isabella Plains,Kaleen,Kambah,Kingston,Latham,Lawson,Lyneham,Lyons,Macarthur,Macgregor,Macquarie,Mawson,McKellar,Melba,Mitchell,Monash,Narrabundah,Ngunnawal,Nicholls,Oaks Estate,O'Connor,O'Malley,Oxley,Page,Palmerston,Parkes,Pearce,Phillip,Pialligo,Red Hill,Reid,Richardson,Rivett,Russell,Scullin,Spence,Stirling,Symonston,Tharwa,Theodore,Torrens,Turner,Wanniassa,Waramanga,Watson,Weetangera,Weston,Yarralumla");
@@ -18,34 +21,53 @@
    $_SESSION['time'] = filter_var($_REQUEST['time'],FILTER_SANITIZE_STRING);
  }
  if (isset($_REQUEST['geolocate'])) {
+   $geocoded = false;
    if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) {
       $_SESSION['lat'] = $_REQUEST['lat'];
         $_SESSION['lon'] = $_REQUEST['lon'];
    } else {
     $contents = geocode(filter_var($_REQUEST['geolocate'],FILTER_SANITIZE_URL),true);
     if (isset($contents[0]->centroid)) {
+      $geocoded = true;
         $_SESSION['lat'] = $contents[0]->centroid->coordinates[0];
         $_SESSION['lon'] = $contents[0]->centroid->coordinates[1];
-    }
-    else {
+      }
+      else {
         $_SESSION['lat'] = "";
         $_SESSION['lon'] = "";
     }
    }
+   if ($_SESSION['lat'] != "" && isMetricsOn()) {
+// Create a new Instance of the tracker
+$owa = new owa_php($config);
+// Set the ID of the site being tracked
+$owa->setSiteId($owaSiteID);
+// Create a new event object
+$event = $owa->makeEvent();
+// Set the Event Type, in this case a "video_play"
+$event->setEventType('geolocate');
+// Set a property
+$event->set('lat',$_SESSION['lat']);
+$event->set('lon',$_SESSION['lon']);
+$event->set('geocoded',$geocoded);
+// Track the event
+$owa->trackEvent($event);
+    }
  }
 debug(print_r($_SESSION,true));
-function isDebug()
-{
-    return $_SERVER['SERVER_NAME'] == "10.0.1.154" || $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1" || !$_SERVER['SERVER_NAME'];
+function isDebug($debugReason = "other")
+{
+    global $debugOkay;
+    return in_array($debugReason,$debugOkay,false) && $_SERVER['SERVER_NAME'] == "10.0.1.154" || $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1" || !$_SERVER['SERVER_NAME'];
 }
 
 function isMetricsOn()
 {
-    return false;
-}
-
-function debug($msg) {
-    if (isDebug()) echo "\n<!-- $msg -->\n";
+    return !isDebug();
+}
+
+function debug($msg, $debugReason = "other") {
+    if (isDebug($debugReason)) echo "\n<!-- ".date(DATE_RFC822)."\n $msg -->\n";
 }
 function isFastDevice() {
    $ua = $_SERVER['HTTP_USER_AGENT']; 
@@ -128,7 +150,8 @@
     require_once('owa/owa_env.php');
     require_once(OWA_DIR.'owa_php.php');
     $owa = new owa_php();
-    $owa->setSiteId('bus.lambdacomplex.org');
+    global $owaSiteID;
+    $owa->setSiteId($owaSiteID);
     $owa->setPageTitle($pageTitle);
     $owa->setPageType($pageType);
     $owa->trackPageView();
@@ -223,7 +246,15 @@
   return $f;
 }
 
-function staticmap($mapPoints, $zoom = 0, $markerImage = "iconb")
+function curPageURL() {
+$isHTTPS = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on");
+$port = (isset($_SERVER["SERVER_PORT"]) && ((!$isHTTPS && $_SERVER["SERVER_PORT"] != "80") || ($isHTTPS && $_SERVER["SERVER_PORT"] != "443")));
+$port = ($port) ? ':'.$_SERVER["SERVER_PORT"] : '';
+$url = ($isHTTPS ? 'https://' : 'http://').$_SERVER["SERVER_NAME"].$port.dirname($_SERVER['PHP_SELF'])."/";
+return $url;
+}
+
+function staticmap($mapPoints, $zoom = 0, $markerImage = "iconb", $collapsible = true)
 {
 $width = 300;
 $height = 300;
@@ -247,7 +278,7 @@
     if (sizeof($mapPoints) === 1) {
          if ($zoom == 0) $zoom = 14;
             $markers .= "{$mapPoints[0][0]},{$mapPoints[0][1]},$markerimage";
-            $center = "{$mapPoints[0][0]},{$mapPoints[0][1]}";        
+            $center = "{$mapPoints[0][0]},{$mapPoints[0][1]}";
     } else {
         foreach ($mapPoints as $index => $mapPoint) {
             $markers .= $mapPoint[0].",".$mapPoint[1].",".$markerImage.($index+1);
@@ -269,9 +300,9 @@
        $center = $totalLat/sizeof($mapPoints).",".$totalLon/sizeof($mapPoints);
     }
     $output = "";
-   if(basename($_SERVER['PHP_SELF']) != "tripPlanner.php") $output .= '<div data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>';
-    $output .= '<center><img src="staticmaplite/staticmap.php?center='.$center.'&zoom='.$zoom.'&size='.$width.'x'.$height.'&maptype=mapnik&markers='.$markers.'" width='.$width.' height='.$height.'></center>';
-   if(basename($_SERVER['PHP_SELF']) != "tripPlanner.php") $output .= '</div>';
+   if ($collapsible) $output .= '<div data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>';
+    $output .= '<center><img src="'.curPageURL().'staticmaplite/staticmap.php?center='.$center.'&zoom='.$zoom.'&size='.$width.'x'.$height.'&maptype=mapnik&markers='.$markers.'" width='.$width.' height='.$height.'></center>';
+   if ($collapsible) $output .= '</div>';
     return $output;
 }
 
@@ -460,7 +491,7 @@
 	        </div>
     		<div data-role="fieldcontain">
 		        <label for="time"> Time: </label>
-		    	<input type="time" name="time" id="time" value="'. (isset($_SESSION['time']) ? $_SESSION['time'] : date("H:m")).'"/> <a href="#" name="currentTime" id="currentTime"/>Current Time?</a>
+		    	<input type="time" name="time" id="time" value="'. (isset($_SESSION['time']) ? $_SESSION['time'] : date("H:i")).'"/> <a href="#" name="currentTime" id="currentTime"/>Current Time?</a>
 	        </div>
 		<div data-role="fieldcontain">
 		    <label for="service_period"> Service Period:  </label>
@@ -477,5 +508,7 @@
                 </form>
             </div></div>';
 }
+
+
 ?>
 

--- a/feedback.php
+++ b/feedback.php
@@ -31,18 +31,22 @@
 <h3>Add/Move/Delete a Bus Stop Location</h3>
 StopID:
 or StopCode:
+<small> if you click on feedback from a stop page, these will get filled in automatically. else describe the location/street of the stop <input type="text" name="stoplocation" /> </small>
 
 Suggested Stop Location (lat/long or words):
+<small> if your device supports javascript, you can pick a location from the map above</small>
 
 Submit!
 
 <h3>Bug Report/Feedback</h3>
+Please leave feedback about bugs/errors or general suggestions about improvements that could be made to the way the data is presented!
 <textarea id="feedback">
 </textarea>
 <textarea id="extrainfo">
     Referrer URL
     User Agent
     User host/IP
+    Server host/IP
     Current date/time
     Dump of $_SESSION
 </textarea>

--- a/layar_api.php
+++ b/layar_api.php
@@ -26,7 +26,7 @@
         $hotspot['distance'] = distance($row[2], $row[3], $_REQUEST['lat'], $_REQUEST['lon']);
         if (!isset($_REQUEST['radius']) || $hotspot['distance'] < $_REQUEST['radius']) {
             $hotspot['actions'] = Array(Array("label" => 'View more trips/information', 'uri' => 'http://bus.lambdacomplex.org/'.'stop.php?stopid='.$row[0]));
-            $url = $APIurl."/json/stoptrips?stop=".$row[0]."&time=".midnight_seconds()."&service_period=".service_period()."&limit=4";
+            $url = $APIurl."/json/stoptrips?stop=".$row[0]."&time=".midnight_seconds()."&service_period=".service_period()."&limit=4&time_range=".str(90*60);
             $trips = json_decode(getPage($url));
             debug(print_r($trips,true));
             foreach ($trips as $key => $row)

--- a/schedule_viewer.py
+++ b/schedule_viewer.py
@@ -421,23 +421,69 @@
       if s.stop_id.lower() == query:
         return StopToTuple(s)
     return []
+  def handle_json_GET_stoproutes(self, params):
+    """Given a stop_id return all routes to visit the stop."""
+    schedule = self.server.schedule
+    stop = schedule.GetStop(params.get('stop', None))
+    service_period = params.get('service_period', None)
+    trips = stop.GetTrips(schedule)
+    result = {}
+    for trip in trips:
+      route = schedule.GetRoute(trip.route_id)
+      if not trip.route_id in result:
+        result[trip.route_id] = (route.route_id, route.route_short_name, route.route_long_name, trip.trip_id)
+    return result
+    
+  def handle_json_GET_stopalltrips(self, params):
+    """Given a stop_id return all trips to visit the stop."""
+    schedule = self.server.schedule
+    stop = schedule.GetStop(params.get('stop', None))
+    service_period = params.get('service_period', None)
+    time_trips = stop.GetStopTimeTrips(schedule)
+    result = []
+    for time, (trip, index), tp in time_trips:
+      headsign = None
+      # Find the most recent headsign from the StopTime objects
+      for stoptime in trip.GetStopTimes()[index::-1]:
+        if stoptime.stop_headsign:
+          headsign = stoptime.stop_headsign
+          break
+      # If stop_headsign isn't found, look for a trip_headsign
+      if not headsign:
+        headsign = trip.trip_headsign
+      route = schedule.GetRoute(trip.route_id)
+      trip_name = ''
+      if route.route_short_name:
+        trip_name += route.route_short_name
+      if route.route_long_name:
+        if len(trip_name):
+          trip_name += " - "
+        trip_name += route.route_long_name
+      if service_period == None or trip.service_id == service_period:
+        result.append((time, (trip.trip_id, trip_name, trip.service_id), tp))
+    return result
 
   def handle_json_GET_stoptrips(self, params):
     """Given a stop_id and time in seconds since midnight return the next
     trips to visit the stop."""
     schedule = self.server.schedule
     stop = schedule.GetStop(params.get('stop', None))
-    time = int(params.get('time', 0))
+    requested_time = int(params.get('time', 0))
     limit = int(params.get('limit', 15))
     service_period = params.get('service_period', None)
-    time_trips = stop.GetStopTimeTrips(schedule)
-    time_trips.sort()  # OPT: use bisect.insort to make this O(N*ln(N)) -> O(N)
-    # Keep the first 15 after param 'time'.
-    # Need make a tuple to find correct bisect point
-    time_trips = time_trips[bisect.bisect_left(time_trips, (time, 0)):]
-    time_trips = time_trips[:15]
+    time_range = params.get('time_range', 24*60*60)
+    
+    
+    filtered_time_trips = []
+    for trip, index in stop._GetTripIndex(schedule):
+      tripstarttime = trip.GetStartTime()
+      if tripstarttime > requested_time and tripstarttime < (requested_time + time_range):
+        time, stoptime, tp = trip.GetTimeInterpolatedStops()[index]
+        if time > requested_time and time < (requested_time + time_range):
+          bisect.insort(filtered_time_trips, (time, (trip, index), tp))
+    
     result = []
-    for time, (trip, index), tp in time_trips:
+    for time, (trip, index), tp in filtered_time_trips:
       if len(result) > limit:
         break
       headsign = None

file:b/stop.pdf.php (new)
--- /dev/null
+++ b/stop.pdf.php
@@ -1,1 +1,185 @@
+<?php
+include('common.inc.php');
+$url = $APIurl."/json/stop?stop_id=".$_REQUEST['stopid'];
+$stop = json_decode(getPage($url));
 
+$html .= '<div data-role="content" class="ui-content" role="main"><p>'.staticmap(Array(0 => Array($stop[2],$stop[3])), 0,"iconb", false).'</p>';
+$html .= '  <ul data-role="listview"  data-inset="true">';
+$url = $APIurl."/json/stoptrips?stop=".$_REQUEST['stopid']."&time=".midnight_seconds()."&service_period=".service_period();
+$trips = json_decode(getPage($url));
+debug(print_r($trips,true));
+foreach ($trips as $row)
+{
+$html .=  '<li>';
+$html .= '<h3><a href="trip.php?stopid='.$_REQUEST['stopid'].'&tripid='.$row[1][0].'">'.$row[1][1];
+if (isFastDevice()) {
+    $viaPoints = viaPointNames($row[1][0],$_REQUEST['stopid']);
+    if ($viaPoints != "") $html .= '<br><small>Via: '.$viaPoints.'</small> </a></h3>';
+}
+$html .= '<p class="ui-li-aside"><strong>'.midnight_seconds_to_time($row[0]).'</strong></p>';
+$html .= '</li>';  
+}
+if (sizeof($trips) == 0) $html .= "<li> <center>No trips in the near future.</center> </li>";
+$html .= '</ul></div>';
+require_once('tcpdf/config/lang/eng.php');
+require_once('tcpdf/tcpdf.php');
+
+// create new PDF document
+class Custom_TCPDF extends TCPDF {
+    var $QRCodeURL;
+  
+    function set_QRCodeURL ($url) {
+        $this->QRCodeURL = $url;
+    }
+
+/**
+         * This method is used to render the page header.
+         * It is automatically called by AddPage() and could be overwritten in your own inherited class.
+         * @public
+         */
+	public function Header() {
+                if ($this->header_xobjid < 0) {
+                        // start a new XObject Template
+                        $this->header_xobjid = $this->startTemplate($this->w, $this->tMargin+10);
+                        $headerfont = $this->getHeaderFont();
+                        $headerdata = $this->getHeaderData();
+                        $this->y = $this->header_margin;
+                        if ($this->rtl) {
+                                $this->x = $this->w - $this->original_rMargin;
+                        } else {
+                               	$this->x = $this->original_lMargin-10;
+                        }
+			if (isset($this->QRCodeURL)) {
+// QRCODE,H : QR-CODE Best error correction
+$style = array(
+        'border' => 1,
+        'padding' => 0,
+        'fgcolor' => array(0,0,0),
+        'bgcolor' => false, //array(255,255,255)
+        'module_width' => 1, // width of a single module in points
+        'module_height' => 1 // height of a single module in points
+);
+$this->write2DBarcode($this->QRCodeURL, 'QRCODE,H', '', '', 25, 25, $style, 'T');
+$imgy = 50+20;
+			} elseif (($headerdata['logo']) AND ($headerdata['logo'] != K_BLANK_IMAGE)) {
+                                $imgtype = $this->getImageFileType(K_PATH_IMAGES.$headerdata['logo']);
+                                if (($imgtype == 'eps') OR ($imgtype == 'ai')) {
+                                       	$this->ImageEps(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
+                                } elseif ($imgtype == 'svg') {
+                                        $this->ImageSVG(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
+                                } else {
+                                       	$this->Image(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
+                                }
+                                $imgy = $this->getImageRBY();
+                       	} else {
+                               	$imgy = $this->y;
+                       	}
+                        $cell_height = round(($this->cell_height_ratio * $headerfont[2]) / $this->k, 2);
+                        // set starting margin for text data cell
+                       	if ($this->getRTL()) {
+                                $header_x = $this->original_rMargin + ($headerdata['logo_width'] * 1.1);
+                       	} else {
+                                $header_x = $this->original_lMargin + ($headerdata['logo_width'] * 1.1);
+                        }
+                       	$cw = $this->w - $this->original_lMargin - $this->original_rMargin - ($headerdata['logo_width'] * 1.1);
+                       	$this->SetTextColor(0, 0, 0);
+                        // header title
+                        $this->SetFont($headerfont[0], 'B', $headerfont[2] + 1);
+                        $this->SetX($header_x);
+                        $this->Cell($cw, $cell_height, $headerdata['title'], 0, 1, '', 0, '', 0);
+                        // header string
+                        $this->SetFont($headerfont[0], $headerfont[1], $headerfont[2]);
+                        $this->SetX($header_x);
+                        $this->MultiCell($cw, $cell_height, $headerdata['string'], 0, '', 0, 1, '', '', true, 0, false);
+                        // print an ending header line
+                        //$this->SetLineStyle(array('width' => 0.85 / $this->k, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)));
+                        //$this->SetY((2.835 / $this->k) + max($imgy, $this->y));
+                        if ($this->rtl) {
+                                $this->SetX($this->original_rMargin);
+                       	} else {
+                                $this->SetX($this->original_lMargin);
+                       	}
+                        //$this->Cell(($this->w - $this->original_lMargin - $this->original_rMargin), 0, '', 'T', 0, 'C');
+                        $this->endTemplate();
+                }
+                // print header template
+                $x = 0;
+                $dx = 0;
+                if ($this->booklet AND (($this->page % 2) == 0)) {
+                        // adjust margins for booklet mode
+                       	$dx = ($this->original_lMargin - $this->original_rMargin);
+                }
+                if ($this->rtl) {
+                       	$x = $this->w + $dx;
+                } else {
+                       	$x = 0 + $dx;
+                }
+                $this->printTemplate($this->header_xobjid, $x, 0, 0, 0, '', '', false);
+        }
+
+
+}
+$pdf = new Custom_TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
+
+// set document information
+$pdf->SetCreator(PDF_CREATOR);
+$pdf->SetAuthor('bus.lambdacomplex.org');
+$pdf->SetTitle($stop[1]);
+
+// set default header data
+$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, $stop[1] . " Timetable", "Some description of customization like Weekdays, 9am-10am");
+$pdf->set_QRCodeURL(curPageURL()."stop.php?stopid=".$_REQUEST['stopid']);
+
+// set header and footer fonts
+$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
+$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
+
+// set default monospaced font
+$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
+
+//set margins
+$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
+$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
+$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
+
+//set auto page breaks
+$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
+
+//set image scale factor
+$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
+
+//set some language-dependent strings
+$pdf->setLanguageArray($l);
+
+// ---------------------------------------------------------
+
+// set default font subsetting mode
+$pdf->setFontSubsetting(true);
+
+// Set font
+// dejavusans is a UTF-8 Unicode font, if you only need to
+// print standard ASCII chars, you can use core fonts like
+// helvetica or times to reduce file size.
+$pdf->SetFont('helvetica', '', 14, '', true);
+
+// Add a page
+// This method has several options, check the source code documentation for more information.
+$pdf->AddPage();
+
+
+// Print text using writeHTMLCell()
+$pdf->writeHTMLCell($w=0, $h=0, $x='', $y='', $html, $border=0, $ln=1, $fill=0, $reseth=true, $align='', $autopadding=true);
+
+
+
+// ---------------------------------------------------------
+
+// Close and output PDF document
+// This method has several options, check the source code documentation for more information.
+$pdf->Output('example_001.pdf', 'I');
+
+//============================================================+
+// END OF FILE
+//============================================================+
+?>
+

file:a/stop.php -> file:b/stop.php
--- a/stop.php
+++ b/stop.php
@@ -6,9 +6,9 @@
 include_header($stop[1],"stop");
 if (isMetricsOn()) {
 // Create a new Instance of the tracker
-$owa = new owa_php($config);
+$owa = new owa_php();
 // Set the ID of the site being tracked
-$owa->setSiteId('bus.lambdacomplex.org');
+$owa->setSiteId($owaSiteID);
 // Create a new event object
 $event = $owa->makeEvent();
 // Set the Event Type, in this case a "video_play"

--- a/stopList.php
+++ b/stopList.php
@@ -42,7 +42,7 @@
 // Create a new Instance of the tracker
 $owa = new owa_php($config);
 // Set the ID of the site being tracked
-$owa->setSiteId('bus.lambdacomplex.org');
+$owa->setSiteId($owaSiteID);
 // Create a new event object
 $event = $owa->makeEvent();
 // Set the Event Type, in this case a "video_play"

--- /dev/null
+++ b/tcpdf/2dbarcodes.php
@@ -1,1 +1,173 @@
+<?php
+//============================================================+
+// File name   : 2dbarcodes.php
+// Version     : 1.0.007
+// Begin       : 2009-04-07
+// Last Update : 2010-12-16
+// Author      : Nicola Asuni - Tecnick.com S.r.l - Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - info@tecnick.com
+// License     : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
+// -------------------------------------------------------------------
+// Copyright (C) 2009-2010  Nicola Asuni - Tecnick.com S.r.l.
+//
+// This file is part of TCPDF software library.
+//
+// TCPDF is free software: you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// TCPDF is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with TCPDF.  If not, see <http://www.gnu.org/licenses/>.
+//
+// See LICENSE.TXT file for more information.
+// -------------------------------------------------------------------
+//
+// Description : PHP class to creates array representations for
+//               2D barcodes to be used with TCPDF.
+//
+//============================================================+
 
+/**
+ * @file
+ * PHP class to creates array representations for 2D barcodes to be used with TCPDF.
+ * @package com.tecnick.tcpdf
+ * @author Nicola Asuni
+ * @version 1.0.007
+ */
+
+/**
+ * @class TCPDF2DBarcode
+ * PHP class to creates array representations for 2D barcodes to be used with TCPDF (http://www.tcpdf.org).
+ * @package com.tecnick.tcpdf
+ * @version 1.0.007
+ * @author Nicola Asuni
+ */
+class TCPDF2DBarcode {
+
+	/**
+	 * Array representation of barcode.
+	 * @protected
+	 */
+	protected $barcode_array = false;
+
+	/**
+	 * This is the class constructor.
+	 * Return an array representations for 2D barcodes:<ul>
+	 * <li>$arrcode['code'] code to be printed on text label</li>
+	 * <li>$arrcode['num_rows'] required number of rows</li>
+	 * <li>$arrcode['num_cols'] required number of columns</li>
+	 * <li>$arrcode['bcode'][$r][$c] value of the cell is $r row and $c column (0 = transparent, 1 = black)</li></ul>
+	 * @param $code (string) code to print
+ 	 * @param $type (string) type of barcode: <ul><li>RAW: raw mode - comma-separad list of array rows</li><li>RAW2: raw mode - array rows are surrounded by square parenthesis.</li><li>QRCODE : QR-CODE Low error correction</li><li>QRCODE,L : QR-CODE Low error correction</li><li>QRCODE,M : QR-CODE Medium error correction</li><li>QRCODE,Q : QR-CODE Better error correction</li><li>QRCODE,H : QR-CODE Best error correction</li><li>PDF417 : PDF417 (ISO/IEC 15438:2006)</li><li>PDF417,a,e,t,s,f,o0,o1,o2,o3,o4,o5,o6 : PDF417 with parameters: a = aspect ratio (width/height); e = error correction level (0-8); t = total number of macro segments; s = macro segment index (0-99998); f = file ID; o0 = File Name (text); o1 = Segment Count (numeric); o2 = Time Stamp (numeric); o3 = Sender (text); o4 = Addressee (text); o5 = File Size (numeric); o6 = Checksum (numeric). NOTES: Parameters t, s and f are required for a Macro Control Block, all other parametrs are optional. To use a comma character ',' on text options, replace it with the character 255: "\xff".</li></ul>
+	 */
+	public function __construct($code, $type) {
+		$this->setBarcode($code, $type);
+	}
+
+	/**
+	 * Return an array representations of barcode.
+ 	 * @return array
+	 */
+	public function getBarcodeArray() {
+		return $this->barcode_array;
+	}
+
+	/**
+	 * Set the barcode.
+	 * @param $code (string) code to print
+ 	 * @param $type (string) type of barcode: <ul><li>RAW: raw mode - comma-separad list of array rows</li><li>RAW2: raw mode - array rows are surrounded by square parenthesis.</li><li>QRCODE : QR-CODE Low error correction</li><li>QRCODE,L : QR-CODE Low error correction</li><li>QRCODE,M : QR-CODE Medium error correction</li><li>QRCODE,Q : QR-CODE Better error correction</li><li>QRCODE,H : QR-CODE Best error correction</li><li>PDF417 : PDF417 (ISO/IEC 15438:2006)</li><li>PDF417,a,e,t,s,f,o0,o1,o2,o3,o4,o5,o6 : PDF417 with parameters: a = aspect ratio (width/height); e = error correction level (0-8); t = total number of macro segments; s = macro segment index (0-99998); f = file ID; o0 = File Name (text); o1 = Segment Count (numeric); o2 = Time Stamp (numeric); o3 = Sender (text); o4 = Addressee (text); o5 = File Size (numeric); o6 = Checksum (numeric). NOTES: Parameters t, s and f are required for a Macro Control Block, all other parametrs are optional. To use a comma character ',' on text options, replace it with the character 255: "\xff".</li></ul>
+ 	 * @return array
+	 */
+	public function setBarcode($code, $type) {
+		$mode = explode(',', $type);
+		$qrtype = strtoupper($mode[0]);
+		switch ($qrtype) {
+			case 'QRCODE': { // QR-CODE
+				require_once(dirname(__FILE__).'/qrcode.php');
+				if (!isset($mode[1]) OR (!in_array($mode[1],array('L','M','Q','H')))) {
+					$mode[1] = 'L'; // Ddefault: Low error correction
+				}
+				$qrcode = new QRcode($code, strtoupper($mode[1]));
+				$this->barcode_array = $qrcode->getBarcodeArray();
+				break;
+			}
+			case 'PDF417': { // PDF417 (ISO/IEC 15438:2006)
+				require_once(dirname(__FILE__).'/pdf417.php');
+				if (!isset($mode[1]) OR ($mode[1] === '')) {
+					$aspectratio = 2; // default aspect ratio (width / height)
+				} else {
+					$aspectratio = floatval($mode[1]);
+				}
+				if (!isset($mode[2]) OR ($mode[2] === '')) {
+					$ecl = -1; // default error correction level (auto)
+				} else {
+					$ecl = intval($mode[2]);
+				}
+				// set macro block
+				$macro = array();
+				if (isset($mode[3]) AND ($mode[3] !== '') AND isset($mode[4]) AND ($mode[4] !== '') AND isset($mode[5]) AND ($mode[5] !== '')) {
+					$macro['segment_total'] = intval($mode[3]);
+					$macro['segment_index'] = intval($mode[4]);
+					$macro['file_id'] = strtr($mode[5], "\xff", ',');
+					for ($i = 0; $i < 7; ++$i) {
+						$o = $i + 6;
+						if (isset($mode[$o]) AND ($mode[$o] !== '')) {
+							// add option
+							$macro['option_'.$i] = strtr($mode[$o], "\xff", ',');
+						}
+					}
+				}
+				$qrcode = new PDF417($code, $ecl, $aspectratio, $macro);
+				$this->barcode_array = $qrcode->getBarcodeArray();
+				break;
+			}
+			case 'RAW':
+			case 'RAW2': { // RAW MODE
+				// remove spaces
+				$code = preg_replace('/[\s]*/si', '', $code);
+				if (strlen($code) < 3) {
+					break;
+				}
+				if ($qrtype == 'RAW') {
+					// comma-separated rows
+					$rows = explode(',', $code);
+				} else { // RAW2
+					// rows enclosed in square parentheses
+					$code = substr($code, 1, -1);
+					$rows = explode('][', $code);
+				}
+				$this->barcode_array['num_rows'] = count($rows);
+				$this->barcode_array['num_cols'] = strlen($rows[0]);
+				$this->barcode_array['bcode'] = array();
+				foreach ($rows as $r) {
+					$this->barcode_array['bcode'][] = str_split($r, 1);
+				}
+				break;
+			}
+			case 'TEST': { // TEST MODE
+				$this->barcode_array['num_rows'] = 5;
+				$this->barcode_array['num_cols'] = 15;
+				$this->barcode_array['bcode'] = array(
+					array(1,1,1,0,1,1,1,0,1,1,1,0,1,1,1),
+					array(0,1,0,0,1,0,0,0,1,0,0,0,0,1,0),
+					array(0,1,0,0,1,1,0,0,1,1,1,0,0,1,0),
+					array(0,1,0,0,1,0,0,0,0,0,1,0,0,1,0),
+					array(0,1,0,0,1,1,1,0,1,1,1,0,0,1,0));
+				break;
+			}
+			default: {
+				$this->barcode_array = false;
+			}
+		}
+	}
+} // end of class
+
+//============================================================+
+// END OF FILE
+//============================================================+
+

--- /dev/null
+++ b/tcpdf/CHANGELOG.TXT
@@ -1,1 +1,1957 @@
-
+5.9.059 (2011-02-27)
+	- Default Header() method was improved to reduce document size.
+
+5.9.058 (2011-02-25)
+	- Image() method was improved to cache images with transparency layers (thanks to Korneliusz Jarzębski for reporting this problem).
+
+5.9.057 (2011-02-24)
+	- A problem with image caching system was fixed (thanks to Korneliusz Jarzębski for reporting this problem).
+
+5.9.056 (2011-02-22)
+	- A bug on fixHTMLCode() method was fixed.
+	- Automatic line break for HTML was fixed.
+
+5.9.055 (2011-02-17)
+	- Another bug related to HTML table page break was fixed.
+
+5.9.054 (2011-02-16)
+	- A bug related to HTML table page break was fixed.
+
+5.9.053 (2011-02-16)
+	- Support for HTMl attribute display="none" was added.
+
+5.9.052 (2011-02-15)
+	- A bug related to HTML automatic newlines was fixed.
+
+5.9.051 (2011-02-12)
+	- "Commas at beginning of new lines" problem was fixed.
+
+5.9.050 (2011-02-11)
+	- Bug #3177606 "SVG Bar chart error" was fixed.
+
+5.9.049 (2011-02-03)
+	- Bug #3170777 "TCPDF creates a new page after a single line in writeHTML" was fixed.
+
+5.9.048 (2011-02-02)
+	- No changes. Just released to override previous release that was not uploaded correctly.
+
+5.9.047 (2011-01-28)
+	- Bug #3167115 "PDF error in <table> (example 48)" was fixed (was introduced in 5.8.046).
+
+5.9.046 (2011-01-18)
+	- PDF view/print layers are now automatically turned off if not used (see setVisibility() method).
+
+5.9.045 (2011-01-17)
+	- HTML list support were improved.
+
+5.9.044 (2011-01-15)
+	- Bug #3158422 "writeHTMLCell Loop" was fixed.
+	- Some HTML image alignment problems were fixed.
+
+5.9.043 (2011-01-14)
+	- Bug #3158178 "PHP Notice" was fixed.
+	- Bug #3158193 "Endless l