Index: /trunk/client/modules/Elezioni/grafici/barcode/demoapp/barcode_image.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/barcode/demoapp/barcode_image.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/barcode/demoapp/barcode_image.php	(revision 266)
@@ -0,0 +1,75 @@
+<?php
+require_once "jpgraph/jpgraph.php";
+require_once "jpgraph/jpgraph_canvas.php";
+require_once "jpgraph/jpgraph_barcode.php";
+
+$params = array(
+    array('code',1),array('data',''),array('modwidth',1),array('info',false),
+    array('notext',false),array('checksum',false),array('showframe',false),
+    array('vertical',false) , array('backend','IMAGE'), array('file',''),
+    array('scale',1), array('height',70), array('pswidth','') );
+
+$n=count($params);
+for($i=0; $i < $n; ++$i ) {
+    $v  = $params[$i][0];
+    if( empty($_GET[$params[$i][0]]) ) {
+	$$v = $params[$i][1];
+    }
+    else
+	$$v = $_GET[$params[$i][0]];
+}
+
+if( $modwidth < 1 || $modwidth > 5 ) {
+    echo "<h4>Module width must be between 1 and 5 pixels</h4>";
+}
+elseif( $data==="" ) {
+    echo "<h3>Please enter data to be encoded, select symbology and press 'Ok'.</h3>";
+    echo "<i>Note: Data must be valid for the choosen encoding.</i>";
+}
+elseif( $code==-1 ) {
+    echo "<h4>No code symbology selected.</h4>";
+}
+elseif( $height < 10 || $height > 500 ) {
+    echo "<h4> Height must be in range [10, 500]</h4>";
+}
+elseif( $scale < 0.1 || $scale > 15 ) {
+    echo "<h4> Scale must be in range [0.1, 15]</h4>";
+}
+else {
+    if( $code==20 ) {
+	$encoder = BarcodeFactory::Create(6);
+	$encoder->UseExtended();
+    }
+    else {
+	$encoder = BarcodeFactory::Create($code);
+    }
+    $b =  $backend=='EPS' ? 'PS' : $backend;
+    $b = substr($backend,0,5) == 'IMAGE' ? 'IMAGE' : $b;
+    $e = BackendFactory::Create($b,$encoder);
+    if( substr($backend,0,5) == 'IMAGE' ) {
+	if( substr($backend,5,1) == 'J' ) 
+	    $e->SetImgFormat('JPEG');
+    }
+    if( $e ) {
+	if( $backend == 'EPS' )
+	    $e->SetEPS();
+	if( $pswidth!='' )
+	    $modwidth = $pswidth;
+	$e->SetModuleWidth($modwidth);
+	$e->AddChecksum($checksum);
+	$e->NoText($notext);
+	$e->SetScale($scale);
+	$e->SetVertical($vertical);
+	$e->ShowFrame($showframe);
+	$e->SetHeight($height);
+	$r = $e->Stroke($data,$file,$info,$info);
+	if( $r )
+	    echo nl2br(htmlspecialchars($r));
+	if( $file != '' )
+	    echo "<p>Wrote file $file.";
+    }
+    else
+	echo "<h3>Can't create choosen backend: $backend.</h3>";
+}
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/barcode/demoapp/barcode_menu.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/barcode/demoapp/barcode_menu.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/barcode/demoapp/barcode_menu.php	(revision 266)
@@ -0,0 +1,125 @@
+<H2>JpGraph Barcode 1.0</h2>
+<hr>
+</font>
+<form name="barcodespec" action="barcode_image.php" target=barcode
+method post>
+<table cellspacing=4 cellpadding=0>
+<tr>
+<td colspan=2>
+Data:<br>
+<input type=text name=data size=25 maxlength=30>
+</td>
+<tr><td>
+Encoding:<br>
+<select name=code>
+<option selected value=-1> Choose encoding </option>
+<option   value=4> UPC A </option>
+<option   value=5> UPC E </option>
+<option   value=3> EAN 8 </option>
+<option   value=2> EAN 13 </option>
+<option   value=1> EAN 128 </option>
+<option   value=11> Industrial 2 of 5 </option>
+<option   value=12> Interleaved 2 of 5 </option>
+<option   value=14> CODE 11 </option>
+<option   value=6> CODE 39 </option>
+<option   value=20> CODE 39 Extended </option>
+<option   value=8> CODE 128 </option>
+<option   value=13> CODABAR </option>
+<option   value=10> BOOKLAND (ISBN) </option>
+</select>
+</td>
+<td>
+Module width:<br>
+<select name=modwidth>
+<option value=1> One </option>
+<option value=2> Two </option>
+<option value=3> Three </option>
+<option value=4> Four </option>
+<option value=5> Five </option>
+</select>
+</td>
+</tr>
+
+<tr>
+<td>
+Add checksum:<br>
+<input type=checkbox value=1 name=checksum>
+</td>
+
+<td>
+Hide text:<br>
+<input type=checkbox value=1 name=notext>
+</td>
+</tr>
+<tr>
+<td>
+Show frame:<br>
+<input type=checkbox value=1 name=showframe>
+</td>
+<td>
+Vertical layout:<br>
+<input type=checkbox value=1 name=vertical>
+</td>
+</tr>
+
+<tr>
+<td>
+Height:<br>
+<input type=text name=height value="70" size=3 maxlength=3>
+</td>
+<td>
+Scale:<br>
+<input type=text name=scale value="1.0" size=4 maxlength=4>
+</td>
+</tr>
+
+
+
+<tr>
+<td>
+Write to file:<br>
+<input type=text name=file size=15 maxlength=80>
+</td>
+<td>
+Format:<br>
+<select name=backend>
+<option selected value="IMAGEPNG">Image (PNG)</option>
+<option value="IMAGEJPG">Image (JPEG)</option>
+<option value="PS">Postscript</option>
+<option value="EPS">EPS</option>
+</select>
+</td>
+
+<tr>
+<td>
+PS module width:
+</td>
+<td>
+<input type=text name=pswidth size=4 maxlength=4><br>
+</td>
+</tr>
+
+<tr>
+<td colspan=2>
+<small><i>(If specified will override Module width above)</i></small><br>
+</td>
+</tr>
+
+
+<tr>
+<td>
+Debug info:<br>
+<input type=checkbox value=1 name=info>
+</td>
+<td align=right valign=bottom>
+<br>
+<input type=submit name=submit value="&nbsp; Create &nbsp;" style="font-weight:bold;">
+</td>
+</tr></table>
+</form>
+
+<p>
+<hr>
+
+
+
Index: /trunk/client/modules/Elezioni/grafici/barcode/demoapp/index.html
===================================================================
--- /trunk/client/modules/Elezioni/grafici/barcode/demoapp/index.html	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/barcode/demoapp/index.html	(revision 266)
@@ -0,0 +1,10 @@
+<!doctype html public "-//W3C//DTD HTML 4.0 Frameset//EN">
+<HTML><HEAD>
+<LINK REL=STYLESHEET TYPE="text/css" HREF="de_normal.css">
+<title>Barcode SYSTEMTEST</title>
+</head>
+<frameset cols="280,*">
+<frame src=barcode_menu.php name=menu>;
+<frame  src=barcode_image.php name=barcode>
+</frameset>
+</html>
Index: /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_errhandling_ex0.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_errhandling_ex0.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_errhandling_ex0.php	(revision 266)
@@ -0,0 +1,16 @@
+<?php
+// ==============================================
+// Output Image using Code 39 using only default values
+// ==============================================
+require_once ('jpgraph/jpgraph_barcode.php');
+
+try {
+$encoder = BarcodeFactory::Create(ENCODING_CODE39);
+$e = BackendFactory::Create(BACKEND_IMAGE,$encoder);
+$e->Stroke('abc123');
+} catch( JpGraphException $e ) {
+	//echo 'Error: ' . $e->getMessage()."\n";
+	JpGraphError::Raise($e->getMessage());
+}
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex0.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex0.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex0.php	(revision 266)
@@ -0,0 +1,11 @@
+<?php
+// ==============================================
+// Output Image using Code 39 using only default values
+// ==============================================
+require_once ('jpgraph/jpgraph_barcode.php');
+
+$encoder = BarcodeFactory::Create(ENCODING_CODE39);
+$e = BackendFactory::Create(BACKEND_IMAGE,$encoder);
+$e->Stroke('ABC123');
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex1.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex1.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex1.php	(revision 266)
@@ -0,0 +1,14 @@
+<?php
+// ==============================================
+// Output Image using Code 128
+// ==============================================
+require_once ('jpgraph/jpgraph_barcode.php');
+
+$encoder = BarcodeFactory::Create(ENCODING_CODE128);
+$e = BackendFactory::Create(BACKEND_PS,$encoder);
+$e->SetModuleWidth(2);
+$e->SetHeight(20);
+echo nl2br($e->Stroke('3125134772'));
+
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex2.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex2.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex2.php	(revision 266)
@@ -0,0 +1,14 @@
+<?php
+// ==============================================
+// Output Postscript of nterleaved 2 of 5
+// ==============================================
+require_once ('jpgraph/jpgraph_barcode.php');
+
+$encoder = BarcodeFactory::Create(ENCODING_CODEI25);
+$e = BackendFactory::Create(BACKEND_PS,$encoder);
+$e->SetModuleWidth(2);
+$e->SetHeight(70);
+$ps = $e->Stroke('3125134772');
+echo nl2br(htmlspecialchars($ps));
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex3.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex3.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex3.php	(revision 266)
@@ -0,0 +1,17 @@
+<?php
+// ==============================================
+// Output Encapsulated Postscript of interleaved 2 of 5
+// ==============================================
+require_once ('jpgraph/jpgraph_barcode.php');
+
+echo "Start ...<br>";
+$encoder = BarcodeFactory::Create(ENCODING_CODEI25);
+$e = BackendFactory::Create(BACKEND_PS,$encoder);
+$e->SetModuleWidth(2);
+$e->SetHeight(70);
+$e->SetEPS();
+$ps = $e->Stroke('3125134772');
+echo nl2br(htmlspecialchars($ps));
+
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex4.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex4.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_ex4.php	(revision 266)
@@ -0,0 +1,12 @@
+<?php
+// ==============================================
+// Output Image using Code Interleaved 2 of 5
+// ==============================================
+require_once ('jpgraph/jpgraph_barcode.php');
+
+$encoder = BarcodeFactory::Create(ENCODING_CODEI25);
+$e = BackendFactory::Create(BACKEND_IMAGE,$encoder);
+$e->SetModuleWidth(2);
+$e->Stroke('1234');
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_usps_example.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_usps_example.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/barcode/examples/barcode_usps_example.php	(revision 266)
@@ -0,0 +1,74 @@
+<?php
+// =======================================================
+// Example of how to format US Postal shipping information
+// =======================================================
+require_once ('jpgraph/jpgraph_barcode.php');
+
+// The Full barcode standard is described in
+// http://www.usps.com/cpim/ftp/pubs/pub91/91c4.html#508hdr1
+//
+// The data start with AI=420 which means
+// "Ship to/Deliver To Postal Code (within single authority)
+//
+class USPS_Confirmation {
+    function USPS_Confirmation() {
+    }
+
+    // Private utility function
+    function _USPS_chkd($aData) {
+	$n = strlen($aData);
+
+	// Add all even numbers starting from position 1 from the end
+	$et = 0 ;
+	for( $i=1; $i <= $n; $i+=2 ) {
+	    $d = intval(substr($aData,-$i,1));
+	    $et += $d;
+	}
+
+	// Add all odd numbers starting from position 2 from the end
+	$ot = 0 ;
+	for( $i=2; $i <= $n; $i+=2 ) {
+	    $d = intval(substr($aData,-$i,1));
+	    $ot += $d;
+	}
+	$tot = 3*$et + $ot;
+	$chkdigit = (10 - ($tot % 10))%10;;
+	return $chkdigit;
+    }
+
+    // Get type 1 of confirmation code (with ZIP)
+    function GetPICwithZIP($aZIP,$aServiceType,$aDUNS,$aSeqNbr) {
+	// Convert to USPS format with AI=420 and extension starting with AI=91
+	$data = '420'. $aZIP . '91' . $aServiceType . $aDUNS . $aSeqNbr;
+	// Only calculate the checkdigit from the AI=91 and forward
+	// and do not include the ~1 (FUNC1) in the calculation
+	$cd = $this->_USPS_chkd(substr($data,8));
+	$data = '420'. $aZIP . '~191' . $aServiceType . $aDUNS . $aSeqNbr;
+	return $data . $cd;
+    }
+
+    // Get type 2 of confirmation code (without ZIP)
+    function GetPIC($aServiceType,$aDUNS,$aSeqNbr) {
+	// Convert to USPS format with AI=91
+	$data = '91' . $aServiceType . $aDUNS . $aSeqNbr;
+	$cd = $this->_USPS_chkd($data);
+	return $data . $cd;
+    }
+
+}
+
+$usps = new USPS_Confirmation();
+$zip     = '92663';
+$service = '21';
+$DUNS    = '805213907';
+$seqnr   = '04508735';
+$data = $usps->GetPICwithZIP($zip,$service,$DUNS,$seqnr);
+//$data = $usps->GetPIC('01','123456789','00000001');
+
+$encoder = BarcodeFactory::Create(ENCODING_EAN128);
+$e = BackendFactory::Create(BACKEND_IMAGE,$encoder);
+$e->SetModuleWidth(2);
+$e->SetFont(FF_ARIAL,FS_NORMAL,14);
+$e->Stroke($data);
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/barcode/mkbarcode.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/barcode/mkbarcode.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/barcode/mkbarcode.php	(revision 266)
@@ -0,0 +1,281 @@
+<?php
+require_once('jpgraph/jpgraph_barcode.php');
+
+/*=======================================================================
+ // File:        MKBARCODE.PHP
+ // Description: Comman line tool to generate linear barcodes
+ // Created:     2009-06-20
+ // Ver:         $Id: mkbarcode.php 1455 2009-07-03 18:52:25Z ljp $
+ //
+ // Copyright (c) Asial Corporation. All rights reserved.
+ //=======================================================================
+ */
+
+//----------------------------------------------------------------------
+// CLASS ParseArgs
+// Parse command line arguments and make sanity checks
+//----------------------------------------------------------------------
+class ParseArgs {
+    var $argc,$argv;
+
+    function ParseArgs() {
+        // Get command line argument
+        $this->argv = ($_SERVER['argv']);
+        $this->argc = ($_SERVER['argc']);
+    }
+
+    function PrintUsage() {
+    	$n = $this->argv[0];
+        echo "$n -b <symbology> [-r -h -c -o <output format> -m <width> -s <scale> -y <height> -f <filename> ] datastring \n".
+            "Create the specified barcode\n".
+            "-b           What symbology to use, one of the following strings (case insensitive)\n".
+            "             UPCA \n".
+            "             UPCE \n".
+            "             EAN128 \n".
+            "             EAN13 \n".
+            "             EAN8 \n".
+            "             CODE11 \n".
+            "             CODE39 \n".
+            "             CODE128 \n".
+            "             CODE25 \n".
+            "             CODEI25 \n".
+            "             CODABAR \n".
+            "             BOOKLAND \n".
+            "-c           Add checkdigit for symbologies where this is optional\n".
+            "-o           Output format. 0=Image, 1=PS, 2=EPS\n".
+            "-m           Module width\n".
+            "-s           Scale factor\n".
+            "-h           Show this help\n".
+			"-f           Filename to write to\n".
+        	"-r           Rotate barcode 90 degrees\n".
+        	"-y height    Set height in pixels\n".
+            "-x           Hide the human readable text\n".
+        	"--silent     Silent. Don't give any error mesages\n";
+        exit(1);
+    }
+
+    function Get() {
+        $barcode='code39';
+        $hide=false;
+        $checkdigit=false;
+        $modulewidth=2;
+        $scale=1;
+        $output=0;
+        $filename='';
+        $data = '';
+        $rotate = false;
+        $silent=false;
+        $height = 70;
+        if( ($n=$this->GetNum()) > 0 ) {
+            $i=1;
+            while( $i <= $n ) {
+                switch( $this->argv[$i] ) {
+                    case '-h':
+                        $this->PrintUsage();
+                        exit(0);
+                        break;
+                    case '-b':
+                        $barcode = $this->argv[++$i];
+                        break;
+                    case '-o':
+                        $output = (int)$this->argv[++$i];
+                        break;
+                    case '-y':
+                        $height = (int)$this->argv[++$i];
+                        break;
+					case '-x':
+                        $hide=true;
+                        break;
+                    case '-r':
+                        $rotate=true;
+                        break;
+                    case '-c':
+                        $checkdigit=true;
+                        break;
+                    case '--silent':
+                        $silent=true;
+                        break;
+                    case '-s':
+                        $scale = (float)$this->argv[++$i];
+                        break;
+                    case '-m':
+                        $modulewidth = (float)$this->argv[++$i];
+                        break;
+                    case '-f':
+                        $filename = $this->argv[++$i];
+                        break;
+                    default:
+                    	if( $data == '' ) {
+                        	$data = $this->argv[$i];
+                    	}
+                    	else {
+  							$this->PrintUsage();
+  							die("Illegal specified parameters");
+                    	}
+                        break;
+                }
+                ++$i;
+            }
+
+        }
+
+        if( $output < 0 || $output > 2 ) {
+        	fwrite(STDERR,"Unkown output format ($output)\n");
+        	exit(1);
+        }
+
+        if( $output === 0  ) {
+        	$modulewidth = floor($modulewidth);
+        }
+
+        // Sanity check
+        if( $modulewidth > 15 ) {
+        	fwrite(STDERR,"Too large modulewidth\n");
+        	exit(1);
+        }
+
+        // Sanity check
+        if( $height > 1000 ) {
+        	fwrite(STDERR,"Too large height\n");
+        	exit(1);
+        }
+
+		// Sanity check
+        if( $scale > 15 ) {
+        	fwrite(STDERR,"Too large scale factor\n");
+        	exit(1);
+        }
+
+        if( strlen($filename) > 256 ) {
+        	fwrite(STDERR,"Too long filename\n");
+        	exit(1);
+        }
+
+        if( trim($data) == '' ) {
+			fwrite(STDERR,"No input data specified\n");
+			exit(1);
+        }
+
+        $barcodes = array(
+            'UPCA' => ENCODING_UPCA,
+            'UPCE' => ENCODING_UPCE,
+            'EAN128' => ENCODING_EAN128,
+            'EAN13' => ENCODING_EAN13,
+            'EAN8' => ENCODING_EAN8,
+            'CODE11' => ENCODING_CODE11,
+            'CODE39' => ENCODING_CODE39,
+            'CODE128' => ENCODING_CODE128,
+            'CODE25' => ENCODING_CODE25,
+            'CODEI25' => ENCODING_CODEI25,
+            'CODABAR' => ENCODING_CODABAR,
+            'BOOKLAND' => ENCODING_BOOKLAND,
+        );
+        $barcode = strtoupper($barcode);
+        if( key_exists($barcode,$barcodes) ) {
+        	$barcode = $barcodes[$barcode];
+        }
+        else {
+        	fwrite(STDERR,'Specified barcode symbology ('.$barcode.") is not supported\n");
+        	exit(1);
+        }
+
+		$ret = array(
+				'barcode'     => $barcode,
+		        'hide' 	      => $hide,
+		        'modulewidth' => $modulewidth,
+		        'scale'       => $scale,
+		        'output'      => $output,
+		        'data'        => $data,
+		        'silent'      => $silent,
+		        'rotate'      => $rotate,
+		        'height'      => $height,
+				'checkdigit'  => $checkdigit,
+		        'filename'    => $filename
+			);
+
+		return $ret;
+    }
+
+    function _Dump() {
+        var_dump($this->argv);
+    }
+
+    function GetNum() {
+        return $this->argc-1;
+    }
+}
+
+//----------------------------------------------------------------------
+// CLASS Driver
+// Main driver class to create barcodes with the parmeters specified on
+// the command line.
+//----------------------------------------------------------------------
+class Driver {
+
+	private $iParams;
+	static public $silent=false;
+
+	static public function ErrHandlerPS(Exception $e) {
+		if( !Driver::$silent )
+			fwrite(STDERR,$e->getMessage()."\n");
+        exit(1);
+	}
+
+	static public function ErrHandlerImg(Exception $e) {
+		if( !Driver::$silent )
+			fwrite(STDERR,$e->getMessage()."\n");
+        $errobj = new JpGraphErrObjectImg();
+        $errobj->Raise($e->getMessage());
+        exit(1);
+	}
+
+	function Run($aParams) {
+
+		$this->iParams = $aParams;
+
+		Driver::$silent = $aParams['silent'];
+
+		$encoder = BarcodeFactory::Create($aParams['barcode']);
+		$encoder->AddChecksum($aParams['checkdigit']);
+		switch( $aParams['output'] ) {
+			case 0:
+				$e = BackendFactory::Create(BACKEND_IMAGE,$encoder);
+				set_exception_handler(array('Driver','ErrHandlerImg'));
+				break;
+			case 1:
+				$e = BackendFactory::Create(BACKEND_PS,$encoder);
+				set_exception_handler(array('Driver','ErrHandlerPS'));
+				break;
+			case 2:
+				$e = BackendFactory::Create(BACKEND_PS,$encoder);
+				$e->SetEPS();
+				set_exception_handler(array('Driver','ErrHandlerPS'));
+				break;
+		}
+		$e->SetHeight($aParams['height']);
+		$e->SetVertical($aParams['rotate']);
+		$e->SetModuleWidth($aParams['modulewidth']);
+		$e->SetScale($aParams['scale']);
+		$e->HideText($aParams['hide']);
+		if( $aParams['output'] === 0 ) {
+			$err = $e->Stroke($aParams['data'], $aParams['filename']);
+		}
+		else {
+			$s = $e->Stroke($aParams['data'], $aParams['filename']);
+			if( $aParams['filename'] == '' ) {
+				// If no filename specified then return the generated postscript
+				echo $s;
+			}
+		}
+	}
+}
+
+$pa = new ParseArgs();
+$params = $pa->Get();
+$driver = new Driver();
+$driver->Run($params);
+
+// Successfull termination
+exit(0);
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/flag_mapping
===================================================================
--- /trunk/client/modules/Elezioni/grafici/flag_mapping	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/flag_mapping	(revision 266)
@@ -0,0 +1,237 @@
+class JpCountryFlags {
+
+$iCountryFlags = array(
+    'Afghanistan' => 'afgh.gif',
+    'Republic of Angola' => 'agla.gif',
+    'Republic of Albania' => 'alba.gif',
+    'Alderney' => 'alde.gif',
+    'Democratic and Popular Republic of Algeria' => 'alge.gif',
+    'Territory of American Samoa' => 'amsa.gif',
+    'Principality of Andorra' => 'andr.gif',
+    'British Overseas Territory of Anguilla' => 'angu.gif',
+    'Antarctica' => 'anta.gif',
+    'Argentine Republic' => 'arge.gif',
+    'League of Arab States' => 'arle.gif',
+    'Republic of Armenia' => 'arme.gif',
+    'Aruba' => 'arub.gif',
+    'Commonwealth of Australia' => 'astl.gif',
+    'Republic of Austria' => 'aust.gif',
+    'Azerbaijani Republic' => 'azer.gif',
+    'British Antarctic Territory' => 'bant.gif',
+    'Kingdom of Belgium' => 'belg.gif',
+    'British Overseas Territory of Bermuda' => 'berm.gif',
+    'Commonwealth of the Bahamas' => 'bhms.gif',
+    'Kingdom of Bahrain' => 'bhrn.gif',
+    'Republic of Belarus' => 'blru.gif',
+    'Republic of Bolivia' => 'blva.gif',
+    'Belize' => 'blze.gif',
+    'Republic of Benin' => 'bnin.gif',
+    'Republic of Botswana' => 'bots.gif',
+    'Federative Republic of Brazil' => 'braz.gif',
+    'Barbados' => 'brbd.gif',
+    'British Indian Ocean Territory' => 'brin.gif',
+    'Brunei Darussalam' => 'brun.gif',
+    'Republic of Burkina' => 'bufa.gif',
+    'Republic of Bulgaria' => 'bulg.gif',
+    'Republic of Burundi' => 'buru.gif',
+    'Overseas Territory of the British Virgin Islands' => 'bvis.gif',
+    'Central African Republic' => 'cafr.gif',
+    'Kingdom of Cambodia' => 'camb.gif',
+    'Republic of Cameroon' => 'came.gif',
+    'Dominion of Canada' => 'cana.gif',
+    'Caribbean Community' => 'cari.gif',
+    'Republic of Cape Verde' => 'cave.gif',
+    'Republic of Chad' => 'chad.gif',
+    'Republic of Chile' => 'chil.gif',
+    'Territory of Christmas Island' => 'chms.gif',
+    'Commonwealth of Independent States' => 'cins.gif',
+    'Cook Islands' => 'ckis.gif',
+    'Republic of Colombia' => 'clmb.gif',
+    'Territory of Cocos Islands' => 'cois.gif',
+    'Commonwealth' => 'comn.gif',
+    'Union of the Comoros' => 'como.gif',
+    'Republic of the Congo' => 'cong.gif',
+    'Republic of Costa Rica' => 'corc.gif',
+    'Republic of Croatia' => 'croa.gif',
+    'Republic of Cuba' => 'cuba.gif',
+    'British Overseas Territory of the Cayman Islands' => 'cyis.gif',
+    'Republic of Cyprus' => 'cypr.gif',
+    'The Czech Republic' => 'czec.gif',
+    'Kingdom of Denmark' => 'denm.gif',
+    'Republic of Djibouti' => 'djib.gif',
+    'Commonwealth of Dominica' => 'domn.gif',
+    'Dominican Republic' => 'dore.gif',
+    'Republic of Ecuador' => 'ecua.gif',
+    'Arab Republic of Egypt' => 'egyp.gif',
+    'Republic of El Salvador' => 'elsa.gif',
+    'England' => 'engl.gif',
+    'Republic of Equatorial Guinea' => 'eqgu.gif',
+    'State of Eritrea' => 'erit.gif',
+    'Republic of Estonia' => 'estn.gif',
+    'Ethiopia' => 'ethp.gif',
+    'European Union' => 'euun.gif',
+    'British Overseas Territory of the Falkland Islands' => 'fais.gif',
+    'International Federation of Vexillological Associations' => 'fiav.gif',
+    'Republic of Fiji' => 'fiji.gif',
+    'Republic of Finland' => 'finl.gif',
+    'Territory of French Polynesia' => 'fpol.gif',
+    'French Republic' => 'fran.gif',
+    'Overseas Department of French Guiana' => 'frgu.gif',
+    'Gabonese Republic' => 'gabn.gif',
+    'Republic of the Gambia' => 'gamb.gif',
+    'Republic of Georgia' => 'geor.gif',
+    'Federal Republic of Germany' => 'germ.gif',
+    'Republic of Ghana' => 'ghan.gif',
+    'Gibraltar' => 'gibr.gif',
+    'Hellenic Republic' => 'grec.gif',
+    'State of Grenada' => 'gren.gif',
+    'Overseas Department of Guadeloupe' => 'guad.gif',
+    'Territory of Guam' => 'guam.gif',
+    'Republic of Guatemala' => 'guat.gif',
+    'The Bailiwick of Guernsey' => 'guer.gif',
+    'Republic of Guinea' => 'guin.gif',
+    'Republic of Haiti' => 'hait.gif',
+    'Hong Kong Special Administrative Region' => 'hokn.gif',
+    'Republic of Honduras' => 'hond.gif',
+    'Republic of Hungary' => 'hung.gif',
+    'Republic of Iceland' => 'icel.gif',
+    'International Committee of the Red Cross' => 'icrc.gif',
+    'Republic of India' => 'inda.gif',
+    'Republic of Indonesia' => 'indn.gif',
+    'Republic of Iraq' => 'iraq.gif',
+    'Republic of Ireland' => 'irel.gif',
+    'Organization of the Islamic Conference' => 'isco.gif',
+    'Isle of Man' => 'isma.gif',
+    'State of Israel' => 'isra.gif',
+    'Italian Republic' => 'ital.gif',
+    'Jamaica' => 'jama.gif',
+    'Japan' => 'japa.gif',
+    'The Bailiwick of Jersey' => 'jers.gif',
+    'Hashemite Kingdom of Jordan' => 'jord.gif',
+    'Republic of Kazakhstan' => 'kazk.gif',
+    'Republic of Kenya' => 'keny.gif',
+    'Republic of Kiribati' => 'kirb.gif',
+    'State of Kuwait' => 'kuwa.gif',
+    'Kyrgyz Republic' => 'kyrg.gif',
+    'Republic of Latvia' => 'latv.gif',
+    'Lebanese Republic' => 'leba.gif',
+    'Kingdom of Lesotho' => 'lest.gif',
+    'Republic of Liberia' => 'libe.gif',
+    'Principality of Liechtenstein' => 'liec.gif',
+    'Republic of Lithuania' => 'lith.gif',
+    'Grand Duchy of Luxembourg' => 'luxe.gif',
+    'Macao Special Administrative Region' => 'maca.gif',
+    'Republic of Macedonia' => 'mace.gif',
+    'Republic of Madagascar' => 'mada.gif',
+    'Republic of the Marshall Islands' => 'mais.gif',
+    'Republic of Maldives' => 'mald.gif',
+    'Republic of Mali' => 'mali.gif',
+    'Federation of Malaysia' => 'mals018.gif',
+    'Republic of Malta' => 'malt.gif',
+    'Republic of Malawi' => 'malw.gif',
+    'Overseas Department of Martinique' => 'mart.gif',
+    'Islamic Republic of Mauritania' => 'maur.gif',
+    'Territorial Collectivity of Mayotte' => 'mayt.gif',
+    'United Mexican States' => 'mexc.gif',
+    'Federated States of Micronesia' => 'micr.gif',
+    'Midway Islands' => 'miis.gif',
+    'Republic of Moldova' => 'mold.gif',
+    'Principality of Monaco' => 'mona.gif',
+    'Republic of Mongolia' => 'mong.gif',
+    'British Overseas Territory of Montserrat' => 'mont.gif',
+    'Kingdom of Morocco' => 'morc.gif',
+    'Republic of Mozambique' => 'moza.gif',
+    'Republic of Mauritius' => 'mrts.gif',
+    'Union of Myanmar' => 'myan.gif',
+    'Republic of Namibia' => 'namb.gif',
+    'North Atlantic Treaty Organization' => 'nato.gif',
+    'Republic of Nauru' => 'naur.gif',
+    'Turkish Republic of Northern Cyprus' => 'ncyp.gif',
+    'Netherlands Antilles' => 'nean.gif',
+    'Kingdom of Nepal' => 'nepa.gif',
+    'Kingdom of the Netherlands' => 'neth.gif',
+    'Territory of Norfolk Island' => 'nfis.gif',
+    'Federal Republic of Nigeria' => 'ngra.gif',
+    'Republic of Nicaragua' => 'nica.gif',
+    'Republic of Niger' => 'nigr.gif',
+    'Niue' => 'niue.gif',
+    'Commonwealth of the Northern Mariana Islands' => 'nmar.gif',
+    'Province of Northern Ireland' => 'noir.gif',
+    'Nordic Council' => 'nord.gif',
+    'Kingdom of Norway' => 'norw.gif',
+    'Territory of New Caledonia and Dependencies' => 'nwca.gif',
+    'New Zealand' => 'nwze.gif',
+    'Organization of American States' => 'oast.gif',
+    'Organization of African Unity' => 'oaun.gif',
+    'International Olympic Committee' => 'olym.gif',
+    'Sultanate of Oman' => 'oman.gif',
+    'Organization of Petroleum Exporting Countries' => 'opec.gif',
+    'Islamic Republic of Pakistan' => 'paks.gif',
+    'Republic of Palau' => 'pala.gif',
+    'Independent State of Papua New Guinea' => 'pang.gif',
+    'Republic of Paraguay' => 'para.gif',
+    'Republic of the Philippines' => 'phil.gif',
+    'British Overseas Territory of the Pitcairn Islands' => 'piis.gif',
+    'Republic of Poland' => 'pola.gif',
+    'Republic of Portugal' => 'port.gif',
+    'Commonwealth of Puerto Rico' => 'purc.gif',
+    'State of Qatar' => 'qata.gif',
+    'Russian Federation' => 'russ.gif',
+    'Republic of Rwanda' => 'rwan.gif',
+    'Kingdom of Saudi Arabia' => 'saar.gif',
+    'Republic of San Marino' => 'sama.gif',
+    'Nordic Sami Conference' => 'sami.gif',
+    'Sark' => 'sark.gif',
+    'Scotland' => 'scot.gif',
+    'Principality of Seborga' => 'sebo.gif',
+    'Republic of Sierra Leone' => 'sile.gif',
+    'Republic of Singapore' => 'sing.gif',
+    'Republic of Korea' => 'skor.gif',
+    'Republic of Slovenia' => 'slva.gif',
+    'Somali Republic' => 'smla.gif',
+    'Republic of Somaliland' => 'smld.gif',
+    'Republic of South Africa' => 'soaf.gif',
+    'Solomon Islands' => 'sois.gif',
+    'Kingdom of Spain' => 'span.gif',
+    'Secretariat of the Pacific Community' => 'spco.gif',
+    'Democratic Socialist Republic of Sri Lanka' => 'srla.gif',
+    'Saint Lucia' => 'stlu.gif',
+    'Republic of the Sudan' => 'suda.gif',
+    'Republic of Suriname' => 'surn.gif',
+    'Slovak Republic' => 'svka.gif',
+    'Kingdom of Sweden' => 'swdn.gif',
+    'Swiss Confederation' => 'swit.gif',
+    'Syrian Arab Republic' => 'syra.gif',
+    'Kingdom of Swaziland' => 'szld.gif',
+    'Republic of China' => 'taiw.gif',
+    'Republic of Tajikistan' => 'tajk.gif',
+    'United Republic of Tanzania' => 'tanz.gif',
+    'Kingdom of Thailand' => 'thal.gif',
+    'Autonomous Region of Tibet' => 'tibe.gif',
+    'Turkmenistan' => 'tkst.gif',
+    'Togolese Republic' => 'togo.gif',
+    'Tokelau' => 'toke.gif',
+    'Kingdom of Tonga' => 'tong.gif',
+    'Tristan da Cunha' => 'trdc.gif',
+    'Tromelin' => 'tris.gif',
+    'Republic of Tunisia' => 'tuns.gif',
+    'Republic of Turkey' => 'turk.gif',
+    'Tuvalu' => 'tuva.gif',
+    'United Arab Emirates' => 'uaem.gif',
+    'Republic of Uganda' => 'ugan.gif',
+    'Ukraine' => 'ukrn.gif',
+    'United Kingdom of Great Britain' => 'unkg.gif',
+    'United Nations' => 'unna.gif',
+    'United States of America' => 'unst.gif',
+    'Oriental Republic of Uruguay' => 'urgy.gif',
+    'Virgin Islands of the United States' => 'usvs.gif',
+    'Republic of Uzbekistan' => 'uzbk.gif',
+    'State of the Vatican City' => 'vacy.gif',
+    'Republic of Vanuatu' => 'vant.gif',
+    'Bolivarian Republic of Venezuela' => 'venz.gif',
+    'Republic of Yemen' => 'yemn.gif',
+    'Democratic Republic of Congo' => 'zare.gif',
+    'Republic of Zimbabwe' => 'zbwe.gif' 
+) ;
+
+
Index: /trunk/client/modules/Elezioni/grafici/imageSmoothArc.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/imageSmoothArc.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/imageSmoothArc.php	(revision 266)
@@ -0,0 +1,344 @@
+<?php
+
+/*
+    
+    Copyright (c) 2006-2008 Ulrich Mierendorff
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+    
+    Changelog:
+    version 1.1
+        - improved the rendering speed by ~20%
+        
+        - Thanks to Matthias MÃ€chler for fixing some small errors:
+            * uninitialized variables
+            * deprecated passing of $img reference in imageSmoothArc ()
+    
+    version 1.0
+        Release of rewritten script
+
+*/
+
+function imageSmoothArcDrawSegment (&$img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $start, $stop, $seg)
+{
+    // Originally written from scratch by Ulrich Mierendorff, 06/2006
+    // Rewritten and improved, 04/2007, 07/2007
+    
+    // Please do not use THIS function directly. Scroll down to imageSmoothArc(...).
+    
+    $fillColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], $color[3] );
+    
+    $xStart = abs($a * cos($start));
+    $yStart = abs($b * sin($start));
+    $xStop  = abs($a * cos($stop));
+    $yStop  = abs($b * sin($stop));
+    $dxStart = 0;
+    $dyStart = 0;
+    $dxStop = 0;
+    $dyStop = 0;
+    if ($xStart != 0)
+        $dyStart = $yStart/$xStart;
+    if ($xStop != 0)
+        $dyStop = $yStop/$xStop;
+    if ($yStart != 0)
+        $dxStart = $xStart/$yStart;
+    if ($yStop != 0)
+        $dxStop = $xStop/$yStop;
+    if (abs($xStart) >= abs($yStart)) {
+        $aaStartX = true;
+    } else {
+        $aaStartX = false;
+    }
+    if ($xStop >= $yStop) {
+        $aaStopX = true;
+    } else {
+        $aaStopX = false;
+    }
+    //$xp = +1; $yp = -1; $xa = +1; $ya = 0;
+    for ( $x = 0; $x < $a; $x += 1 ) {
+        /*$y = $b * sqrt( 1 - ($x*$x)/($a*$a) );
+        
+        $error = $y - (int)($y);
+        $y = (int)($y);
+        
+        $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );*/
+        
+        $_y1 = $dyStop*$x;
+        $_y2 = $dyStart*$x;
+        if ($xStart > $xStop)
+        {
+            $error1 = $_y1 - (int)($_y1);
+            $error2 = 1 - $_y2 + (int)$_y2;
+            $_y1 = $_y1-$error1;
+            $_y2 = $_y2+$error2;
+        }
+        else
+        {
+            $error1 = 1 - $_y1 + (int)$_y1;
+            $error2 = $_y2 - (int)($_y2);
+            $_y1 = $_y1+$error1;
+            $_y2 = $_y2-$error2;
+        }
+        /*
+        if ($aaStopX)
+            $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
+        if ($aaStartX)
+            $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
+        */
+        
+        if ($seg == 0 || $seg == 2)
+        {
+            $i = $seg;
+            if (!($start > $i*M_PI/2 && $x > $xStart)) {
+                if ($i == 0) {
+                    $xp = +1; $yp = -1; $xa = +1; $ya = 0;
+                } else {
+                    $xp = -1; $yp = +1; $xa = 0; $ya = +1;
+                }
+                if ( $stop < ($i+1)*(M_PI/2) && $x <= $xStop ) {
+                    $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
+                    $y1 = $_y1; if ($aaStopX) imageSetPixel($img, $cx+$xp*($x)+$xa, $cy+$yp*($y1+1)+$ya, $diffColor1);
+                    
+                } else {
+                    $y = $b * sqrt( 1 - ($x*$x)/($a*$a) );
+                    $error = $y - (int)($y);
+                    $y = (int)($y);
+                    $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );
+                    $y1 = $y; if ($x < $aaAngleX ) imageSetPixel($img, $cx+$xp*$x+$xa, $cy+$yp*($y1+1)+$ya, $diffColor);
+                }
+                if ($start > $i*M_PI/2 && $x <= $xStart) {
+                    $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
+                    $y2 = $_y2; if ($aaStartX) imageSetPixel($img, $cx+$xp*$x+$xa, $cy+$yp*($y2-1)+$ya, $diffColor2);
+                } else {
+                    $y2 = 0;
+                }
+                if ($y2 <= $y1) imageLine($img, $cx+$xp*$x+$xa, $cy+$yp*$y1+$ya , $cx+$xp*$x+$xa, $cy+$yp*$y2+$ya, $fillColor);
+            }
+        }
+        
+        if ($seg == 1 || $seg == 3)
+        {
+            $i = $seg;
+            if (!($stop < ($i+1)*M_PI/2 && $x > $xStop)) {
+                if ($i == 1) {
+                    $xp = -1; $yp = -1; $xa = 0; $ya = 0;
+                } else {
+                    $xp = +1; $yp = +1; $xa = 1; $ya = 1;
+                }
+                if ( $start > $i*M_PI/2 && $x < $xStart ) {
+                    $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
+                    $y1 = $_y2; if ($aaStartX) imageSetPixel($img, $cx+$xp*$x+$xa, $cy+$yp*($y1+1)+$ya, $diffColor2);
+                    
+                } else {
+                    $y = $b * sqrt( 1 - ($x*$x)/($a*$a) );
+                    $error = $y - (int)($y);
+                    $y = (int) $y;
+                    $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );
+                    $y1 = $y; if ($x < $aaAngleX ) imageSetPixel($img, $cx+$xp*$x+$xa, $cy+$yp*($y1+1)+$ya, $diffColor);
+                }
+                if ($stop < ($i+1)*M_PI/2 && $x <= $xStop) {
+                    $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
+                    $y2 = $_y1; if ($aaStopX)  imageSetPixel($img, $cx+$xp*$x+$xa, $cy+$yp*($y2-1)+$ya, $diffColor1);
+                } else {
+                    $y2 = 0;
+                }
+                if ($y2 <= $y1) imageLine($img, $cx+$xp*$x+$xa, $cy+$yp*$y1+$ya, $cx+$xp*$x+$xa, $cy+$yp*$y2+$ya, $fillColor);
+            }
+        }
+    }
+    
+    ///YYYYY
+    
+    for ( $y = 0; $y < $b; $y += 1 ) {
+        /*$x = $a * sqrt( 1 - ($y*$y)/($b*$b) );
+        
+        $error = $x - (int)($x);
+        $x = (int)($x);
+        
+        $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );
+        */
+        $_x1 = $dxStop*$y;
+        $_x2 = $dxStart*$y;
+        if ($yStart > $yStop)
+        {
+            $error1 = $_x1 - (int)($_x1);
+            $error2 = 1 - $_x2 + (int)$_x2;
+            $_x1 = $_x1-$error1;
+            $_x2 = $_x2+$error2;
+        }
+        else
+        {
+            $error1 = 1 - $_x1 + (int)$_x1;
+            $error2 = $_x2 - (int)($_x2);
+            $_x1 = $_x1+$error1;
+            $_x2 = $_x2-$error2;
+        }
+/*
+        if (!$aaStopX)
+            $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
+        if (!$aaStartX)
+            $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
+*/
+        
+        if ($seg == 0 || $seg == 2)
+        {
+            $i = $seg;
+            if (!($start > $i*M_PI/2 && $y > $yStop)) {
+                if ($i == 0) {
+                    $xp = +1; $yp = -1; $xa = 1; $ya = 0;
+                } else {
+                    $xp = -1; $yp = +1; $xa = 0; $ya = 1;
+                }
+                if ( $stop < ($i+1)*(M_PI/2) && $y <= $yStop ) {
+                    $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
+                    $x1 = $_x1; if (!$aaStopX) imageSetPixel($img, $cx+$xp*($x1-1)+$xa, $cy+$yp*($y)+$ya, $diffColor1);
+                } 
+                if ($start > $i*M_PI/2 && $y < $yStart) {
+                    $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
+                    $x2 = $_x2; if (!$aaStartX) imageSetPixel($img, $cx+$xp*($x2+1)+$xa, $cy+$yp*($y)+$ya, $diffColor2);
+                } else {
+                    $x = $a * sqrt( 1 - ($y*$y)/($b*$b) );
+                    $error = $x - (int)($x);
+                    $x = (int)($x);
+                    $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );
+                    $x1 = $x; if ($y < $aaAngleY && $y <= $yStop ) imageSetPixel($img, $cx+$xp*($x1+1)+$xa, $cy+$yp*$y+$ya, $diffColor);
+                }
+            }
+        }
+        
+        if ($seg == 1 || $seg == 3)
+        {
+            $i = $seg;
+            if (!($stop < ($i+1)*M_PI/2 && $y > $yStart)) {
+                if ($i == 1) {
+                    $xp = -1; $yp = -1; $xa = 0; $ya = 0;
+                } else {
+                    $xp = +1; $yp = +1; $xa = 1; $ya = 1;
+                }
+                if ( $start > $i*M_PI/2 && $y < $yStart ) {
+                    $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
+                    $x1 = $_x2; if (!$aaStartX) imageSetPixel($img, $cx+$xp*($x1-1)+$xa, $cy+$yp*$y+$ya,  $diffColor2);
+                } 
+                if ($stop < ($i+1)*M_PI/2 && $y <= $yStop) {
+                    $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
+                    $x2 = $_x1; if (!$aaStopX)  imageSetPixel($img, $cx+$xp*($x2+1)+$xa, $cy+$yp*$y+$ya, $diffColor1);
+                } else {
+                    $x = $a * sqrt( 1 - ($y*$y)/($b*$b) );
+                    $error = $x - (int)($x);
+                    $x = (int)($x);
+                    $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );
+                    $x1 = $x; if ($y < $aaAngleY  && $y < $yStart) imageSetPixel($img,$cx+$xp*($x1+1)+$xa,  $cy+$yp*$y+$ya, $diffColor);
+                }
+            }
+        }
+    }
+}
+
+
+function imageSmoothArc ( &$img, $cx, $cy, $w, $h, $color, $start, $stop)
+{
+    // Originally written from scratch by Ulrich Mierendorff, 06/2006
+    // Rewritten and improved, 04/2007, 07/2007
+    // compared to old version:
+    // + Support for transparency added
+    // + Improved quality of edges & antialiasing
+    
+    // note: This function does not represent the fastest way to draw elliptical
+    // arcs. It was written without reading any papers on that subject. Better
+    // algorithms may be twice as fast or even more.
+    
+    // what it cannot do: It does not support outlined arcs, only filled
+    
+    // Parameters:
+    // $cx      - Center of ellipse, X-coord
+    // $cy      - Center of ellipse, Y-coord
+    // $w       - Width of ellipse ($w >= 2)
+    // $h       - Height of ellipse ($h >= 2 )
+    // $color   - Color of ellipse as a four component array with RGBA
+    // $start   - Starting angle of the arc, no limited range!
+    // $stop    - Stop     angle of the arc, no limited range!
+    // $start _can_ be greater than $stop!
+    // If any value is not in the given range, results are undefined!
+    
+    // This script does not use any special algorithms, everything is completely
+    // written from scratch; see http://de.wikipedia.org/wiki/Ellipse for formulas.
+    
+    while ($start < 0)
+        $start += 2*M_PI;
+    while ($stop < 0)
+        $stop += 2*M_PI;
+    
+    while ($start > 2*M_PI)
+        $start -= 2*M_PI;
+    
+    while ($stop > 2*M_PI)
+        $stop -= 2*M_PI;
+    
+    
+    if ($start > $stop)
+    {
+        imageSmoothArc ( $img, $cx, $cy, $w, $h, $color, $start, 2*M_PI);
+        imageSmoothArc ( $img, $cx, $cy, $w, $h, $color, 0, $stop);
+        return;
+    }
+    
+    $a = 1.0*round ($w/2);
+    $b = 1.0*round ($h/2);
+    $cx = 1.0*round ($cx);
+    $cy = 1.0*round ($cy);
+    
+    $aaAngle = atan(($b*$b)/($a*$a)*tan(0.25*M_PI));
+    $aaAngleX = $a*cos($aaAngle);
+    $aaAngleY = $b*sin($aaAngle);
+    
+    $a -= 0.5; // looks better...
+    $b -= 0.5;
+    
+    for ($i=0; $i<4;$i++)
+    {
+        if ($start < ($i+1)*M_PI/2)
+        {
+            if ($start > $i*M_PI/2)
+            {
+                if ($stop > ($i+1)*M_PI/2)
+                {
+                    imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY , $color, $start, ($i+1)*M_PI/2, $i);
+                }
+                else
+                {
+                    imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $start, $stop, $i);
+                    break;
+                }
+            }
+            else
+            {
+                if ($stop > ($i+1)*M_PI/2)
+                {
+                    imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $i*M_PI/2, ($i+1)*M_PI/2, $i);
+                }
+                else
+                {
+                    imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $i*M_PI/2, $stop, $i);
+                    break;
+                }
+            }
+        }
+    }
+}
+?>
Index: /trunk/client/modules/Elezioni/grafici/jpgraph_contour.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/jpgraph_contour.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/jpgraph_contour.php	(revision 266)
@@ -0,0 +1,587 @@
+<?php
+/*=======================================================================
+// File:        JPGRAPH_CONTOUR.PHP
+// Description: Contour plot
+// Created:     2009-03-08
+// Ver:         $Id: jpgraph_contour.php 1870 2009-09-29 04:24:18Z ljp $
+//
+// Copyright (c) Asial Corporation. All rights reserved.
+//========================================================================
+*/
+require_once('jpgraph_meshinterpolate.inc.php');
+define('HORIZ_EDGE',0);
+define('VERT_EDGE',1);
+
+/**
+ * This class encapsulates the core contour plot algorithm. It will find the path
+ * of the specified isobars in the data matrix specified. It is assumed that the
+ * data matrix models an equspaced X-Y mesh of datavalues corresponding to the Z
+ * values.
+ *
+ */
+class Contour {
+
+    private $dataPoints = array();
+    private $nbrCols=0,$nbrRows=0;
+    private $horizEdges = array(), $vertEdges=array();
+    private $isobarValues = array();
+    private $stack = null;
+    private $isobarCoord = array();
+    private $nbrIsobars = 10, $isobarColors = array();
+    private $invert = true;
+    private $highcontrast = false, $highcontrastbw = false;
+
+    /**
+     * Create a new contour level "algorithm machine".
+     * @param $aMatrix    The values to find the contour from
+     * @param $aIsobars Mixed. If integer it determines the number of isobars to be used. The levels are determined
+     * automatically as equdistance between the min and max value of the matrice.
+     * If $aIsobars is an array then this is interpretated as an array of values to be used as isobars in the
+     * contour plot.
+     * @return an instance of the contour algorithm
+     */
+    function __construct($aMatrix,$aIsobars=10, $aColors=null) {
+
+        $this->nbrRows = count($aMatrix);
+        $this->nbrCols = count($aMatrix[0]);
+        $this->dataPoints = $aMatrix;
+
+        if( is_array($aIsobars) ) {
+            // use the isobar values supplied
+            $this->nbrIsobars = count($aIsobars);
+            $this->isobarValues = $aIsobars;
+        }
+        else {
+            // Determine the isobar values automatically
+            $this->nbrIsobars = $aIsobars;
+            list($min,$max) = $this->getMinMaxVal();
+            $stepSize = ($max-$min) / $aIsobars ;
+            $isobar = $min+$stepSize/2;
+            for ($i = 0; $i < $aIsobars; $i++) {
+                $this->isobarValues[$i] = $isobar;
+                $isobar += $stepSize;
+            }
+        }
+
+        if( $aColors !== null && count($aColors) > 0 ) {
+
+            if( !is_array($aColors) ) {
+                JpGraphError::RaiseL(28001);
+                //'Third argument to Contour must be an array of colors.'
+            }
+
+            if( count($aColors) != count($this->isobarValues) ) {
+                JpGraphError::RaiseL(28002);
+                //'Number of colors must equal the number of isobar lines specified';
+            }
+
+            $this->isobarColors = $aColors;
+        }
+    }
+
+    /**
+     * Flip the plot around the Y-coordinate. This has the same affect as flipping the input
+     * data matrice
+     *
+     * @param $aFlg If true the the vertice in input data matrice position (0,0) corresponds to the top left
+     * corner of teh plot otherwise it will correspond to the bottom left corner (a horizontal flip)
+     */
+    function SetInvert($aFlg=true) {
+        $this->invert = $aFlg;
+    }
+
+    /**
+     * Find the min and max values in the data matrice
+     *
+     * @return array(min_value,max_value)
+     */
+    function getMinMaxVal() {
+        $min = $this->dataPoints[0][0];
+        $max = $this->dataPoints[0][0];
+        for ($i = 0; $i < $this->nbrRows; $i++) {
+            if( ($mi=min($this->dataPoints[$i])) < $min )  $min = $mi;
+            if( ($ma=max($this->dataPoints[$i])) > $max )  $max = $ma;
+        }
+        return array($min,$max);
+    }
+
+    /**
+     * Reset the two matrices that keeps track on where the isobars crosses the
+     * horizontal and vertical edges
+     */
+    function resetEdgeMatrices() {
+        for ($k = 0; $k < 2; $k++) {
+            for ($i = 0; $i <= $this->nbrRows; $i++) {
+                for ($j = 0; $j <= $this->nbrCols; $j++) {
+                    $this->edges[$k][$i][$j] = false;
+                }
+            }
+        }
+    }
+
+    /**
+     * Determine if the specified isobar crosses the horizontal edge specified by its row and column
+     *
+     * @param $aRow Row index of edge to be checked
+     * @param $aCol Col index of edge to be checked
+     * @param $aIsobar Isobar value
+     * @return true if the isobar is crossing this edge
+     */
+    function isobarHCrossing($aRow,$aCol,$aIsobar) {
+
+        if( $aCol >= $this->nbrCols-1 ) {
+            JpGraphError::RaiseL(28003,$aCol);
+            //'ContourPlot Internal Error: isobarHCrossing: Coloumn index too large (%d)'
+        }
+        if( $aRow >= $this->nbrRows ) {
+            JpGraphError::RaiseL(28004,$aRow);
+            //'ContourPlot Internal Error: isobarHCrossing: Row index too large (%d)'
+        }
+
+        $v1 = $this->dataPoints[$aRow][$aCol];
+        $v2 = $this->dataPoints[$aRow][$aCol+1];
+
+        return ($aIsobar-$v1)*($aIsobar-$v2) < 0 ;
+
+    }
+
+    /**
+     * Determine if the specified isobar crosses the vertical edge specified by its row and column
+     *
+     * @param $aRow Row index of edge to be checked
+     * @param $aCol Col index of edge to be checked
+     * @param $aIsobar Isobar value
+     * @return true if the isobar is crossing this edge
+     */
+    function isobarVCrossing($aRow,$aCol,$aIsobar) {
+
+        if( $aRow >= $this->nbrRows-1) {
+            JpGraphError::RaiseL(28005,$aRow);
+            //'isobarVCrossing: Row index too large
+        }
+        if( $aCol >= $this->nbrCols ) {
+            JpGraphError::RaiseL(28006,$aCol);
+            //'isobarVCrossing: Col index too large
+        }
+
+        $v1 = $this->dataPoints[$aRow][$aCol];
+        $v2 = $this->dataPoints[$aRow+1][$aCol];
+
+        return ($aIsobar-$v1)*($aIsobar-$v2) < 0 ;
+
+    }
+
+    /**
+     * Determine all edges, horizontal and vertical that the specified isobar crosses. The crossings
+     * are recorded in the two edge matrices.
+     *
+     * @param $aIsobar The value of the isobar to be checked
+     */
+    function determineIsobarEdgeCrossings($aIsobar) {
+
+        $ib = $this->isobarValues[$aIsobar];
+
+        for ($i = 0; $i < $this->nbrRows-1; $i++) {
+            for ($j = 0; $j < $this->nbrCols-1; $j++) {
+                $this->edges[HORIZ_EDGE][$i][$j] = $this->isobarHCrossing($i,$j,$ib);
+                $this->edges[VERT_EDGE][$i][$j] = $this->isobarVCrossing($i,$j,$ib);
+            }
+        }
+
+        // We now have the bottom and rightmost edges unsearched
+        for ($i = 0; $i < $this->nbrRows-1; $i++) {
+            $this->edges[VERT_EDGE][$i][$j] = $this->isobarVCrossing($i,$this->nbrCols-1,$ib);
+        }
+        for ($j = 0; $j < $this->nbrCols-1; $j++) {
+            $this->edges[HORIZ_EDGE][$i][$j] = $this->isobarHCrossing($this->nbrRows-1,$j,$ib);
+        }
+
+    }
+
+    /**
+     * Return the normalized coordinates for the crossing of the specified edge with the specified
+     * isobar- The crossing is simpy detrmined with a linear interpolation between the two vertices
+     * on each side of the edge and the value of the isobar
+     *
+     * @param $aRow Row of edge
+     * @param $aCol Column of edge
+     * @param $aEdgeDir Determine if this is a horizontal or vertical edge
+     * @param $ib The isobar value
+     * @return unknown_type
+     */
+    function getCrossingCoord($aRow,$aCol,$aEdgeDir,$aIsobarVal) {
+
+        // In order to avoid numerical problem when two vertices are very close
+        // we have to check and avoid dividing by close to zero denumerator.
+        if( $aEdgeDir == HORIZ_EDGE ) {
+            $d = abs($this->dataPoints[$aRow][$aCol] - $this->dataPoints[$aRow][$aCol+1]);
+            if( $d > 0.001 ) {
+                $xcoord = $aCol + abs($aIsobarVal - $this->dataPoints[$aRow][$aCol]) / $d;
+            }
+            else {
+                $xcoord = $aCol;
+            }
+            $ycoord = $aRow;
+        }
+        else {
+            $d = abs($this->dataPoints[$aRow][$aCol] - $this->dataPoints[$aRow+1][$aCol]);
+            if( $d > 0.001 ) {
+                $ycoord = $aRow + abs($aIsobarVal - $this->dataPoints[$aRow][$aCol]) / $d;
+            }
+            else {
+                $ycoord = $aRow;
+            }
+            $xcoord = $aCol;
+        }
+        if( $this->invert ) {
+            $ycoord = $this->nbrRows-1 - $ycoord;
+        }
+        return array($xcoord,$ycoord);
+
+    }
+
+    /**
+     * In order to avoid all kinds of unpleasent extra checks and complex boundary
+     * controls for the degenerated case where the contour levels exactly crosses
+     * one of the vertices we add a very small delta (0.1%) to the data point value.
+     * This has no visible affect but it makes the code sooooo much cleaner.
+     *
+     */
+    function adjustDataPointValues() {
+
+        $ni = count($this->isobarValues);
+        for ($k = 0; $k < $ni; $k++) {
+            $ib = $this->isobarValues[$k];
+            for ($row = 0 ; $row < $this->nbrRows-1; ++$row) {
+                for ($col = 0 ; $col < $this->nbrCols-1; ++$col ) {
+                    if( abs($this->dataPoints[$row][$col] - $ib) < 0.0001 ) {
+                        $this->dataPoints[$row][$col] += $this->dataPoints[$row][$col]*0.001;
+                    }
+                }
+            }
+        }
+
+    }
+
+    /**
+     * @param $aFlg
+     * @param $aBW
+     * @return unknown_type
+     */
+    function UseHighContrastColor($aFlg=true,$aBW=false) {
+        $this->highcontrast = $aFlg;
+        $this->highcontrastbw = $aBW;
+    }
+
+    /**
+     * Calculate suitable colors for each defined isobar
+     *
+     */
+    function CalculateColors() {
+        if ( $this->highcontrast ) {
+            if ( $this->highcontrastbw ) {
+                for ($ib = 0; $ib < $this->nbrIsobars; $ib++) {
+                    $this->isobarColors[$ib] = 'black';
+                }
+            }
+            else {
+                // Use only blue/red scale
+                $step = round(255/($this->nbrIsobars-1));
+                for ($ib = 0; $ib < $this->nbrIsobars; $ib++) {
+                    $this->isobarColors[$ib] = array($ib*$step, 50, 255-$ib*$step);
+                }
+            }
+        }
+        else {
+            $n = $this->nbrIsobars;
+            $v = 0; $step = 1 / ($this->nbrIsobars-1);
+            for ($ib = 0; $ib < $this->nbrIsobars; $ib++) {
+                $this->isobarColors[$ib] = RGB::GetSpectrum($v);
+                $v += $step;
+            }
+        }
+    }
+
+    /**
+     * This is where the main work is done. For each isobar the crossing of the edges are determined
+     * and then each cell is analyzed to find the 0, 2 or 4 crossings. Then the normalized coordinate
+     * for the crossings are determined and pushed on to the isobar stack. When the method is finished
+     * the $isobarCoord will hold one arrayfor each isobar where all the line segments that makes
+     * up the contour plot are stored.
+     *
+     * @return array( $isobarCoord, $isobarValues, $isobarColors )
+     */
+    function getIsobars() {
+
+        $this->adjustDataPointValues();
+
+        for ($isobar = 0; $isobar < $this->nbrIsobars; $isobar++) {
+
+            $ib = $this->isobarValues[$isobar];
+            $this->resetEdgeMatrices();
+            $this->determineIsobarEdgeCrossings($isobar);
+            $this->isobarCoord[$isobar] = array();
+
+            $ncoord = 0;
+
+            for ($row = 0 ; $row < $this->nbrRows-1; ++$row) {
+                for ($col = 0 ; $col < $this->nbrCols-1; ++$col ) {
+
+                    // Find out how many crossings around the edges
+                    $n = 0;
+                    if ( $this->edges[HORIZ_EDGE][$row][$col] )   $neigh[$n++] = array($row,  $col,  HORIZ_EDGE);
+                    if ( $this->edges[HORIZ_EDGE][$row+1][$col] ) $neigh[$n++] = array($row+1,$col,  HORIZ_EDGE);
+                    if ( $this->edges[VERT_EDGE][$row][$col] )    $neigh[$n++] = array($row,  $col,  VERT_EDGE);
+                    if ( $this->edges[VERT_EDGE][$row][$col+1] )  $neigh[$n++] = array($row,  $col+1,VERT_EDGE);
+
+                    if ( $n == 2 ) {
+                        $n1=0; $n2=1;
+                        $this->isobarCoord[$isobar][$ncoord++] = array(
+                        $this->getCrossingCoord($neigh[$n1][0],$neigh[$n1][1],$neigh[$n1][2],$ib),
+                        $this->getCrossingCoord($neigh[$n2][0],$neigh[$n2][1],$neigh[$n2][2],$ib) );
+                    }
+                    elseif ( $n == 4 ) {
+                        // We must determine how to connect the edges either northwest->southeast or
+                        // northeast->southwest. We do that by calculating the imaginary middle value of
+                        // the cell by averaging the for corners. This will compared with the value of the
+                        // top left corner will help determine the orientation of the ridge/creek
+                        $midval = ($this->dataPoints[$row][$col]+$this->dataPoints[$row][$col+1]+$this->dataPoints[$row+1][$col]+$this->dataPoints[$row+1][$col+1])/4;
+                        $v = $this->dataPoints[$row][$col];
+                        if( $midval == $ib ) {
+                            // Orientation "+"
+                            $n1=0; $n2=1; $n3=2; $n4=3;
+                        } elseif ( ($midval > $ib && $v > $ib) ||  ($midval < $ib && $v < $ib) ) {
+                            // Orientation of ridge/valley = "\"
+                            $n1=0; $n2=3; $n3=2; $n4=1;
+                        } elseif ( ($midval > $ib && $v < $ib) ||  ($midval < $ib && $v > $ib) ) {
+                            // Orientation of ridge/valley = "/"
+                            $n1=0; $n2=2; $n3=3; $n4=1;
+                        }
+
+                        $this->isobarCoord[$isobar][$ncoord++] = array(
+                        $this->getCrossingCoord($neigh[$n1][0],$neigh[$n1][1],$neigh[$n1][2],$ib),
+                        $this->getCrossingCoord($neigh[$n2][0],$neigh[$n2][1],$neigh[$n2][2],$ib) );
+
+                        $this->isobarCoord[$isobar][$ncoord++] = array(
+                        $this->getCrossingCoord($neigh[$n3][0],$neigh[$n3][1],$neigh[$n3][2],$ib),
+                        $this->getCrossingCoord($neigh[$n4][0],$neigh[$n4][1],$neigh[$n4][2],$ib) );
+
+                    }
+                }
+            }
+        }
+
+        if( count($this->isobarColors) == 0 ) {
+            // No manually specified colors. Calculate them automatically.
+            $this->CalculateColors();
+        }
+        return array( $this->isobarCoord, $this->isobarValues, $this->isobarColors );
+    }
+}
+
+
+/**
+ * This class represent a plotting of a contour outline of data given as a X-Y matrice
+ *
+ */
+class ContourPlot extends Plot {
+
+    private $contour, $contourCoord, $contourVal, $contourColor;
+    private $nbrCountours = 0 ;
+    private $dataMatrix = array();
+    private $invertLegend = false;
+    private $interpFactor = 1;
+    private $flipData = false;
+    private $isobar = 10;
+    private $showLegend = false;
+    private $highcontrast = false, $highcontrastbw = false;
+    private $manualIsobarColors = array();
+
+    /**
+     * Construct a contour plotting algorithm. The end result of the algorithm is a sequence of
+     * line segments for each isobar given as two vertices.
+     *
+     * @param $aDataMatrix    The Z-data to be used
+     * @param $aIsobar A mixed variable, if it is an integer then this specified the number of isobars to use.
+     * The values of the isobars are automatically detrmined to be equ-spaced between the min/max value of the
+     * data. If it is an array then it explicetely gives the isobar values
+     * @param $aInvert By default the matrice with row index 0 corresponds to Y-value 0, i.e. in the bottom of
+     * the plot. If this argument is true then the row with the highest index in the matrice corresponds  to
+     * Y-value 0. In affect flipping the matrice around an imaginary horizontal axis.
+     * @param $aHighContrast Use high contrast colors (blue/red:ish)
+     * @param $aHighContrastBW Use only black colors for contours
+     * @return an instance of the contour plot algorithm
+     */
+    function __construct($aDataMatrix, $aIsobar=10, $aFactor=1, $aInvert=false, $aIsobarColors=array()) {
+
+        $this->dataMatrix = $aDataMatrix;
+        $this->flipData = $aInvert;
+        $this->isobar = $aIsobar;
+        $this->interpFactor = $aFactor;
+
+        if ( $this->interpFactor > 1 ) {
+
+            if( $this->interpFactor > 5 ) {
+                JpGraphError::RaiseL(28007);// ContourPlot interpolation factor is too large (>5)
+            }
+
+            $ip = new MeshInterpolate();
+            $this->dataMatrix = $ip->Linear($this->dataMatrix, $this->interpFactor);
+        }
+
+        $this->contour = new Contour($this->dataMatrix,$this->isobar,$aIsobarColors);
+
+        if( is_array($aIsobar) )
+            $this->nbrContours = count($aIsobar);
+        else
+            $this->nbrContours = $aIsobar;
+    }
+
+
+    /**
+     * Flipe the data around the center
+     *
+     * @param $aFlg
+     *
+     */
+    function SetInvert($aFlg=true) {
+        $this->flipData = $aFlg;
+    }
+
+    /**
+     * Set the colors for the isobar lines
+     *
+     * @param $aColorArray
+     *
+     */
+    function SetIsobarColors($aColorArray) {
+        $this->manualIsobarColors = $aColorArray;
+    }
+
+    /**
+     * Show the legend
+     *
+     * @param $aFlg true if the legend should be shown
+     *
+     */
+    function ShowLegend($aFlg=true) {
+        $this->showLegend = $aFlg;
+    }
+
+
+    /**
+     * @param $aFlg true if the legend should start with the lowest isobar on top
+     * @return unknown_type
+     */
+    function Invertlegend($aFlg=true) {
+        $this->invertLegend = $aFlg;
+    }
+
+    /* Internal method. Give the min value to be used for the scaling
+     *
+     */
+    function Min() {
+        return array(0,0);
+    }
+
+    /* Internal method. Give the max value to be used for the scaling
+     *
+     */
+    function Max() {
+        return array(count($this->dataMatrix[0])-1,count($this->dataMatrix)-1);
+    }
+
+    /**
+     * Internal ramewrok method to setup the legend to be used for this plot.
+     * @param $aGraph The parent graph class
+     */
+    function Legend($aGraph) {
+
+        if( ! $this->showLegend )
+            return;
+
+        if( $this->invertLegend ) {
+            for ($i = 0; $i < $this->nbrContours; $i++) {
+                $aGraph->legend->Add(sprintf('%.1f',$this->contourVal[$i]), $this->contourColor[$i]);
+            }
+        }
+        else {
+            for ($i = $this->nbrContours-1; $i >= 0 ; $i--) {
+                $aGraph->legend->Add(sprintf('%.1f',$this->contourVal[$i]), $this->contourColor[$i]);
+            }
+        }
+    }
+
+
+    /**
+     *  Framework function which gets called before the Stroke() method is called
+     *
+     *  @see Plot#PreScaleSetup($aGraph)
+     *
+     */
+    function PreScaleSetup($aGraph) {
+        $xn = count($this->dataMatrix[0])-1;
+        $yn = count($this->dataMatrix)-1;
+
+        $aGraph->xaxis->scale->Update($aGraph->img,0,$xn);
+        $aGraph->yaxis->scale->Update($aGraph->img,0,$yn);
+
+        $this->contour->SetInvert($this->flipData);
+        list($this->contourCoord,$this->contourVal,$this->contourColor) = $this->contour->getIsobars();
+    }
+
+    /**
+     * Use high contrast color schema
+     *
+     * @param $aFlg True, to use high contrast color
+     * @param $aBW True, Use only black and white color schema
+     */
+    function UseHighContrastColor($aFlg=true,$aBW=false) {
+        $this->highcontrast = $aFlg;
+        $this->highcontrastbw = $aBW;
+        $this->contour->UseHighContrastColor($this->highcontrast,$this->highcontrastbw);
+    }
+
+    /**
+     * Internal method. Stroke the contour plot to the graph
+     *
+     * @param $img Image handler
+     * @param $xscale Instance of the xscale to use
+     * @param $yscale Instance of the yscale to use
+     */
+    function Stroke($img,$xscale,$yscale) {
+
+        if( count($this->manualIsobarColors) > 0 ) {
+            $this->contourColor = $this->manualIsobarColors;
+            if( count($this->manualIsobarColors) != $this->nbrContours ) {
+                JpGraphError::RaiseL(28002);
+            }
+        }
+
+        $img->SetLineWeight($this->line_weight);
+
+        for ($c = 0; $c < $this->nbrContours; $c++) {
+
+            $img->SetColor( $this->contourColor[$c] );
+
+            $n = count($this->contourCoord[$c]);
+            $i = 0;
+            while ( $i < $n ) {
+                list($x1,$y1) = $this->contourCoord[$c][$i][0];
+                $x1t = $xscale->Translate($x1);
+                $y1t = $yscale->Translate($y1);
+
+                list($x2,$y2) = $this->contourCoord[$c][$i++][1];
+                $x2t = $xscale->Translate($x2);
+                $y2t = $yscale->Translate($y2);
+
+                $img->Line($x1t,$y1t,$x2t,$y2t);
+            }
+
+        }
+    }
+
+}
+
+// EOF
+?>
Index: /trunk/client/modules/Elezioni/grafici/jpgraph_meshinterpolate.inc.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/jpgraph_meshinterpolate.inc.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/jpgraph_meshinterpolate.inc.php	(revision 266)
@@ -0,0 +1,105 @@
+<?php
+/*=======================================================================
+// File:        JPGRAPH_MESHINTERPOLATE.INC.PHP
+// Description: Utility class to do mesh linear interpolation of a matrix
+// Created:     2009-03-09
+// Ver:         $Id: jpgraph_meshinterpolate.inc.php 1709 2009-07-30 08:00:08Z ljp $
+//
+// Copyright (c) Asial Corporation. All rights reserved.
+//========================================================================
+*/
+  
+/**
+* Utility function to do linear mesh interpolation
+* @param $aDat Matrix to interpolate
+* @param $aFactor Interpolation factor  
+*/
+function doMeshInterpolate( &$aData, $aFactor ) {
+    $m = new MeshInterpolate();
+    $aData = $m->Linear($aData,$aFactor);
+}
+
+/**
+ * Utility class to interpolate a given data matrix
+ *
+ */
+class MeshInterpolate {
+    private $data = array();
+
+   /**
+    * Calculate the mid points of the given rectangle which has its top left
+    * corner at $row,$col. The $aFactordecides how many spliots should be done.
+    * i.e. how many more divisions should be done recursively
+    *
+    * @param $row Top left corner of square to work with
+    * @param $col Top left corner of square to work with
+    * $param $aFactor In how many subsquare should we split this square. A value of 1 indicates that no action
+    */
+    function IntSquare( $aRow, $aCol, $aFactor ) {
+        if ( $aFactor <= 1 )
+            return;
+
+        $step = pow( 2, $aFactor-1 );
+
+        $v0 = $this->data[$aRow][$aCol];
+        $v1 = $this->data[$aRow][$aCol + $step];
+        $v2 = $this->data[$aRow + $step][$aCol];
+        $v3 = $this->data[$aRow + $step][$aCol + $step];
+
+        $this->data[$aRow][$aCol + $step / 2] = ( $v0 + $v1 ) / 2;
+        $this->data[$aRow + $step / 2][$aCol] = ( $v0 + $v2 ) / 2;
+        $this->data[$aRow + $step][$aCol + $step / 2] = ( $v2 + $v3 ) / 2;
+        $this->data[$aRow + $step / 2][$aCol + $step] = ( $v1 + $v3 ) / 2;
+        $this->data[$aRow + $step / 2][$aCol + $step / 2] = ( $v0 + $v1 + $v2 + $v3 ) / 4;
+
+        $this->IntSquare( $aRow, $aCol, $aFactor-1 );
+        $this->IntSquare( $aRow, $aCol + $step / 2, $aFactor-1 );
+        $this->IntSquare( $aRow + $step / 2, $aCol, $aFactor-1 );
+        $this->IntSquare( $aRow + $step / 2, $aCol + $step / 2, $aFactor-1 );
+    }
+
+    /**
+     * Interpolate values in a matrice so that the total number of data points
+     * in vert and horizontal axis are $aIntNbr more. For example $aIntNbr=2 will
+     * make the data matrice have tiwce as many vertical and horizontal dta points.
+     *
+     * Note: This will blow up the matrcide in memory size in the order of $aInNbr^2
+     *
+     * @param  $ &$aData The original data matricde
+     * @param  $aInNbr Interpolation factor
+     * @return the interpolated matrice
+     */
+    function Linear( &$aData, $aIntFactor ) {
+        $step = pow( 2, $aIntFactor-1 );
+
+        $orig_cols = count( $aData[0] );
+        $orig_rows = count( $aData );
+        // Number of new columns/rows
+        // N = (a-1) * 2^(f-1) + 1
+        $p = pow( 2, $aIntFactor-1 );
+        $new_cols = $p * ( $orig_cols - 1 ) + 1;
+        $new_rows = $p * ( $orig_rows - 1 ) + 1;
+
+        $this->data = array_fill( 0, $new_rows, array_fill( 0, $new_cols, 0 ) );
+        // Initialize the new matrix with the values that we know
+        for ( $i = 0; $i < $new_rows; $i++ ) {
+            for ( $j = 0; $j < $new_cols; $j++ ) {
+                $v = 0 ;
+                if ( ( $i % $step == 0 ) && ( $j % $step == 0 ) ) {
+                    $v = $aData[$i / $step][$j / $step];
+                }
+                $this->data[$i][$j] = $v;
+            }
+        }
+
+        for ( $i = 0; $i < $new_rows-1; $i += $step ) {
+            for ( $j = 0; $j < $new_cols-1; $j += $step ) {
+                $this->IntSquare( $i, $j, $aIntFactor );
+            }
+        }
+
+        return $this->data;
+    }
+}
+  
+?>
Index: /trunk/client/modules/Elezioni/grafici/jpgraph_plotline.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/jpgraph_plotline.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/jpgraph_plotline.php	(revision 266)
@@ -0,0 +1,142 @@
+<?php
+/*=======================================================================
+ // File:  		 JPGRAPH_PLOTLINE.PHP
+ // Description: PlotLine extension for JpGraph
+ // Created:  	 2009-03-24
+ // Ver:  		 $Id: jpgraph_plotline.php 1931 2010-03-22 15:05:48Z ljp $
+ //
+ // CLASS PlotLine
+ // Data container class to hold properties for a static
+ // line that is drawn directly in the plot area.
+ // Useful to add static borders inside a plot to show for example set-values
+ //
+ // Copyright (c) Asial Corporation. All rights reserved.
+ //========================================================================
+ */
+
+class PlotLine {
+    public $scaleposition, $direction=-1;
+    protected $weight=1;
+    protected $color = 'black';
+    private $legend='',$hidelegend=false, $legendcsimtarget='', $legendcsimalt='',$legendcsimwintarget='';
+    private $iLineStyle='solid';
+    public $numpoints=0; // Needed since the framework expects this property
+
+    function __construct($aDir=HORIZONTAL,$aPos=0,$aColor='black',$aWeight=1) {
+        $this->direction = $aDir;
+        $this->color=$aColor;
+        $this->weight=$aWeight;
+        $this->scaleposition=$aPos;
+    }
+
+    function SetLegend($aLegend,$aCSIM='',$aCSIMAlt='',$aCSIMWinTarget='') {
+        $this->legend = $aLegend;
+        $this->legendcsimtarget = $aCSIM;
+        $this->legendcsimwintarget = $aCSIMWinTarget;
+        $this->legendcsimalt = $aCSIMAlt;
+    }
+
+    function HideLegend($f=true) {
+        $this->hidelegend = $f;
+    }
+
+    function SetPosition($aScalePosition) {
+        $this->scaleposition=$aScalePosition;
+    }
+
+    function SetDirection($aDir) {
+        $this->direction = $aDir;
+    }
+
+    function SetColor($aColor) {
+        $this->color=$aColor;
+    }
+
+    function SetWeight($aWeight) {
+        $this->weight=$aWeight;
+    }
+
+    function SetLineStyle($aStyle) {
+        $this->iLineStyle = $aStyle;
+    }
+
+    function GetCSIMAreas() {
+        return '';
+    }
+
+    //---------------
+    // PRIVATE METHODS
+
+    function DoLegend($graph) {
+        if( !$this->hidelegend ) $this->Legend($graph);
+    }
+
+    // Framework function the chance for each plot class to set a legend
+    function Legend($aGraph) {
+        if( $this->legend != '' ) {
+            $dummyPlotMark = new PlotMark();
+            $lineStyle = 1;
+            $aGraph->legend->Add($this->legend,$this->color,$dummyPlotMark,$lineStyle,
+            $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
+        }
+    }
+
+    function PreStrokeAdjust($aGraph) {
+        // Nothing to do
+    }
+
+    // Called by framework to allow the object to draw
+    // optional information in the margin area
+    function StrokeMargin($aImg) {
+        // Nothing to do
+    }
+
+    // Framework function to allow the object to adjust the scale
+    function PrescaleSetup($aGraph) {
+        // Nothing to do
+    }
+
+    function Min() {
+        return array(null,null);
+    }
+
+    function Max() {
+        return array(null,null);
+    }
+
+    function _Stroke($aImg,$aMinX,$aMinY,$aMaxX,$aMaxY,$aXPos,$aYPos) {
+        $aImg->SetColor($this->color);
+        $aImg->SetLineWeight($this->weight);
+        $oldStyle = $aImg->SetLineStyle($this->iLineStyle);
+        if( $this->direction == VERTICAL ) {
+            $ymin_abs = $aMinY;
+            $ymax_abs = $aMaxY;
+            $xpos_abs = $aXPos;
+            $aImg->StyleLine($xpos_abs, $ymin_abs, $xpos_abs, $ymax_abs);
+        }
+        elseif( $this->direction == HORIZONTAL ) {
+            $xmin_abs = $aMinX;
+            $xmax_abs = $aMaxX;
+            $ypos_abs = $aYPos;
+            $aImg->StyleLine($xmin_abs, $ypos_abs, $xmax_abs, $ypos_abs);
+        }
+        else {
+            JpGraphError::RaiseL(25125);//(" Illegal direction for static line");
+        }
+        $aImg->SetLineStyle($oldStyle);
+    }
+
+    function Stroke($aImg,$aXScale,$aYScale) {
+        $this->_Stroke($aImg,
+            $aImg->left_margin,
+            $aYScale->Translate($aYScale->GetMinVal()),
+            $aImg->width-$aImg->right_margin,
+            $aYScale->Translate($aYScale->GetMaxVal()),
+            $aXScale->Translate($this->scaleposition),
+            $aYScale->Translate($this->scaleposition)
+        );
+    }
+}
+
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/jpgraph_table.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/jpgraph_table.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/jpgraph_table.php	(revision 266)
@@ -0,0 +1,1331 @@
+<?php
+/*=======================================================================
+ // File:        JPGRAPH_TABLE.PHP
+ // Description: Classes to create basic tables of data
+ // Created:     2006-01-25
+ // Ver:         $Id: jpgraph_table.php 1514 2009-07-07 11:15:58Z ljp $
+ //
+ // Copyright (c) Asial Corporation. All rights reserved.
+ //========================================================================
+ */
+
+// Style of grid lines in table
+DEFINE('TGRID_SINGLE',1);
+DEFINE('TGRID_DOUBLE',2);
+DEFINE('TGRID_DOUBLE2',3);
+
+// Type of constrain for image constrain
+DEFINE('TIMG_WIDTH',1);
+DEFINE('TIMG_HEIGHT',2);
+
+//---------------------------------------------------------------------
+// CLASS GTextTableCell
+// Description:
+// Internal class that represents each cell in the table
+//---------------------------------------------------------------------
+class GTextTableCell {
+    public $iColSpan=1,$iRowSpan=1;
+    public $iMarginLeft=5,$iMarginRight=5,$iMarginTop=5,$iMarginBottom=5;
+    public $iVal=NULL;
+    private $iBGColor='', $iFontColor='black';
+    private $iFF=FF_FONT1,$iFS=FS_NORMAL,$iFSize=10;
+    private $iRow=0, $iCol=0;
+    private $iVertAlign = 'bottom', $iHorAlign = 'left';
+    private $iMerged=FALSE,$iPRow=NULL,$iPCol=NULL;
+    private $iTable=NULL;
+    private $iGridColor=array('darkgray','darkgray','darkgray','darkgray');
+    private $iGridWeight=array(1,1,0,0); // left,top,bottom,right;
+    private $iGridStyle=array(TGRID_SINGLE,TGRID_SINGLE,TGRID_SINGLE,TGRID_SINGLE); // left,top,bottom,right;
+    private $iNumberFormat=null;
+    private $iIcon=null, $iIconConstrain=array();
+    private $iCSIMtarget = '',$iCSIMwintarget = '', $iCSIMalt = '', $iCSIMArea = '';
+
+    function __construct($aVal='',$aRow=0,$aCol=0) {
+        $this->iVal = new Text($aVal);
+        $this->iRow = $aRow;
+        $this->iCol = $aCol;
+        $this->iPRow = $aRow; // Initialiy each cell is its own parent
+        $this->iPCol = $aCol;
+        $this->iIconConstrain = array(-1,-1);
+    }
+
+    function Init($aTable) {
+        $this->iTable = $aTable;
+    }
+
+    function SetCSIMTarget($aTarget,$aAlt='',$aWinTarget='') {
+        $this->iCSIMtarget = $aTarget;
+        $this->iCSIMwintarget = $aWinTarget;
+        $this->iCSIMalt = $aAlt;
+    }
+
+    function GetCSIMArea() {
+        if( $this->iCSIMtarget !== '' )
+        return $this->iCSIMArea;
+        else
+        return '';
+    }
+
+    function SetImageConstrain($aType,$aVal) {
+        if( !in_array($aType,array(TIMG_WIDTH, TIMG_HEIGHT)) ) {
+            JpGraphError::RaiseL(27015);
+        }
+        $this->iIconConstrain = array($aType,$aVal);
+    }
+
+    function SetCountryFlag($aFlag,$aScale=1.0,$aMix=100,$aStdSize=3) {
+        $this->iIcon = new IconPlot();
+        $this->iIcon->SetCountryFlag($aFlag,0,0,$aScale,$aMix,$aStdSize);
+    }
+
+    function SetImage($aFile,$aScale=1.0,$aMix=100) {
+        $this->iIcon = new IconPlot($aFile,0,0,$aScale,$aMix);
+    }
+
+    function SetImageFromString($aStr,$aScale=1.0,$aMix=100) {
+        $this->iIcon = new IconPlot("",0,0,$aScale,$aMix);
+        $this->iIcon->CreateFromString($aStr);
+    }
+
+    function SetRowColSpan($aRowSpan,$aColSpan) {
+        $this->iRowSpan = $aRowSpan;
+        $this->iColSpan = $aColSpan;
+        $this->iMerged = true;
+    }
+
+    function SetMerged($aPRow,$aPCol,$aFlg=true) {
+        $this->iMerged = $aFlg;
+        $this->iPRow=$aPRow;
+        $this->iPCol=$aPCol;
+    }
+
+    function IsMerged() {
+        return $this->iMerged;
+    }
+
+    function SetNumberFormat($aF) {
+        $this->iNumberFormat = $aF;
+    }
+
+    function Set($aTxt) {
+        $this->iVal->Set($aTxt);
+    }
+
+    function SetFont($aFF,$aFS,$aFSize) {
+        $this->iFF = $aFF;
+        $this->iFS = $aFS;
+        $this->iFSize = $aFSize;
+        $this->iVal->SetFont($aFF,$aFS,$aFSize);
+    }
+
+    function SetFillColor($aColor) {
+        $this->iBGColor=$aColor;
+    }
+
+    function SetFontColor($aColor) {
+        $this->iFontColor=$aColor;
+    }
+
+    function SetGridColor($aLeft,$aTop=null,$aBottom=null,$aRight=null) {
+        if( $aLeft !== null ) $this->iGridColor[0] = $aLeft;
+        if( $aTop !== null ) $this->iGridColor[1] = $aTop;
+        if( $aBottom !== null ) $this->iGridColor[2] = $aBottom;
+        if( $aRight !== null )$this->iGridColor[3] = $aRight;
+    }
+
+    function SetGridStyle($aLeft,$aTop=null,$aBottom=null,$aRight=null) {
+        if( $aLeft !== null ) $this->iGridStyle[0] = $aLeft;
+        if( $aTop !== null ) $this->iGridStyle[1] = $aTop;
+        if( $aBottom !== null ) $this->iGridStyle[2] = $aBottom;
+        if( $aRight !== null )$this->iGridStyle[3] = $aRight;
+    }
+
+    function SetGridWeight($aLeft=null,$aTop=null,$aBottom=null,$aRight=null) {
+        $weight_arr = array($aLeft, $aTop, $aBottom, $aRight);
+        for ($i = 0; $i < count($weight_arr); $i++) {
+            if ($weight_arr[$i] === "") {
+                $weight_arr[$i] = 0;
+            }
+        }
+        if( $aLeft !== null ) $this->iGridWeight[0] = $weight_arr[0];
+        if( $aTop !== null ) $this->iGridWeight[1] = $weight_arr[1];
+        if( $aBottom !== null ) $this->iGridWeight[2] = $weight_arr[2];
+        if( $aRight !== null ) $this->iGridWeight[3] = $weight_arr[3];
+    }
+
+    function SetMargin($aLeft,$aRight,$aTop,$aBottom) {
+        $this->iMarginLeft=$aLeft;
+        $this->iMarginRight=$aRight;
+        $this->iMarginTop=$aTop;
+        $this->iMarginBottom=$aBottom;
+    }
+
+    function GetWidth($aImg) {
+        if( $this->iIcon !== null ) {
+            if( $this->iIconConstrain[0] == TIMG_WIDTH ) {
+            	$this->iIcon->SetScale(1);
+            	$tmp = $this->iIcon->GetWidthHeight();
+                $this->iIcon->SetScale($this->iIconConstrain[1]/$tmp[0]);
+            }
+            elseif( $this->iIconConstrain[0] == TIMG_HEIGHT ) {
+            	$this->iIcon->SetScale(1);
+            	$tmp = $this->iIcon->GetWidthHeight();
+                $this->iIcon->SetScale($this->iIconConstrain[1]/$tmp[1]);
+            }
+            $tmp = $this->iIcon->GetWidthHeight();
+            $iwidth = $tmp[0];
+        }
+        else {
+            $iwidth=0;
+        }
+        if( $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->dir == 0 ) {
+            $pwidth = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->GetWidth($aImg);
+        }
+        elseif( $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->dir == 90 ) {
+            $pwidth = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->GetFontHeight($aImg)+2;
+        }
+        else {
+            $pwidth = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->GetWidth($aImg)+2;
+        }
+
+        $pcolspan = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iColSpan;
+        return round(max($iwidth,$pwidth)/$pcolspan) + $this->iMarginLeft + $this->iMarginRight;
+    }
+
+    function GetHeight($aImg) {
+        if( $this->iIcon !== null ) {
+            if( $this->iIconConstrain[0] == TIMG_WIDTH ) {
+            	$this->iIcon->SetScale(1);
+            	$tmp = $this->iIcon->GetWidthHeight();
+            	$this->iIcon->SetScale($this->iIconConstrain[1]/$tmp[0]);
+            }
+            elseif( $this->iIconConstrain[0] == TIMG_HEIGHT ) {
+            	$this->iIcon->SetScale(1);
+            	$tmp = $this->iIcon->GetWidthHeight();
+                $this->iIcon->SetScale($this->iIconConstrain[1]/$tmp[1]);
+            }
+            $tmp = $this->iIcon->GetWidthHeight();
+            $iheight =  $tmp[1];
+        }
+        else {
+            $iheight = 0;
+        }
+        if( $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->dir == 0 ) {
+            $pheight = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->GetHeight($aImg);
+        }
+        else {
+            $pheight = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->GetHeight($aImg)+1;
+        }
+        $prowspan = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iRowSpan;
+        return round(max($iheight,$pheight)/$prowspan) + $this->iMarginTop + $this->iMarginBottom;
+    }
+
+    function SetAlign($aHorAlign='left',$aVertAlign='bottom') {
+        $aHorAlign = strtolower($aHorAlign);
+        $aVertAlign = strtolower($aVertAlign);
+        $chk = array('left','right','center','bottom','top','middle');
+        if( !in_array($aHorAlign,$chk) || !in_array($aVertAlign,$chk) ) {
+            JpGraphError::RaiseL(27011,$aHorAlign,$aVertAlign);
+        }
+        $this->iVertAlign = $aVertAlign;
+        $this->iHorAlign = $aHorAlign;
+    }
+
+    function AdjustMarginsForGrid() {
+        if( $this->iCol > 0 ) {
+            switch( $this->iGridStyle[0] ) {
+                case TGRID_SINGLE:  $wf=1;  break;
+                case TGRID_DOUBLE:  $wf=3;  break;
+                case TGRID_DOUBLE2: $wf=4;  break;
+            }
+            $this->iMarginLeft += $this->iGridWeight[0]*$wf;
+        }
+        if( $this->iRow > 0 ) {
+            switch( $this->iGridStyle[1] ) {
+                case TGRID_SINGLE:  $wf=1;  break;
+                case TGRID_DOUBLE:  $wf=3;  break;
+                case TGRID_DOUBLE2: $wf=4;  break;
+            }
+            $this->iMarginTop += $this->iGridWeight[1]*$wf;
+        }
+        if( $this->iRow+$this->iRowSpan-1 < $this->iTable->iSize[0]-1 ) {
+            switch( $this->iGridStyle[2] ) {
+                case TGRID_SINGLE: $wf=1; break;
+                case TGRID_DOUBLE: $wf=3; break;
+                case TGRID_DOUBLE2: $wf=4; break;
+            }
+            $this->iMarginBottom += $this->iGridWeight[2]*$wf;
+        }
+        if( $this->iCol+$this->iColSpan-1 < $this->iTable->iSize[1]-1 ) {
+            switch( $this->iGridStyle[3] ) {
+                case TGRID_SINGLE: $wf=1; break;
+                case TGRID_DOUBLE: $wf=3; break;
+                case TGRID_DOUBLE2: $wf=4; break;
+            }
+            $this->iMarginRight += $this->iGridWeight[3]*$wf;
+        }
+    }
+
+    function StrokeVGrid($aImg,$aX,$aY,$aWidth,$aHeight,$aDir=1) {
+        // Left or right grid line
+        // For the right we increase the X-pos and for the right we decrease it. This is
+        // determined by the direction argument.
+        $idx = $aDir==1 ? 0 : 3;
+
+        // We don't stroke the grid lines that are on the edge of the table since this is
+        // the place of the border.
+        if( ( ($this->iCol > 0 && $idx==0) || ($this->iCol+$this->iColSpan-1 < $this->iTable->iSize[1]-1 && $idx==3) )
+        && $this->iGridWeight[$idx] > 0 ) {
+            $x = $aDir==1 ? $aX : $aX + $aWidth-1;
+            $y = $aY+$aHeight-1;
+            $aImg->SetColor($this->iGridColor[$idx]);
+            switch( $this->iGridStyle[$idx] ) {
+                case TGRID_SINGLE:
+                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
+                    $aImg->Line($x+$i*$aDir,$aY, $x+$i*$aDir,$y);
+                    break;
+
+                case TGRID_DOUBLE:
+                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
+                    $aImg->Line($x+$i*$aDir,$aY, $x+$i*$aDir,$y);
+                    $x += $this->iGridWeight[$idx]*2;
+                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
+                    $aImg->Line($x+$i*$aDir,$aY, $x+$i*$aDir,$y);
+                    break;
+
+                case TGRID_DOUBLE2:
+                    for( $i=0; $i < $this->iGridWeight[$idx]*2; ++$i )
+                    $aImg->Line($x+$i*$aDir,$aY,$x+$i*$aDir,$y);
+                    $x += $this->iGridWeight[$idx]*3;
+                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
+                    $aImg->Line($x+$i*$aDir,$aY, $x+$i*$aDir,$y);
+                    break;
+            }
+        }
+    }
+
+    function StrokeHGrid($aImg,$aX,$aY,$aWidth,$aHeight,$aDir=1) {
+        // Top or bottom grid line
+        // For the left we increase the X-pos and for the right we decrease it. This is
+        // determined by the direction argument.
+        $idx = $aDir==1 ? 1 : 2;
+
+        // We don't stroke the grid lines that are on the edge of the table since this is
+        // the place of the border.
+        if( ( ($this->iRow > 0 && $idx==1) || ($this->iRow+$this->iRowSpan-1 < $this->iTable->iSize[0]-1 && $idx==2) )
+        && $this->iGridWeight[$idx] > 0) {
+            $y = $aDir==1 ? $aY : $aY+$aHeight-1;
+            $x = $aX+$aWidth-1;
+            $aImg->SetColor($this->iGridColor[$idx]);
+            switch( $this->iGridStyle[$idx] ) {
+                case TGRID_SINGLE:
+                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
+                    $aImg->Line($aX,$y+$i, $x,$y+$i);
+                    break;
+
+                case TGRID_DOUBLE:
+                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
+                    $aImg->Line($aX,$y+$i, $x,$y+$i);
+                    $y += $this->iGridWeight[$idx]*2;
+                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
+                    $aImg->Line($aX,$y+$i, $x,$y+$i);
+                    break;
+
+                case TGRID_DOUBLE2:
+                    for( $i=0; $i < $this->iGridWeight[$idx]*2; ++$i )
+                    $aImg->Line($aX,$y+$i, $x,$y+$i);
+                    $y += $this->iGridWeight[$idx]*3;
+                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
+                    $aImg->Line($aX,$y+$i, $x,$y+$i);
+                    break;
+            }
+        }
+    }
+
+    function Stroke($aImg,$aX,$aY,$aWidth,$aHeight) {
+        // If this is a merged cell we only stroke if it is the parent cell.
+        // The parent cell holds the merged cell block
+        if( $this->iMerged && ($this->iRow != $this->iPRow || $this->iCol != $this->iPCol) ) {
+            return;
+        }
+
+        if( $this->iBGColor != '' ) {
+            $aImg->SetColor($this->iBGColor);
+            $aImg->FilledRectangle($aX,$aY,$aX+$aWidth-1,$aY+$aHeight-1);
+        }
+
+        $coords = $aX.','.$aY.','.($aX+$aWidth-1).','.$aY.','.($aX+$aWidth-1).','.($aY+$aHeight-1).','.$aX.','.($aY+$aHeight-1);
+        if( ! empty($this->iCSIMtarget) ) {
+            $this->iCSIMArea = '<area shape="poly" coords="'.$coords.'" href="'.$this->iCSIMtarget.'"';
+            if( ! empty($this->iCSIMwintarget) ) {
+                $this->iCSIMArea .= " target=\"".$this->iCSIMwintarget."\"";
+            }
+            if( ! empty($this->iCSIMalt) ) {
+                $this->iCSIMArea .= ' alt="'.$this->iCSIMalt.'" title="'.$this->iCSIMalt."\" ";
+            }
+            $this->iCSIMArea .= " />\n";
+        }
+
+        $this->StrokeVGrid($aImg,$aX,$aY,$aWidth,$aHeight);
+        $this->StrokeVGrid($aImg,$aX,$aY,$aWidth,$aHeight,-1);
+        $this->StrokeHGrid($aImg,$aX,$aY,$aWidth,$aHeight);
+        $this->StrokeHGrid($aImg,$aX,$aY,$aWidth,$aHeight,-1);
+
+        if( $this->iIcon !== null ) {
+            switch( $this->iHorAlign ) {
+                case 'left':
+                    $x = $aX+$this->iMarginLeft;
+                    $hanchor='left';
+                    break;
+                case 'center':
+                case 'middle':
+                    $x = $aX+$this->iMarginLeft+round(($aWidth-$this->iMarginLeft-$this->iMarginRight)/2);
+                    $hanchor='center';
+                    break;
+                case 'right':
+                    $x = $aX+$aWidth-$this->iMarginRight-1;
+                    $hanchor='right';
+                    break;
+                default:
+                    JpGraphError::RaiseL(27012,$this->iHorAlign);
+            }
+
+            switch( $this->iVertAlign ) {
+                case 'top':
+                    $y = $aY+$this->iMarginTop;
+                    $vanchor='top';
+                    break;
+                case 'center':
+                case 'middle':
+                    $y = $aY+$this->iMarginTop+round(($aHeight-$this->iMarginTop-$this->iMarginBottom)/2);
+                    $vanchor='center';
+                    break;
+                case 'bottom':
+                    $y = $aY+$aHeight-1-$this->iMarginBottom;
+                    $vanchor='bottom';
+                    break;
+                default:
+                    JpGraphError::RaiseL(27012,$this->iVertAlign);
+            }
+            $this->iIcon->SetAnchor($hanchor,$vanchor);
+            $this->iIcon->_Stroke($aImg,$x,$y);
+        }
+        $this->iVal->SetColor($this->iFontColor);
+        $this->iVal->SetFont($this->iFF,$this->iFS,$this->iFSize);
+        switch( $this->iHorAlign ) {
+            case 'left':
+                $x = $aX+$this->iMarginLeft;
+                break;
+            case 'center':
+            case 'middle':
+                $x = $aX+$this->iMarginLeft+round(($aWidth-$this->iMarginLeft-$this->iMarginRight)/2);
+                break;
+            case 'right':
+                $x = $aX+$aWidth-$this->iMarginRight-1;
+                break;
+            default:
+                JpGraphError::RaiseL(27012,$this->iHorAlign);
+        }
+        // A workaround for the shortcomings in the TTF font handling in GD
+        // The anchor position for rotated text (=90) is to "short" so we add
+        // an offset based on the actual font size
+        if( $this->iVal->dir != 0 && $this->iVal->font_family >= 10 ) {
+            $aY += 4 + round($this->iVal->font_size*0.8);
+        }
+        switch( $this->iVertAlign ) {
+            case 'top':
+                $y = $aY+$this->iMarginTop;
+                break;
+            case 'center':
+            case 'middle':
+                $y = $aY+$this->iMarginTop+round(($aHeight-$this->iMarginTop-$this->iMarginBottom)/2);
+                //$y -= round($this->iVal->GetFontHeight($aImg)/2);
+                $y -= round($this->iVal->GetHeight($aImg)/2);
+                break;
+            case 'bottom':
+                //$y = $aY+$aHeight-1-$this->iMarginBottom-$this->iVal->GetFontHeight($aImg);
+                $y = $aY+$aHeight-$this->iMarginBottom-$this->iVal->GetHeight($aImg);
+                break;
+            default:
+                JpGraphError::RaiseL(27012,$this->iVertAlign);
+        }
+        $this->iVal->SetAlign($this->iHorAlign,'top');
+        if( $this->iNumberFormat !== null && is_numeric($this->iVal->t) ) {
+            $this->iVal->t = sprintf($this->iNumberFormat,$this->iVal->t);
+        }
+        $this->iVal->Stroke($aImg,$x,$y);
+    }
+}
+
+//---------------------------------------------------------------------
+// CLASS GTextTable
+// Description:
+// Graphic text table
+//---------------------------------------------------------------------
+class GTextTable {
+    public $iCells = array(), $iSize=array(0,0); // Need to be public since they are used by the cell
+    private $iWidth=0, $iHeight=0;
+    private $iColWidth=NULL,$iRowHeight=NULL;
+    private $iImg=NULL;
+    private $iXPos=0, $iYPos=0;
+    private $iScaleXPos=null,$iScaleYPos=null;
+    private $iBGColor='';
+    private $iBorderColor='black',$iBorderWeight=1;
+    private $iInit=false;
+    private $iYAnchor='top',$iXAnchor='left';
+    /*-----------------------------------------------------------------
+     * First and second phase constructors
+     *-----------------------------------------------------------------
+     */
+    function __construct() {
+        // Empty
+    }
+
+    function Init($aRows=0,$aCols=0,$aFillText='') {
+        $this->iSize[0] = $aRows;
+        $this->iSize[1] = $aCols;
+        for($i=0; $i < $this->iSize[0]; ++$i) {
+            for($j=0; $j < $this->iSize[1]; ++$j) {
+                $this->iCells[$i][$j] = new GTextTableCell($aFillText,$i,$j);
+                $this->iCells[$i][$j]->Init($this);
+            }
+        }
+        $this->iInit=true;
+    }
+
+    /*-----------------------------------------------------------------
+     * Outer border of table
+     *-----------------------------------------------------------------
+     */
+    function SetBorder($aWeight=1,$aColor='black') {
+        $this->iBorderColor=$aColor;
+        $this->iBorderWeight = $aWeight;
+    }
+
+
+    /*-----------------------------------------------------------------
+     * Position in graph of table
+     *-----------------------------------------------------------------
+     */
+    function SetPos($aX,$aY) {
+        $this->iXPos = $aX;
+        $this->iYPos = $aY;
+    }
+
+    function SetScalePos($aX,$aY) {
+        $this->iScaleXPos = $aX;
+        $this->iScaleYPos = $aY;
+    }
+
+    function SetAnchorPos($aXAnchor,$aYAnchor='top') {
+        $this->iXAnchor = $aXAnchor;
+        $this->iYAnchor = $aYAnchor;
+    }
+
+    /*-----------------------------------------------------------------
+     * Setup country flag in a cell
+     *-----------------------------------------------------------------
+     */
+    function SetCellCountryFlag($aRow,$aCol,$aFlag,$aScale=1.0,$aMix=100,$aStdSize=3) {
+        $this->_chkR($aRow);
+        $this->_chkC($aCol);
+        $this->iCells[$aRow][$aCol]->SetCountryFlag($aFlag,$aScale,$aMix,$aStdSize);
+
+    }
+
+    /*-----------------------------------------------------------------
+     * Setup image in a cell
+     *-----------------------------------------------------------------
+     */
+    function SetCellImage($aRow,$aCol,$aFile,$aScale=1.0,$aMix=100) {
+        $this->_chkR($aRow);
+        $this->_chkC($aCol);
+        $this->iCells[$aRow][$aCol]->SetImage($aFile,$aScale,$aMix);
+    }
+
+    function SetRowImage($aRow,$aFile,$aScale=1.0,$aMix=100) {
+        $this->_chkR($aRow);
+        for($j=0; $j < $this->iSize[1]; ++$j) {
+            $this->iCells[$aRow][$j]->SetImage($aFile,$aScale,$aMix);
+        }
+    }
+
+    function SetColImage($aCol,$aFile,$aScale=1.0,$aMix=100) {
+        $this->_chkC($aCol);
+        for($j=0; $j < $this->iSize[0]; ++$j) {
+            $this->iCells[$j][$aCol]->SetImage($aFile,$aScale,$aMix);
+        }
+    }
+
+    function SetImage($aFileR1,$aScaleC1=null,$aMixR2=null,$aC2=null,$aFile=null,$aScale=1.0,$aMix=100) {
+        if( $aScaleC1 !== null && $aMixR2!==null && $aC2!==null && $aFile!==null ) {
+            $this->_chkR($aArgR1);  $this->_chkC($aC1);
+            $this->_chkR($aR2);  $this->_chkC($aC2);
+        }
+        else {
+            if( $aScaleC1 !== null ) $aScale = $aScaleC1;
+            if( $aMixR2 !== null ) $aMix = $aMixR2;
+            $aFile = $aFileR1;
+            $aMixR2 = $this->iSize[0]-1; $aFileR1 = 0;
+            $aC2 = $this->iSize[1]-1; $aScaleC1 = 0;
+        }
+        for($i=$aArgR1; $i <= $aR2; ++$i) {
+            for($j=$aC1; $j <= $aC2; ++$j) {
+                $this->iCells[$i][$j]->SetImage($aFile,$aScale,$aMix);
+            }
+        }
+    }
+
+    function SetCellImageConstrain($aRow,$aCol,$aType,$aVal) {
+        $this->_chkR($aRow);
+        $this->_chkC($aCol);
+        $this->iCells[$aRow][$aCol]->SetImageConstrain($aType,$aVal);
+    }
+
+    /*-----------------------------------------------------------------
+     * Generate a HTML version of the table
+     *-----------------------------------------------------------------
+     */
+    function toString() {
+        $t = '<table border=1 cellspacing=0 cellpadding=0>';
+        for($i=0; $i < $this->iSize[0]; ++$i) {
+            $t .= '<tr>';
+            for($j=0; $j < $this->iSize[1]; ++$j) {
+                $t .= '<td>';
+                if( $this->iCells[$i][$j]->iMerged )
+                $t .= 'M ';
+                $t .= 'val='.$this->iCells[$i][$j]->iVal->t;
+                $t .= ' (cs='.$this->iCells[$i][$j]->iColSpan.
+        ', rs='.$this->iCells[$i][$j]->iRowSpan.')';
+                $t .= '</td>';
+            }
+            $t .= '</tr>';
+        }
+        $t .= '</table>';
+        return $t;
+    }
+
+    /*-----------------------------------------------------------------
+     * Specify data for table
+     *-----------------------------------------------------------------
+     */
+    function Set($aArg1,$aArg2=NULL,$aArg3=NULL) {
+        if( $aArg2===NULL && $aArg3===NULL ) {
+            if( is_array($aArg1) ) {
+                if( is_array($aArg1[0]) ) {
+                    $m = count($aArg1);
+                    // Find the longest row
+                    $n=0;
+                    for($i=0; $i < $m; ++$i)
+                    $n = max(count($aArg1[$i]),$n);
+                    for($i=0; $i < $m; ++$i) {
+                        for($j=0; $j < $n; ++$j) {
+                            if( isset($aArg1[$i][$j]) ){
+                                $this->_setcell($i,$j,(string)$aArg1[$i][$j]);
+                            }
+                            else {
+                                $this->_setcell($i,$j);
+                            }
+                        }
+                    }
+                    $this->iSize[0] = $m;
+                    $this->iSize[1] = $n;
+                    $this->iInit=true;
+                }
+                else {
+                    JpGraphError::RaiseL(27001);
+                    //('Illegal argument to GTextTable::Set(). Array must be 2 dimensional');
+                }
+            }
+            else {
+                JpGraphError::RaiseL(27002);
+                //('Illegal argument to GTextTable::Set()');
+            }
+        }
+        else {
+            // Must be in the form (row,col,val)
+            $this->_chkR($aArg1);
+            $this->_chkC($aArg2);
+            $this->_setcell($aArg1,$aArg2,(string)$aArg3);
+        }
+    }
+
+    /*---------------------------------------------------------------------
+     * Cell margin setting
+     *---------------------------------------------------------------------
+     */
+    function SetPadding($aArgR1,$aC1=null,$aR2=null,$aC2=null,$aPad=null) {
+        if( $aC1 !== null && $aR2!==null && $aC2!==null && $aPad!==null ) {
+            $this->_chkR($aArgR1);  $this->_chkC($aC1);
+            $this->_chkR($aR2);  $this->_chkC($aC2);
+        }
+        else {
+            $aPad = $aArgR1;
+            $aR2 = $this->iSize[0]-1; $aArgR1 = 0;
+            $aC2 = $this->iSize[1]-1; $aC1 = 0;
+        }
+        for($i=$aArgR1; $i <= $aR2; ++$i) {
+            for($j=$aC1; $j <= $aC2; ++$j) {
+                $this->iCells[$i][$j]->SetMargin($aPad,$aPad,$aPad,$aPad);
+            }
+        }
+    }
+
+    function SetRowPadding($aRow,$aPad) {
+        $this->_chkR($aRow);
+        for($j=0; $j < $this->iSize[1]; ++$j) {
+            $this->iCells[$aRow][$j]->SetMargin($aPad,$aPad,$aPad,$aPad);
+        }
+    }
+
+    function SetColPadding($aCol,$aPad) {
+        $this->_chkC($aCol);
+        for($j=0; $j < $this->iSize[0]; ++$j) {
+            $this->iCells[$j][$aCol]->SetMargin($aPad,$aPad,$aPad,$aPad);
+        }
+    }
+
+    function SetCellPadding($aRow,$aCol,$aPad) {
+        $this->_chkR($aRow);
+        $this->_chkC($aCol);
+        $this->iCells[$aRow][$aCol]->SetMargin($aPad,$aPad,$aPad,$aPad);
+    }
+
+
+    /*---------------------------------------------------------------------
+     * Cell text orientation setting
+     *---------------------------------------------------------------------
+     */
+    function SetTextOrientation($aArgR1,$aC1=null,$aR2=null,$aC2=null,$aO=null) {
+        if( $aC1 !== null && $aR2!==null && $aC2!==null && $aPad!==null ) {
+            $this->_chkR($aArgR1);  $this->_chkC($aC1);
+            $this->_chkR($aR2);  $this->_chkC($aC2);
+        }
+        else {
+            $aO = $aArgR1;
+            $aR2 = $this->iSize[0]-1; $aArgR1 = 0;
+            $aC2 = $this->iSize[1]-1; $aC1 = 0;
+        }
+        for($i=$aArgR1; $i <= $aR2; ++$i) {
+            for($j=$aC1; $j <= $aC2; ++$j) {
+                $this->iCells[$i][$j]->iVal->SetOrientation($aO);
+            }
+        }
+    }
+
+    function SetRowTextOrientation($aRow,$aO) {
+        $this->_chkR($aRow);
+        for($j=0; $j < $this->iSize[1]; ++$j) {
+            $this->iCells[$aRow][$j]->iVal->SetOrientation($aO);
+        }
+    }
+
+    function SetColTextOrientation($aCol,$aO) {
+        $this->_chkC($aCol);
+        for($j=0; $j < $this->iSize[0]; ++$j) {
+            $this->iCells[$j][$aCol]->iVal->SetOrientation($aO);
+        }
+    }
+
+    function SetCellTextOrientation($aRow,$aCol,$aO) {
+        $this->_chkR($aRow);
+        $this->_chkC($aCol);
+        $this->iCells[$aRow][$aCol]->iVal->SetOrientation($aO);
+    }
+
+
+
+
+    /*---------------------------------------------------------------------
+     * Font color setting
+     *---------------------------------------------------------------------
+     */
+
+    function SetColor($aArgR1,$aC1=null,$aR2=null,$aC2=null,$aArg=null) {
+        if( $aC1 !== null && $aR2!==null && $aC2!==null && $aArg!==null ) {
+            $this->_chkR($aArgR1);  $this->_chkC($aC1);
+            $this->_chkR($aR2);  $this->_chkC($aC2);
+        }
+        else {
+            $aArg = $aArgR1;
+            $aR2 = $this->iSize[0]-1; $aArgR1 = 0;
+            $aC2 = $this->iSize[1]-1; $aC1 = 0;
+        }
+        for($i=$aArgR1; $i <= $aR2; ++$i) {
+            for($j=$aC1; $j <= $aC2; ++$j) {
+                $this->iCells[$i][$j]->SetFontColor($aArg);
+            }
+        }
+    }
+
+    function SetRowColor($aRow,$aColor) {
+        $this->_chkR($aRow);
+        for($j=0; $j < $this->iSize[1]; ++$j) {
+            $this->iCells[$aRow][$j]->SetFontColor($aColor);
+        }
+    }
+
+    function SetColColor($aCol,$aColor) {
+        $this->_chkC($aCol);
+        for($i=0; $i < $this->iSize[0]; ++$i) {
+            $this->iCells[$i][$aCol]->SetFontColor($aColor);
+        }
+    }
+
+    function SetCellColor($aRow,$aCol,$aColor) {
+        $this->_chkR($aRow);
+        $this->_chkC($aCol);
+        $this->iCells[$aRow][$aCol]->SetFontColor($aColor);
+    }
+
+    /*---------------------------------------------------------------------
+     * Fill color settings
+     *---------------------------------------------------------------------
+     */
+
+    function SetFillColor($aArgR1,$aC1=null,$aR2=null,$aC2=null,$aArg=null) {
+        if( $aC1 !== null && $aR2!==null && $aC2!==null && $aArg!==null ) {
+            $this->_chkR($aArgR1);  $this->_chkC($aC1);
+            $this->_chkR($aR2);  $this->_chkC($aC2);
+            for($i=$aArgR1; $i <= $aR2; ++$i) {
+                for($j=$aC1; $j <= $aC2; ++$j) {
+                    $this->iCells[$i][$j]->SetFillColor($aArg);
+                }
+            }
+        }
+        else {
+            $this->iBGColor = $aArgR1;
+        }
+    }
+
+    function SetRowFillColor($aRow,$aColor) {
+        $this->_chkR($aRow);
+        for($j=0; $j < $this->iSize[1]; ++$j) {
+            $this->iCells[$aRow][$j]->SetFillColor($aColor);
+        }
+    }
+
+    function SetColFillColor($aCol,$aColor) {
+        $this->_chkC($aCol);
+        for($i=0; $i < $this->iSize[0]; ++$i) {
+            $this->iCells[$i][$aCol]->SetFillColor($aColor);
+        }
+    }
+
+    function SetCellFillColor($aRow,$aCol,$aColor) {
+        $this->_chkR($aRow);
+        $this->_chkC($aCol);
+        $this->iCells[$aRow][$aCol]->SetFillColor($aColor);
+    }
+
+    /*---------------------------------------------------------------------
+     * Font family setting
+     *---------------------------------------------------------------------
+     */
+    function SetFont() {
+        $numargs = func_num_args();
+        if( $numargs == 2 || $numargs == 3 ) {
+            $aFF = func_get_arg(0);
+            $aFS = func_get_arg(1);
+            if( $numargs == 3 )
+            $aFSize=func_get_arg(2);
+            else
+            $aFSize=10;
+            $aR2 = $this->iSize[0]-1; $aR1 = 0;
+            $aC2 = $this->iSize[1]-1; $aC1 = 0;
+
+        }
+        elseif($numargs == 6 || $numargs == 7 ) {
+            $aR1 = func_get_arg(0); $aC1 = func_get_arg(1);
+            $aR2 = func_get_arg(2); $aC2 = func_get_arg(3);
+            $aFF = func_get_arg(4); $aFS = func_get_arg(5);
+            if( $numargs == 7 )
+            $aFSize=func_get_arg(6);
+            else
+            $aFSize=10;
+        }
+        else {
+            JpGraphError::RaiseL(27003);
+            //('Wrong number of arguments to GTextTable::SetColor()');
+        }
+        $this->_chkR($aR1);  $this->_chkC($aC1);
+        $this->_chkR($aR2);  $this->_chkC($aC2);
+        for($i=$aR1; $i <= $aR2; ++$i) {
+            for($j=$aC1; $j <= $aC2; ++$j) {
+                $this->iCells[$i][$j]->SetFont($aFF,$aFS,$aFSize);
+            }
+        }
+    }
+
+    function SetRowFont($aRow,$aFF,$aFS,$aFSize=10) {
+        $this->_chkR($aRow);
+        for($j=0; $j < $this->iSize[1]; ++$j) {
+            $this->iCells[$aRow][$j]->SetFont($aFF,$aFS,$aFSize);
+        }
+    }
+
+    function SetColFont($aCol,$aFF,$aFS,$aFSize=10) {
+        $this->_chkC($aCol);
+        for($i=0; $i < $this->iSize[0]; ++$i) {
+            $this->iCells[$i][$aCol]->SetFont($aFF,$aFS,$aFSize);
+        }
+    }
+
+    function SetCellFont($aRow,$aCol,$aFF,$aFS,$aFSize=10) {
+        $this->_chkR($aRow);
+        $this->_chkC($aCol);
+        $this->iCells[$aRow][$aCol]->SetFont($aFF,$aFS,$aFSize);
+    }
+
+    /*---------------------------------------------------------------------
+     * Cell align settings
+     *---------------------------------------------------------------------
+     */
+
+    function SetAlign($aR1HAlign=null,$aC1VAlign=null,$aR2=null,$aC2=null,$aHArg=null,$aVArg='center') {
+        if( $aC1VAlign !== null && $aR2!==null && $aC2!==null && $aHArg!==null ) {
+            $this->_chkR($aR1HAlign);  $this->_chkC($aC1VAlign);
+            $this->_chkR($aR2);  $this->_chkC($aC2);
+        }
+        else {
+            if( $aR1HAlign === null ) {
+                JpGraphError::RaiseL(27010);
+            }
+            if( $aC1VAlign === null ) {
+                $aC1VAlign = 'center';
+            }
+            $aHArg = $aR1HAlign;
+            $aVArg = $aC1VAlign === null ? 'center' : $aC1VAlign ;
+            $aR2 = $this->iSize[0]-1; $aR1HAlign = 0;
+            $aC2 = $this->iSize[1]-1; $aC1VAlign = 0;
+        }
+        for($i=$aR1HAlign; $i <= $aR2; ++$i) {
+            for($j=$aC1VAlign; $j <= $aC2; ++$j) {
+                $this->iCells[$i][$j]->SetAlign($aHArg,$aVArg);
+            }
+        }
+    }
+
+    function SetCellAlign($aRow,$aCol,$aHorAlign,$aVertAlign='bottom') {
+        $this->_chkR($aRow);
+        $this->_chkC($aCol);
+        $this->iCells[$aRow][$aCol]->SetAlign($aHorAlign,$aVertAlign);
+    }
+
+    function SetRowAlign($aRow,$aHorAlign,$aVertAlign='bottom') {
+        $this->_chkR($aRow);
+        for($j=0; $j < $this->iSize[1]; ++$j) {
+            $this->iCells[$aRow][$j]->SetAlign($aHorAlign,$aVertAlign);
+        }
+    }
+
+    function SetColAlign($aCol,$aHorAlign,$aVertAlign='bottom') {
+        $this->_chkC($aCol);
+        for($i=0; $i < $this->iSize[0]; ++$i) {
+            $this->iCells[$i][$aCol]->SetAlign($aHorAlign,$aVertAlign);
+        }
+    }
+
+    /*---------------------------------------------------------------------
+     * Cell number format
+     *---------------------------------------------------------------------
+     */
+
+    function SetNumberFormat($aArgR1,$aC1=null,$aR2=null,$aC2=null,$aArg=null) {
+        if( $aC1 !== null && $aR2!==null && $aC2!==null && $aArg!==null ) {
+            $this->_chkR($aArgR1);  $this->_chkC($aC1);
+            $this->_chkR($aR2);  $this->_chkC($aC2);
+        }
+        else {
+            $aArg = $aArgR1;
+            $aR2 = $this->iSize[0]-1; $aArgR1 = 0;
+            $aC2 = $this->iSize[1]-1; $aC1 = 0;
+        }
+        if( !is_string($aArg) ) {
+            JpGraphError::RaiseL(27013); // argument must be a string
+        }
+        for($i=$aArgR1; $i <= $aR2; ++$i) {
+            for($j=$aC1; $j <= $aC2; ++$j) {
+                $this->iCells[$i][$j]->SetNumberFormat($aArg);
+            }
+        }
+    }
+
+    function SetRowNumberFormat($aRow,$aF) {
+        $this->_chkR($aRow);
+        if( !is_string($aF) ) {
+            JpGraphError::RaiseL(27013); // argument must be a string
+        }
+        for($j=0; $j < $this->iSize[1]; ++$j) {
+            $this->iCells[$aRow][$j]->SetNumberFormat($aF);
+        }
+    }
+
+    function SetColNumberFormat($aCol,$aF) {
+        $this->_chkC($aCol);
+        if( !is_string($aF) ) {
+            JpGraphError::RaiseL(27013); // argument must be a string
+        }
+        for($i=0; $i < $this->iSize[0]; ++$i) {
+            $this->iCells[$i][$aCol]->SetNumberFormat($aF);
+        }
+    }
+
+    function SetCellNumberFormat($aRow,$aCol,$aF) {
+        $this->_chkR($aRow); $this->_chkC($aCol);
+        if( !is_string($aF) ) {
+            JpGraphError::RaiseL(27013); // argument must be a string
+        }
+        $this->iCells[$aRow][$aCol]->SetNumberFormat($aF);
+    }
+
+    /*---------------------------------------------------------------------
+     * Set row and column min size
+     *---------------------------------------------------------------------
+     */
+
+    function SetMinColWidth($aColWidth,$aWidth=null) {
+        // If there is only one argument this means that all
+        // columns get set to the same width
+        if( $aWidth===null ) {
+            for($i=0; $i < $this->iSize[1]; ++$i) {
+                $this->iColWidth[$i]  = $aColWidth;
+            }
+        }
+        else {
+            $this->_chkC($aColWidth);
+            $this->iColWidth[$aColWidth]  = $aWidth;
+        }
+    }
+
+    function SetMinRowHeight($aRowHeight,$aHeight=null) {
+        // If there is only one argument this means that all
+        // rows get set to the same height
+        if( $aHeight===null ) {
+            for($i=0; $i < $this->iSize[0]; ++$i) {
+                $this->iRowHeight[$i]  = $aRowHeight;
+            }
+        }
+        else {
+            $this->_chkR($aRowHeight);
+            $this->iRowHeight[$aRowHeight]  = $aHeight;
+        }
+    }
+
+    /*---------------------------------------------------------------------
+     * Grid line settings
+     *---------------------------------------------------------------------
+     */
+
+    function SetGrid($aWeight=1,$aColor='black',$aStyle=TGRID_SINGLE) {
+        $rc = $this->iSize[0];
+        $cc = $this->iSize[1];
+        for($i=0; $i < $rc; ++$i) {
+            for($j=0; $j < $cc; ++$j) {
+                $this->iCells[$i][$j]->SetGridColor($aColor,$aColor);
+                $this->iCells[$i][$j]->SetGridWeight($aWeight,$aWeight);
+                $this->iCells[$i][$j]->SetGridStyle($aStyle);
+            }
+        }
+    }
+
+    function SetColGrid($aCol,$aWeight=1,$aColor='black',$aStyle=TGRID_SINGLE) {
+        $this->_chkC($aCol);
+        for($i=0; $i < $this->iSize[0]; ++$i) {
+            $this->iCells[$i][$aCol]->SetGridWeight($aWeight);
+            $this->iCells[$i][$aCol]->SetGridColor($aColor);
+            $this->iCells[$i][$aCol]->SetGridStyle($aStyle);
+        }
+    }
+
+    function SetRowGrid($aRow,$aWeight=1,$aColor='black',$aStyle=TGRID_SINGLE) {
+        $this->_chkR($aRow);
+        for($j=0; $j < $this->iSize[1]; ++$j) {
+            $this->iCells[$aRow][$j]->SetGridWeight(NULL,$aWeight);
+            $this->iCells[$aRow][$j]->SetGridColor(NULL,$aColor);
+            $this->iCells[$aRow][$j]->SetGridStyle(NULL,$aStyle);
+        }
+    }
+
+    /*---------------------------------------------------------------------
+     * Merge cells
+     *---------------------------------------------------------------------
+     */
+
+    function MergeRow($aRow,$aHAlign='center',$aVAlign='center') {
+        $this->_chkR($aRow);
+        $this->MergeCells($aRow,0,$aRow,$this->iSize[1]-1,$aHAlign,$aVAlign);
+    }
+
+    function MergeCol($aCol,$aHAlign='center',$aVAlign='center') {
+        $this->_chkC($aCol);
+        $this->MergeCells(0,$aCol,$this->iSize[0]-1,$aCol,$aHAlign,$aVAlign);
+    }
+
+    function MergeCells($aR1,$aC1,$aR2,$aC2,$aHAlign='center',$aVAlign='center') {
+        if( $aR1 > $aR2 || $aC1 > $aC2 ) {
+            JpGraphError::RaiseL(27004);
+            //('GTextTable::MergeCells(). Specified cell range to be merged is not valid.');
+        }
+        $this->_chkR($aR1); $this->_chkC($aC1);
+        $this->_chkR($aR2); $this->_chkC($aC2);
+        $rspan = $aR2-$aR1+1;
+        $cspan = $aC2-$aC1+1;
+        // Setup the parent cell for this merged group
+        if( $this->iCells[$aR1][$aC1]->IsMerged() ) {
+            JpGraphError::RaiseL(27005,$aR1,$aC1,$aR2,$aC2);
+            //("Cannot merge already merged cells in the range ($aR1,$aC1), ($aR2,$aC2)");
+        }
+        $this->iCells[$aR1][$aC1]->SetRowColSpan($rspan,$cspan);
+        $this->iCells[$aR1][$aC1]->SetAlign($aHAlign,$aVAlign);
+        for($i=$aR1; $i <= $aR2; ++$i) {
+            for($j=$aC1; $j <= $aC2; ++$j) {
+                if( ! ($i == $aR1 && $j == $aC1) ) {
+                    if( $this->iCells[$i][$j]->IsMerged() ) {
+                        JpGraphError::RaiseL(27005,$aR1,$aC1,$aR2,$aC2);
+                        //("Cannot merge already merged cells in the range ($aR1,$aC1), ($aR2,$aC2)");
+                    }
+                    $this->iCells[$i][$j]->SetMerged($aR1,$aC1,true);
+                }
+            }
+        }
+    }
+
+
+    /*---------------------------------------------------------------------
+     * CSIM methods
+     *---------------------------------------------------------------------
+     */
+
+    function SetCSIMTarget($aTarget,$aAlt=null,$aAutoTarget=false) {
+        $m = $this->iSize[0];
+        $n = $this->iSize[1];
+        $csim = '';
+        for($i=0; $i < $m; ++$i) {
+            for($j=0; $j < $n; ++$j) {
+                if( $aAutoTarget )
+                $t = $aTarget."?row=$i&col=$j";
+                else
+                $t = $aTarget;
+                $this->iCells[$i][$j]->SetCSIMTarget($t,$aAlt);
+            }
+        }
+    }
+
+    function SetCellCSIMTarget($aRow,$aCol,$aTarget,$aAlt=null) {
+        $this->_chkR($aRow);
+        $this->_chkC($aCol);
+        $this->iCells[$aRow][$aCol]->SetCSIMTarget($aTarget,$aAlt);
+    }
+
+    /*---------------------------------------------------------------------
+     * Private methods
+     *---------------------------------------------------------------------
+     */
+
+    function GetCSIMAreas() {
+        $m = $this->iSize[0];
+        $n = $this->iSize[1];
+        $csim = '';
+        for($i=0; $i < $m; ++$i) {
+            for($j=0; $j < $n; ++$j) {
+                $csim .= $this->iCells[$i][$j]->GetCSIMArea();
+            }
+        }
+        return $csim;
+    }
+
+    function _chkC($aCol) {
+        if( ! $this->iInit ) {
+            JpGraphError::Raise(27014); // Table not initialized
+        }
+        if( $aCol < 0 || $aCol >= $this->iSize[1] )
+        JpGraphError::RaiseL(27006,$aCol);
+        //("GTextTable:\nColumn argument ($aCol) is outside specified table size.");
+    }
+
+    function _chkR($aRow) {
+        if( ! $this->iInit ) {
+            JpGraphError::Raise(27014); // Table not initialized
+        }
+        if( $aRow < 0 || $aRow >= $this->iSize[0] )
+        JpGraphError::RaiseL(27007,$aRow);
+        //("GTextTable:\nRow argument ($aRow) is outside specified table size.");
+    }
+
+    function _getScalePos() {
+        if( $this->iScaleXPos === null || $this->iScaleYPos === null ) {
+            return false;
+        }
+        return array($this->iScaleXPos, $this->iScaleYPos);
+    }
+
+    function _autoSizeTable($aImg) {
+        // Get maximum column width and row height
+        $m = $this->iSize[0];
+        $n = $this->iSize[1];
+        $w=1;$h=1;
+
+        // Get maximum row height per row
+        for($i=0; $i < $m; ++$i) {
+            $h=0;
+            for($j=0; $j < $n; ++$j) {
+                $h = max($h,$this->iCells[$i][$j]->GetHeight($aImg));
+            }
+            if( isset($this->iRowHeight[$i]) ) {
+                $this->iRowHeight[$i]  = max($h,$this->iRowHeight[$i]);
+            }
+            else
+            $this->iRowHeight[$i]  = $h;
+        }
+
+        // Get maximum col width per columns
+        for($j=0; $j < $n; ++$j) {
+            $w=0;
+            for($i=0; $i < $m; ++$i) {
+                $w = max($w,$this->iCells[$i][$j]->GetWidth($aImg));
+            }
+            if( isset($this->iColWidth[$j]) ) {
+                $this->iColWidth[$j]  = max($w,$this->iColWidth[$j]);
+            }
+            else
+            $this->iColWidth[$j]  = $w;
+        }
+    }
+
+    function _setcell($aRow,$aCol,$aVal='') {
+        if( isset($this->iCells[$aRow][$aCol]) ) {
+            $this->iCells[$aRow][$aCol]->Set($aVal);
+        }
+        else {
+            $this->iCells[$aRow][$aCol] = new GTextTableCell((string)$aVal,$aRow,$aCol);
+            $this->iCells[$aRow][$aCol]->Init($this);
+        }
+    }
+
+    function StrokeWithScale($aImg,$aXScale,$aYScale) {
+        if( is_numeric($this->iScaleXPos) && is_numeric($this->iScaleYPos) ) {
+            $x = round($aXScale->Translate($this->iScaleXPos));
+            $y = round($aYScale->Translate($this->iScaleYPos));
+            $this->Stroke($aImg,$x,$y);
+        }
+        else {
+            $this->Stroke($aImg);
+        }
+    }
+
+    function Stroke($aImg,$aX=NULL,$aY=NULL) {
+        if( $aX !== NULL && $aY !== NULL ) {
+            $this->iXPos = $aX;
+            $this->iYPos = $aY;
+        }
+
+        $rc = $this->iSize[0]; // row count
+        $cc = $this->iSize[1]; // column count
+
+        if( $rc == 0 || $cc == 0 ) {
+            JpGraphError::RaiseL(27009);
+        }
+
+        // Adjust margins of each cell based on the weight of the grid. Each table grid line
+        // is actually occupying the left side and top part of each cell.
+        for($j=0; $j < $cc; ++$j) {
+            $this->iCells[0][$j]->iMarginTop += $this->iBorderWeight;
+        }
+        for($i=0; $i < $rc; ++$i) {
+            $this->iCells[$i][0]->iMarginLeft += $this->iBorderWeight;
+        }
+        for($i=0; $i < $rc; ++$i) {
+            for($j=0; $j < $cc; ++$j) {
+                $this->iCells[$i][$j]->AdjustMarginsForGrid();
+            }
+        }
+
+        // adjust row and column size depending on cell content
+        $this->_autoSizeTable($aImg);
+
+        if( $this->iSize[1] != count($this->iColWidth) || $this->iSize[0] != count($this->iRowHeight) ) {
+            JpGraphError::RaiseL(27008);
+            //('Column and row size arrays must match the dimesnions of the table');
+        }
+
+        // Find out overall table size
+        $width=0;
+        for($i=0; $i < $cc; ++$i) {
+            $width += $this->iColWidth[$i];
+        }
+        $height=0;
+        for($i=0; $i < $rc; ++$i) {
+            $height += $this->iRowHeight[$i];
+        }
+
+        // Adjust the X,Y position to alway be at the top left corner
+        // The anchor position, i.e. how the client want to interpret the specified
+        // x and y coordinate must be taken into account
+        switch( strtolower($this->iXAnchor) ) {
+            case 'left' :
+                break;
+            case 'center':
+                $this->iXPos -= round($width/2);
+                break;
+            case 'right':
+                $this->iXPos -= $width;
+                break;
+        }
+        switch( strtolower($this->iYAnchor) ) {
+            case 'top' :
+                break;
+            case 'center':
+            case 'middle':
+                $this->iYPos -= round($height/2);
+                break;
+            case 'bottom':
+                $this->iYPos -= $height;
+                break;
+        }
+
+        // Set the overall background color of the table if set
+        if( $this->iBGColor !== '' ) {
+            $aImg->SetColor($this->iBGColor);
+            $aImg->FilledRectangle($this->iXPos,$this->iYPos,$this->iXPos+$width,$this->iYPos+$height);
+        }
+
+        // Stroke all cells
+        $rpos=$this->iYPos;
+        for($i=0; $i < $rc; ++$i) {
+            $cpos=$this->iXPos;
+            for($j=0; $j < $cc; ++$j) {
+                // Calculate width and height of this cell if it is spanning
+                // more than one column or row
+                $cwidth=0;
+                for( $k=0; $k < $this->iCells[$i][$j]->iColSpan; ++$k ) {
+                    $cwidth += $this->iColWidth[$j+$k];
+                }
+                $cheight=0;
+                for( $k=0; $k < $this->iCells[$i][$j]->iRowSpan; ++$k ) {
+                    $cheight += $this->iRowHeight[$i+$k];
+                }
+
+                $this->iCells[$i][$j]->Stroke($aImg,$cpos,$rpos,$cwidth,$cheight);
+                $cpos += $this->iColWidth[$j];
+            }
+            $rpos += $this->iRowHeight[$i];
+        }
+
+        // Stroke outer border
+        $aImg->SetColor($this->iBorderColor);
+        if( $this->iBorderWeight == 1 )
+        $aImg->Rectangle($this->iXPos,$this->iYPos,$this->iXPos+$width,$this->iYPos+$height);
+        else {
+            for( $i=0; $i < $this->iBorderWeight; ++$i )
+            $aImg->Rectangle($this->iXPos+$i,$this->iYPos+$i,
+            $this->iXPos+$width-1+$this->iBorderWeight-$i,
+            $this->iYPos+$height-1+$this->iBorderWeight-$i);
+        }
+    }
+}
+
+/*
+ EOF
+ */
+?>
Index: /trunk/client/modules/Elezioni/grafici/jpgraph_theme.inc.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/jpgraph_theme.inc.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/jpgraph_theme.inc.php	(revision 266)
@@ -0,0 +1,136 @@
+<?php
+//=======================================================================
+// File:        JPGRAPH_THEME.INC.PHP
+// Description: Class to define graph theme
+// Created:     2010-09-29 
+// Ver:         $Id: jpgraph_theme.inc.php 83 2010-10-01 11:24:19Z atsushi $
+//
+// Copyright (c) Asial Corporation. All rights reserved.
+//========================================================================
+
+
+// include Theme classes
+foreach (glob(dirname(__FILE__) . '/themes/*.php') as $theme_class_script) {
+  require_once($theme_class_script);
+}
+
+//===================================================
+// CLASS 
+// Description: 
+//===================================================
+abstract class Theme {
+    protected $color_index;
+    
+    function __construct() {
+        $this->color_index = 0;
+    }
+    /**
+    * 
+    */
+    abstract function GetColorList();
+
+    /**
+    *
+    */
+    abstract function ApplyPlot($plot);
+
+
+    /**
+    *
+    */   
+    function SetupPlot($plot) {
+        if (is_array($plot)) {
+            foreach ($plot as $obj) {
+                $this->ApplyPlot($obj);
+            }
+        } else {
+            $this->ApplyPlot($plot);
+        }
+    }
+
+    /**
+    *
+    */
+    function ApplyGraph($graph) {
+
+        $this->graph = $graph;
+        $method_name = '';
+
+        if (get_class($graph) == 'Graph') {
+            $method_name = 'SetupGraph';
+        } else {
+            $method_name = 'Setup' . get_class($graph);
+        }
+
+        if (method_exists($this, $method_name)) {
+            $this->$method_name($graph);
+        } else {
+            JpGraphError::RaiseL(30001, $method_name, $method_name); //Theme::%s() is not defined. \nPlease make %s(\$graph) function in your theme classs.
+        }
+    }
+
+    /**
+    *
+    */
+    function PreStrokeApply($graph) {
+    }
+
+    /**
+    *
+    */
+    function GetThemeColors($num = 30) { 
+        $result_list = array();
+
+        $old_index = $this->color_index;
+        $this->color_index = 0;
+        $count = 0;
+  
+        $i = 0;
+        while (true) {
+            for ($j = 0; $j < count($this->GetColorList()); $j++) {
+                if (++$count > $num) {
+                    break 2;
+                }
+                $result_list[] = $this->GetNextColor();
+            }
+            $i++;
+        }
+
+        $this->color_index = $old_index;
+        
+        return $result_list;
+    }
+
+    /**
+    *
+    */
+    function GetNextColor() {
+        $color_list = $this->GetColorList();
+
+        $color = null;
+        if (isset($color_list[$this->color_index])) {
+            $color = $color_list[$this->color_index];
+        } else {
+            $color_count = count($color_list);
+            if ($color_count <= $this->color_index) {
+                $color_tmp = $color_list[$this->color_index % $color_count];
+                $brightness = 1.0 - intval($this->color_index / $color_count) * 0.2;
+                $rgb = new RGB();
+                $color = $color_tmp . ':' . $brightness;
+                $color = $rgb->Color($color);
+                $alpha = array_pop($color);
+                $color = $rgb->tryHexConversion($color);
+                if ($alpha) {
+                    $color .= '@' . $alpha;
+                }
+            }
+        }
+
+        $this->color_index++;
+
+        return $color;
+    }
+
+} // Class
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/jpgraph_windrose.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/jpgraph_windrose.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/jpgraph_windrose.php	(revision 266)
@@ -0,0 +1,1566 @@
+<?php
+/*=======================================================================
+ // File:        JPGRAPH_WINDROSE.PHP
+ // Description: Windrose extension for JpGraph
+ // Created:     2003-09-17
+ // Ver:         $Id: jpgraph_windrose.php 1928 2010-01-11 19:56:51Z ljp $
+ //
+ // Copyright (c) Asial Corporation. All rights reserved.
+ //========================================================================
+ */
+
+require_once('jpgraph_glayout_vh.inc.php');
+
+//------------------------------------------------------------------------
+// Determine how many compass directions to show
+//------------------------------------------------------------------------
+define('WINDROSE_TYPE4',1);
+define('WINDROSE_TYPE8',2);
+define('WINDROSE_TYPE16',3);
+define('WINDROSE_TYPEFREE',4);
+
+//------------------------------------------------------------------------
+// How should the labels for the circular grids be aligned
+//------------------------------------------------------------------------
+define('LBLALIGN_CENTER',1);
+define('LBLALIGN_TOP',2);
+
+//------------------------------------------------------------------------
+// How should the labels around the plot be align
+//------------------------------------------------------------------------
+define('LBLPOSITION_CENTER',1);
+define('LBLPOSITION_EDGE',2);
+
+//------------------------------------------------------------------------
+// Interpretation of ordinal values in the data
+//------------------------------------------------------------------------
+define('KEYENCODING_CLOCKWISE',1);
+define('KEYENCODING_ANTICLOCKWISE',2);
+
+// Internal debug flag
+define('__DEBUG',false);
+
+
+//===================================================
+// CLASS WindrosePlotScale
+//===================================================
+class WindrosePlotScale {
+    private $iMax,$iDelta=5;
+    private $iNumCirc=3;
+    public $iMaxNum=0;
+    private $iLblFmt='%.0f%%';
+    public $iFontFamily=FF_VERDANA,$iFontStyle=FS_NORMAL,$iFontSize=10;
+    public $iZFontFamily=FF_ARIAL,$iZFontStyle=FS_NORMAL,$iZFontSize=10;
+    public $iFontColor='black',$iZFontColor='black';
+    private $iFontFrameColor=false, $iFontBkgColor=false;
+    private $iLblZeroTxt=null;
+    private $iLblAlign=LBLALIGN_CENTER;
+    public $iAngle='auto';
+    private $iManualScale = false;
+    private $iHideLabels = false;
+
+    function __construct($aData) {
+        $max=0;
+        $totlegsum = 0;
+        $maxnum=0;
+        $this->iZeroSum=0;
+        foreach( $aData as $idx => $legdata ) {
+            $legsum = array_sum($legdata);
+            $maxnum = max($maxnum,count($legdata)-1);
+            $max = max($legsum-$legdata[0],$max);
+            $totlegsum += $legsum;
+            $this->iZeroSum += $legdata[0] ;
+        }
+        if( round($totlegsum) > 100 ) {
+            JpGraphError::RaiseL(22001,$legsum);
+            //("Total percentage for all windrose legs in a windrose plot can not exceed  100% !\n(Current max is: ".$legsum.')');
+        }
+        $this->iMax = $max ;
+        $this->iMaxNum = $maxnum;
+        $this->iNumCirc = $this->GetNumCirc();
+        $this->iMaxVal = $this->iNumCirc * $this->iDelta ;
+    }
+
+    // Return number of grid circles
+    function GetNumCirc() {
+        // Never return less than 1 circles
+        $num = ceil($this->iMax / $this->iDelta);
+        return max(1,$num) ;
+    }
+
+    function SetMaxValue($aMax) {
+        $this->iMax = $aMax;
+        $this->iNumCirc = $this->GetNumCirc();
+        $this->iMaxVal = $this->iNumCirc * $this->iDelta ;
+    }
+
+    // Set step size for circular grid
+    function Set($aMax,$aDelta=null) {
+        if( $aDelta==null ) {
+            $this->SetMaxValue($aMax);
+            return;
+        }
+        $this->iDelta = $aDelta;
+        $this->iNumCirc = ceil($aMax/$aDelta); //$this->GetNumCirc();
+        $this->iMaxVal = $this->iNumCirc * $this->iDelta ;
+        $this->iMax=$aMax;
+        // Remember that user has specified interval so don't
+        // do autoscaling
+        $this->iManualScale = true;
+    }
+
+    function AutoScale($aRadius,$aMinDist=30) {
+
+        if( $this->iManualScale ) return;
+
+        // Make sure distance (in pixels) between two circles
+        // is never less than $aMinDist pixels
+        $tst = ceil($aRadius / $this->iNumCirc) ;
+
+        while( $tst <= $aMinDist && $this->iDelta < 100 ) {
+            $this->iDelta += 5;
+            $tst = ceil($aRadius / $this->GetNumCirc()) ;
+        }
+
+        if( $this->iDelta >= 100 ) {
+            JpGraphError::RaiseL(22002);//('Graph is too small to have a scale. Please make the graph larger.');
+        }
+
+        // If the distance is to large try with multiples of 2 instead
+        if( $tst > $aMinDist * 3 ) {
+            $this->iDelta = 2;
+            $tst = ceil($aRadius / $this->iNumCirc) ;
+
+            while( $tst <= $aMinDist && $this->iDelta < 100 ) {
+                $this->iDelta += 2;
+                $tst = ceil($aRadius / $this->GetNumCirc()) ;
+            }
+
+            if( $this->iDelta >= 100 ) {
+                JpGraphError::RaiseL(22002); //('Graph is too small to have a scale. Please make the graph larger.');
+            }
+        }
+
+        $this->iNumCirc = $this->GetNumCirc();
+        $this->iMaxVal = $this->iNumCirc * $this->iDelta ;
+    }
+
+    // Return max of all leg values
+    function GetMax() {
+        return $this->iMax;
+    }
+
+    function Hide($aFlg=true) {
+        $this->iHideLabels = $aFlg;
+    }
+
+    function SetAngle($aAngle) {
+        $this->iAngle = $aAngle ;
+    }
+
+    // Translate a Leg value to radius distance
+    function RelTranslate($aVal,$r,$ri) {
+        $tv = round($aVal/$this->iMaxVal*($r-$ri));
+        return $tv ;
+    }
+
+    function SetLabelAlign($aAlign) {
+        $this->iLblAlign = $aAlign ;
+    }
+
+    function SetLabelFormat($aFmt) {
+        $this->iLblFmt = $aFmt ;
+    }
+
+    function SetLabelFillColor($aBkgColor,$aBorderColor=false) {
+
+        $this->iFontBkgColor = $aBkgColor;
+        if( $aBorderColor === false ) {
+            $this->iFontFrameColor = $aBkgColor;
+        }
+        else {
+            $this->iFontFrameColor = $aBorderColor;
+        }
+    }
+
+    function SetFontColor($aColor) {
+        $this->iFontColor = $aColor ;
+        $this->iZFontColor = $aColor ;
+    }
+
+    function SetFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize=10) {
+        $this->iFontFamily = $aFontFamily ;
+        $this->iFontStyle = $aFontStyle ;
+        $this->iFontSize = $aFontSize ;
+        $this->SetZFont($aFontFamily,$aFontStyle,$aFontSize);
+    }
+
+    function SetZFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize=10) {
+        $this->iZFontFamily = $aFontFamily ;
+        $this->iZFontStyle = $aFontStyle ;
+        $this->iZFontSize = $aFontSize ;
+    }
+
+    function SetZeroLabel($aTxt) {
+        $this->iLblZeroTxt = $aTxt ;
+    }
+
+    function SetZFontColor($aColor) {
+        $this->iZFontColor = $aColor ;
+    }
+
+    function StrokeLabels($aImg,$xc,$yc,$ri,$rr) {
+
+        if( $this->iHideLabels ) return;
+
+        // Setup some convinient vairables
+        $a = $this->iAngle * M_PI/180.0;
+        $n = $this->iNumCirc;
+        $d = $this->iDelta;
+
+        // Setup the font and font color
+        $val = new Text();
+        $val->SetFont($this->iFontFamily,$this->iFontStyle,$this->iFontSize);
+        $val->SetColor($this->iFontColor);
+
+        if( $this->iFontBkgColor !== false ) {
+            $val->SetBox($this->iFontBkgColor,$this->iFontFrameColor);
+        }
+
+        // Position the labels relative to the radiant circles
+        if( $this->iLblAlign == LBLALIGN_TOP ) {
+            if( $a > 0 && $a <= M_PI/2 ) {
+                $val->SetAlign('left','bottom');
+            }
+            elseif( $a > M_PI/2 && $a <= M_PI ) {
+                $val->SetAlign('right','bottom');
+            }
+        }
+        elseif( $this->iLblAlign == LBLALIGN_CENTER ) {
+            $val->SetAlign('center','center');
+        }
+
+        // Stroke the labels close to each circle
+        $v = $d ;
+        $si = sin($a);
+        $co = cos($a);
+        for( $i=0; $i < $n; ++$i, $v += $d ) {
+            $r = $ri + ($i+1) * $rr;
+            $x = $xc + $co * $r;
+            $y = $yc - $si * $r;
+            $val->Set(sprintf($this->iLblFmt,$v));
+            $val->Stroke($aImg,$x,$y);
+        }
+
+        // Print the text in the zero circle
+        if( $this->iLblZeroTxt === null ) {
+            $this->iLblZeroTxt = sprintf($this->iLblFmt,$this->iZeroSum);
+        }
+        else {
+            $this->iLblZeroTxt = sprintf($this->iLblZeroTxt,$this->iZeroSum);
+        }
+
+        $val->Set($this->iLblZeroTxt);
+        $val->SetAlign('center','center');
+        $val->SetParagraphAlign('center');
+        $val->SetColor($this->iZFontColor);
+        $val->SetFont($this->iZFontFamily,$this->iZFontStyle,$this->iZFontSize);
+        $val->Stroke($aImg,$xc,$yc);
+    }
+}
+
+//===================================================
+// CLASS LegendStyle
+//===================================================
+class LegendStyle {
+    public $iLength = 40, $iMargin = 20 , $iBottomMargin=5;
+    public $iCircleWeight=2,  $iCircleRadius = 18, $iCircleColor='black';
+    public $iTxtFontFamily=FF_VERDANA,$iTxtFontStyle=FS_NORMAL,$iTxtFontSize=8;
+    public $iLblFontFamily=FF_VERDANA,$iLblFontStyle=FS_NORMAL,$iLblFontSize=8;
+    public $iCircleFontFamily=FF_VERDANA,$iCircleFontStyle=FS_NORMAL,$iCircleFontSize=8;
+    public $iLblFontColor='black',$iTxtFontColor='black',$iCircleFontColor='black';
+    public $iShow=true;
+    public $iFormatString='%.1f';
+    public $iTxtMargin=6, $iTxt='';
+    public $iZCircleTxt='Calm';
+
+    function SetFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize=10) {
+        $this->iLblFontFamily = $aFontFamily ;
+        $this->iLblFontStyle = $aFontStyle ;
+        $this->iLblFontSize = $aFontSize ;
+        $this->iTxtFontFamily = $aFontFamily ;
+        $this->iTxtFontStyle = $aFontStyle ;
+        $this->iTxtFontSize = $aFontSize ;
+        $this->iCircleFontFamily = $aFontFamily ;
+        $this->iCircleFontStyle = $aFontStyle ;
+        $this->iCircleFontSize = $aFontSize ;
+    }
+
+    function SetLFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize=10) {
+        $this->iLblFontFamily = $aFontFamily ;
+        $this->iLblFontStyle = $aFontStyle ;
+        $this->iLblFontSize = $aFontSize ;
+    }
+
+    function SetTFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize=10) {
+        $this->iTxtFontFamily = $aFontFamily ;
+        $this->iTxtFontStyle = $aFontStyle ;
+        $this->iTxtFontSize = $aFontSize ;
+    }
+
+    function SetCFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize=10) {
+        $this->iCircleFontFamily = $aFontFamily ;
+        $this->iCircleFontStyle = $aFontStyle ;
+        $this->iCircleFontSize = $aFontSize ;
+    }
+
+
+    function SetFontColor($aColor) {
+        $this->iTxtFontColor = $aColor ;
+        $this->iLblFontColor = $aColor ;
+        $this->iCircleFontColor = $aColor ;
+    }
+
+    function SetTFontColor($aColor) {
+        $this->iTxtFontColor = $aColor ;
+    }
+
+    function SetLFontColor($aColor) {
+        $this->iLblFontColor = $aColor ;
+    }
+
+    function SetCFontColor($aColor) {
+        $this->iCircleFontColor = $aColor ;
+    }
+
+    function SetCircleWeight($aWeight) {
+        $this->iCircleWeight = $aWeight;
+    }
+
+    function SetCircleRadius($aRadius) {
+        $this->iCircleRadius = $aRadius;
+    }
+
+    function SetCircleColor($aColor) {
+        $this->iCircleColor = $aColor ;
+    }
+
+    function SetCircleText($aTxt) {
+        $this->iZCircleTxt = $aTxt;
+    }
+
+    function SetMargin($aMarg,$aBottomMargin=5) {
+        $this->iMargin=$aMarg;
+        $this->iBottomMargin=$aBottomMargin;
+    }
+
+    function SetLength($aLength) {
+        $this->iLength = $aLength ;
+    }
+
+    function Show($aFlg=true) {
+        $this->iShow = $aFlg;
+    }
+
+    function Hide($aFlg=true) {
+        $this->iShow = ! $aFlg;
+    }
+
+    function SetFormat($aFmt) {
+        $this->iFormatString=$aFmt;
+    }
+
+    function SetText($aTxt) {
+        $this->iTxt = $aTxt ;
+    }
+
+}
+
+define('RANGE_OVERLAPPING',0);
+define('RANGE_DISCRETE',1);
+
+//===================================================
+// CLASS WindrosePlot
+//===================================================
+class WindrosePlot {
+    private $iAntiAlias=true;
+    private $iData=array();
+    public $iX=0.5,$iY=0.5;
+    public $iSize=0.55;
+    private $iGridColor1='gray',$iGridColor2='darkgreen';
+    private $iRadialColorArray=array();
+    private $iRadialWeightArray=array();
+    private $iRadialStyleArray=array();
+    private $iRanges = array(1,2,3,5,6,10,13.5,99.0);
+    private $iRangeStyle = RANGE_OVERLAPPING ;
+    public $iCenterSize=60;
+    private $iType = WINDROSE_TYPE16;
+    public $iFontFamily=FF_VERDANA,$iFontStyle=FS_NORMAL,$iFontSize=10;
+    public $iFontColor='darkgray';
+    private $iRadialGridStyle='longdashed';
+    private $iAllDirectionLabels =  array('E','ENE','NE','NNE','N','NNW','NW','WNW','W','WSW','SW','SSW','S','SSE','SE','ESE');
+    private $iStandardDirections = array();
+    private $iCircGridWeight=3, $iRadialGridWeight=1;
+    private $iLabelMargin=12;
+    private $iLegweights = array(2,4,6,8,10,12,14,16,18,20);
+    private $iLegColors = array('orange','black','blue','red','green','purple','navy','yellow','brown');
+    private $iLabelFormatString='', $iLabels=array();
+    private $iLabelPositioning = LBLPOSITION_EDGE;
+    private $iColor='white';
+    private $iShowBox=false, $iBoxColor='black',$iBoxWeight=1,$iBoxStyle='solid';
+    private $iOrdinalEncoding=KEYENCODING_ANTICLOCKWISE;
+    public $legend=null;
+
+    function __construct($aData) {
+        $this->iData = $aData;
+        $this->legend = new LegendStyle();
+
+        // Setup the scale
+        $this->scale = new WindrosePlotScale($this->iData);
+
+        // default label for free type i agle and a degree sign
+        $this->iLabelFormatString = '%.1f'.SymChar::Get('degree');
+
+        $delta = 2*M_PI/16;
+        for( $i=0, $a=0; $i < 16; ++$i, $a += $delta ) {
+            $this->iStandardDirections[$this->iAllDirectionLabels[$i]] = $a;
+        }
+    }
+
+    // Dummy method to make window plots have the same signature as the
+    // layout classes since windrose plots are "leaf" classes in the hierarchy
+    function LayoutSize() {
+        return 1;
+    }
+
+    function SetSize($aSize) {
+        $this->iSize = $aSize;
+    }
+
+    function SetDataKeyEncoding($aEncoding) {
+        $this->iOrdinalEncoding = $aEncoding;
+    }
+
+    function SetColor($aColor) {
+        $this->iColor = $aColor;
+    }
+
+    function SetRadialColors($aColors) {
+        $this->iRadialColorArray = $aColors;
+    }
+
+    function SetRadialWeights($aWeights) {
+        $this->iRadialWeightArray = $aWeights;
+    }
+
+    function SetRadialStyles($aStyles) {
+        $this->iRadialStyleArray = $aStyles;
+    }
+
+    function SetBox($aColor='black',$aWeight=1, $aStyle='solid', $aShow=true) {
+        $this->iShowBox = $aShow ;
+        $this->iBoxColor = $aColor ;
+        $this->iBoxWeight = $aWeight ;
+        $this->iBoxStyle = $aStyle;
+    }
+
+    function SetLabels($aLabels) {
+        $this->iLabels = $aLabels ;
+    }
+
+    function SetLabelMargin($aMarg) {
+        $this->iLabelMargin = $aMarg ;
+    }
+
+    function SetLabelFormat($aLblFormat) {
+        $this->iLabelFormatString = $aLblFormat ;
+    }
+
+    function SetCompassLabels($aLabels) {
+        if( count($aLabels) != 16 ) {
+            JpgraphError::RaiseL(22004); //('Label specification for windrose directions must have 16 values (one for each compass direction).');
+        }
+        $this->iAllDirectionLabels = $aLabels ;
+
+        $delta = 2*M_PI/16;
+        for( $i=0, $a=0; $i < 16; ++$i, $a += $delta ) {
+            $this->iStandardDirections[$this->iAllDirectionLabels[$i]] = $a;
+        }
+
+    }
+
+    function SetCenterSize($aSize) {
+        $this->iCenterSize = $aSize;
+    }
+    // Alias for SetCenterSize
+    function SetZCircleSize($aSize) {
+        $this->iCenterSize = $aSize;
+    }
+
+    function SetFont($aFFam,$aFStyle=FS_NORMAL,$aFSize=10) {
+        $this->iFontFamily = $aFFam ;
+        $this->iFontStyle = $aFStyle ;
+        $this->iFontSize = $aFSize ;
+    }
+
+    function SetFontColor($aColor) {
+        $this->iFontColor=$aColor;
+    }
+
+    function SetGridColor($aColor1,$aColor2) {
+        $this->iGridColor1 = $aColor1;
+        $this->iGridColor2 = $aColor2;
+    }
+
+    function SetGridWeight($aGrid1=1,$aGrid2=2) {
+        $this->iCircGridWeight = $aGrid1 ;
+        $this->iRadialGridWeight = $aGrid2 ;
+    }
+
+    function SetRadialGridStyle($aStyle) {
+        $aStyle = strtolower($aStyle);
+        if( !in_array($aStyle,array('solid','dotted','dashed','longdashed')) ) {
+            JpGraphError::RaiseL(22005); //("Line style for radial lines must be on of ('solid','dotted','dashed','longdashed') ");
+        }
+        $this->iRadialGridStyle=$aStyle;
+    }
+
+    function SetRanges($aRanges) {
+        $this->iRanges = $aRanges;
+    }
+
+    function SetRangeStyle($aStyle) {
+        $this->iRangeStyle = $aStyle;
+    }
+
+    function SetRangeColors($aLegColors) {
+        $this->iLegColors = $aLegColors;
+    }
+
+    function SetRangeWeights($aWeights) {
+        $n=count($aWeights);
+        for($i=0; $i< $n; ++$i ) {
+            $aWeights[$i] = floor($aWeights[$i]/2);
+        }
+        $this->iLegweights = $aWeights;
+
+    }
+
+    function SetType($aType) {
+        if( $aType < WINDROSE_TYPE4 || $aType > WINDROSE_TYPEFREE ) {
+            JpGraphError::RaiseL(22006); //('Illegal windrose type specified.');
+        }
+        $this->iType = $aType;
+    }
+
+    // Alias for SetPos()
+    function SetCenterPos($aX,$aY) {
+        $this->iX = $aX;
+        $this->iY = $aY;        
+    }
+    
+    function SetPos($aX,$aY) {
+        $this->iX = $aX;
+        $this->iY = $aY;
+    }
+
+    function SetAntiAlias($aFlag) {
+        $this->iAntiAlias = $aFlag ;
+        if( ! $aFlag )
+        $this->iCircGridWeight = 1;
+    }
+
+    function _ThickCircle($aImg,$aXC,$aYC,$aRad,$aWeight=2,$aColor) {
+
+        $aImg->SetColor($aColor);
+        $aRad *= 2 ;
+        $aImg->Ellipse($aXC,$aYC,$aRad,$aRad);
+        if( $aWeight > 1 ) {
+            $aImg->Ellipse($aXC,$aYC,$aRad+1,$aRad+1);
+            $aImg->Ellipse($aXC,$aYC,$aRad+2,$aRad+2);
+            if( $aWeight > 2 ) {
+                $aImg->Ellipse($aXC,$aYC,$aRad+3,$aRad+3);
+                $aImg->Ellipse($aXC,$aYC,$aRad+3,$aRad+4);
+                $aImg->Ellipse($aXC,$aYC,$aRad+4,$aRad+3);
+            }
+        }
+    }
+
+    function _StrokeWindLeg($aImg,$xc,$yc,$a,$ri,$r,$weight,$color) {
+
+        // If less than 1 px long then we assume this has been caused by rounding problems
+        // and should not be stroked
+        if( $r < 1 ) return;
+
+        $xt = $xc + cos($a)*$ri;
+        $yt = $yc - sin($a)*$ri;
+        $xxt = $xc + cos($a)*($ri+$r);
+        $yyt = $yc - sin($a)*($ri+$r);
+
+        $x1 = $xt - $weight*sin($a);
+        $y1 = $yt - $weight*cos($a);
+        $x2 = $xxt - $weight*sin($a);
+        $y2 = $yyt - $weight*cos($a);
+
+        $x3 = $xxt + $weight*sin($a);
+        $y3 = $yyt + $weight*cos($a);
+        $x4 = $xt + $weight*sin($a);
+        $y4 = $yt + $weight*cos($a);
+
+        $pts = array($x1,$y1,$x2,$y2,$x3,$y3,$x4,$y4);
+        $aImg->SetColor($color);
+        $aImg->FilledPolygon($pts);
+
+    }
+
+    function _StrokeLegend($aImg,$x,$y,$scaling=1,$aReturnWidth=false) {
+
+        if( ! $this->legend->iShow ) return 0;
+
+        $nlc = count($this->iLegColors);
+        $nlw = count($this->iLegweights);
+
+        // Setup font for ranges
+        $value = new Text();
+        $value->SetAlign('center','bottom');
+        $value->SetFont($this->legend->iLblFontFamily,
+        $this->legend->iLblFontStyle,
+        $this->legend->iLblFontSize*$scaling);
+        $value->SetColor($this->legend->iLblFontColor);
+
+        // Remember x-center
+        $xcenter = $x ;
+
+        // Construct format string
+        $fmt = $this->legend->iFormatString.'-'.$this->legend->iFormatString;
+
+        // Make sure that the length of each range is enough to cover the
+        // size of the labels
+        $tst = sprintf($fmt,$this->iRanges[0],$this->iRanges[1]);
+        $value->Set($tst);
+        $w = $value->GetWidth($aImg);
+        $l = round(max($this->legend->iLength * $scaling,$w*1.5));
+
+        $r = $this->legend->iCircleRadius * $scaling ;
+        $len = 2*$r + $this->scale->iMaxNum * $l;
+
+        // We are called just to find out the width
+        if( $aReturnWidth ) return $len;
+
+        $x -= round($len/2);
+        $x += $r;
+
+        // 4 pixels extra vertical margin since the circle sometimes is +/- 1 pixel of the
+        // theorethical radius due to imperfection in the GD library
+        //$y -= round(max($r,$scaling*$this->iLegweights[($this->scale->iMaxNum-1) % $nlw])+4*$scaling);
+        $y -= ($this->legend->iCircleRadius + 2)*$scaling+$this->legend->iBottomMargin*$scaling;
+
+        // Adjust for bottom text
+        if( $this->legend->iTxt != '' ) {
+            // Setup font for text
+            $value->Set($this->legend->iTxt);
+            $y -= /*$this->legend->iTxtMargin + */ $value->GetHeight($aImg);
+        }
+
+        // Stroke 0-circle
+        $this->_ThickCircle($aImg,$x,$y,$r,$this->legend->iCircleWeight,
+        $this->legend->iCircleColor);
+
+        // Remember the center of the circe
+        $xc=$x; $yc=$y;
+
+        $value->SetAlign('center','bottom');
+        $x += $r+1;
+
+        // Stroke all used ranges
+        $txty = $y -
+        round($this->iLegweights[($this->scale->iMaxNum-1)%$nlw]*$scaling) - 4*$scaling;
+        if( $this->scale->iMaxNum >= count($this->iRanges) ) {
+            JpGraphError::RaiseL(22007); //('To few values for the range legend.');
+        }
+        $i=0;$idx=0;
+        while( $i < $this->scale->iMaxNum ) {
+            $y1 = $y - round($this->iLegweights[$i % $nlw]*$scaling);
+            $y2 = $y + round($this->iLegweights[$i % $nlw]*$scaling);
+            $x2 = $x + $l ;
+            $aImg->SetColor($this->iLegColors[$i % $nlc]);
+            $aImg->FilledRectangle($x,$y1,$x2,$y2);
+            if( $this->iRangeStyle == RANGE_OVERLAPPING ) {
+                $lbl = sprintf($fmt,$this->iRanges[$idx],$this->iRanges[$idx+1]);
+            }
+            else {
+                $lbl = sprintf($fmt,$this->iRanges[$idx],$this->iRanges[$idx+1]);
+                ++$idx;
+            }
+            $value->Set($lbl);
+            $value->Stroke($aImg,$x+$l/2,$txty);
+            $x = $x2;
+            ++$i;++$idx;
+        }
+
+        // Setup circle font
+        $value->SetFont($this->legend->iCircleFontFamily,
+        $this->legend->iCircleFontStyle,
+        $this->legend->iCircleFontSize*$scaling);
+        $value->SetColor($this->legend->iCircleFontColor);
+
+        // Stroke 0-circle text
+        $value->Set($this->legend->iZCircleTxt);
+        $value->SetAlign('center','center');
+        $value->ParagraphAlign('center');
+        $value->Stroke($aImg,$xc,$yc);
+
+        // Setup circle font
+        $value->SetFont($this->legend->iTxtFontFamily,
+        $this->legend->iTxtFontStyle,
+        $this->legend->iTxtFontSize*$scaling);
+        $value->SetColor($this->legend->iTxtFontColor);
+
+        // Draw the text under the legend
+        $value->Set($this->legend->iTxt);
+        $value->SetAlign('center','top');
+        $value->SetParagraphAlign('center');
+        $value->Stroke($aImg,$xcenter,$y2+$this->legend->iTxtMargin*$scaling);
+    }
+
+    function SetAutoScaleAngle($aIsRegRose=true) {
+
+        // If the user already has manually set an angle don't
+        // trye to find a position
+        if( is_numeric($this->scale->iAngle) )
+            return;
+
+        if( $aIsRegRose ) {
+
+            // Create a complete data for all directions
+            // and translate string directions to ordinal values.
+            // This will much simplify the logic below
+            for( $i=0; $i < 16; ++$i ) {
+                $dtxt = $this->iAllDirectionLabels[$i];
+                if( !empty($this->iData[$dtxt]) ) {
+                    $data[$i] = $this->iData[$dtxt];
+                }
+                elseif( !empty($this->iData[strtolower($dtxt)]) ) {
+                    $data[$i] = $this->iData[strtolower($dtxt)];
+                }
+                elseif( !empty($this->iData[$i]) ) {
+                    $data[$i] = $this->iData[$i];
+                }
+                else {
+                    $data[$i] = array();
+                }
+            }
+
+            // Find the leg which has the lowest weighted sum of number of data around it
+            $c0 = array_sum($data[0]);
+            $c1 = array_sum($data[1]);
+            $found = 1;
+            $min = $c0+$c1*100; // Initialize to a high value
+            for( $i=1; $i < 15; ++$i ) {
+                $c2 = array_sum($data[$i+1]);
+
+                // Weight the leg we will use more to give preference
+                // to a short middle leg even if the 3 way sum is similair
+                $w = $c0 + 3*$c1 + $c2 ;
+                if( $w < $min ) {
+                    $min = $w;
+                    $found = $i;
+                }
+                $c0 = $c1;
+                $c1 = $c2;
+            }
+            $this->scale->iAngle = $found*22.5;
+        }
+        else {
+            $n = count($this->iData);
+            foreach( $this->iData as $dir => $leg ) {
+                if( !is_numeric($dir) ) {
+                    $pos = array_search(strtoupper($dir),$this->iAllDirectionLabels);
+                    if( $pos !== false ) {
+                        $dir = $pos*22.5;
+                    }
+                }
+                $data[round($dir)] = $leg;
+            }
+
+            // Get all the angles for the data and sort it
+            $keys = array_keys($data);
+            sort($keys, SORT_NUMERIC);
+
+            $n = count($data);
+            $found = false;
+            $max = 0 ;
+            for( $i=0; $i < 15; ++$i ) {
+                $try_a = round(22.5*$i);
+
+                if( $try_a > $keys[$n-1] ) break;
+
+                if( in_array($try_a,$keys) ) continue;
+
+                // Find the angle just lower than this
+                $j=0;
+                while( $j < $n && $keys[$j] <= $try_a ) ++$j;
+                if( $j == 0 ) {
+                    $kj = 0; $keys[$n-1];
+                    $d1 = 0; abs($kj-$try_a);
+                }
+                else {
+                    --$j;
+                    $kj = $keys[$j];
+                    $d1 = abs($kj-$try_a);
+                }
+
+                // Find the angle just larger than this
+                $l=$n-1;
+                while( $l >= 0 && $keys[$l] >= $try_a ) --$l;
+                if( $l == $n-1) {
+                    $kl = $keys[0];
+                    $d2 = abs($kl-$try_a);
+                }
+                else {
+                    ++$l;
+                    $kl = $keys[$l];
+                    $d2 = abs($kl-$try_a);
+                }
+
+                // Weight the distance so that legs with large spread
+                // gets a better weight
+                $w = $d1 + $d2;
+                if( $i == 0 ) {
+                    $w = round(1.4 * $w);
+                }
+                $diff = abs($d1 - $d2);
+                $w *= (360-$diff);
+                if( $w > $max ) {
+                    $found = $i;
+                    $max = $w;
+                }
+            }
+
+            $a = $found*22.5;
+
+            // Some heuristics to have some preferred positions
+            if( $keys[$n-1] < 25 ) $a = 45;
+            elseif( $keys[0] > 60 ) $a = 45;
+            elseif( $keys[0] > 25 && $keys[$n-1] < 340 ) $a = 0;
+            elseif( $keys[$n-1] < 75 ) $a = 90;
+            elseif( $keys[$n-1] < 120 ) $a = 135;
+            elseif( $keys[$n-1] < 160 ) $a = 180;
+
+            $this->scale->iAngle = $a ;
+        }
+    }
+
+    function NormAngle($a) {
+        while( $a > 360 ) {
+            $a -= 360;
+        }
+        return $a;
+    }
+
+    function SetLabelPosition($aPos) {
+        $this->iLabelPositioning  = $aPos ;
+    }
+
+    function _StrokeFreeRose($dblImg,$value,$scaling,$xc,$yc,$r,$ri) {
+
+        // Plot radial grid lines and remember the end position
+        // and the angle for later use when plotting the labels
+        if( $this->iType != WINDROSE_TYPEFREE ) {
+            JpGraphError::RaiseL(22008); //('Internal error: Trying to plot free Windrose even though type is not a free windorose');
+        }
+
+        // Check if we should auto-position the angle for the
+        // labels. Basically we try to find a firection with smallest
+        // (or none) data.
+        $this->SetAutoScaleAngle(false);
+
+        $nlc = count($this->iLegColors);
+        $nlw = count($this->iLegweights);
+
+        // Stroke grid lines for directions and remember the
+        // position for the labels
+        $txtpos=array();
+        $num = count($this->iData);
+
+        $keys = array_keys($this->iData);
+
+        foreach( $this->iData as $dir => $legdata ) {
+            if( in_array($dir,$this->iAllDirectionLabels,true) === true) {
+                $a = $this->iStandardDirections[strtoupper($dir)];
+                if( in_array($a*180/M_PI,$keys) ) {
+                    JpGraphError::RaiseL(22009,round($a*180/M_PI));
+                    //('You have specified the same direction twice, once with an angle and once with a compass direction ('.$a*180/M_PI.' degrees.)');
+                }
+            }
+            elseif( is_numeric($dir) ) {
+                $this->NormAngle($dir);
+
+                if( $this->iOrdinalEncoding == KEYENCODING_CLOCKWISE ) {
+                    $dir = 360-$dir;
+                }
+
+                $a = $dir * M_PI/180;
+            }
+            else {
+                JpGraphError::RaiseL(22010);//('Direction must either be a numeric value or one of the 16 compass directions');
+            }
+
+            $xxc = round($xc + cos($a)*$ri);
+            $yyc = round($yc - sin($a)*$ri);
+            $x = round($xc + cos($a)*$r);
+            $y = round($yc - sin($a)*$r);
+            if( empty($this->iRadialColorArray[$dir]) ) {
+                $dblImg->SetColor($this->iGridColor2);
+            }
+            else {
+                $dblImg->SetColor($this->iRadialColorArray[$dir]);
+            }
+            if( empty($this->iRadialWeightArray[$dir]) ) {
+                $dblImg->SetLineWeight($this->iRadialGridWeight);
+            }
+            else {
+                $dblImg->SetLineWeight($this->iRadialWeightArray[$dir]);
+            }
+            if( empty($this->iRadialStyleArray[$dir]) ) {
+                $dblImg->SetLineStyle($this->iRadialGridStyle);
+            }
+            else {
+                $dblImg->SetLineStyle($this->iRadialStyleArray[$dir]);
+            }
+            $dblImg->StyleLine($xxc,$yyc,$x,$y);
+            $txtpos[] = array($x,$y,$a);
+        }
+        $dblImg->SetLineWeight(1);
+
+        // Setup labels
+        $lr = $scaling * $this->iLabelMargin;
+
+        if( $this->iLabelPositioning == LBLPOSITION_EDGE ) {
+            $value->SetAlign('left','top');
+        }
+        else {
+            $value->SetAlign('center','center');
+            $value->SetMargin(0);
+        }
+
+        for($i=0; $i < $num; ++$i ) {
+
+            list($x,$y,$a) = $txtpos[$i];
+
+            // Determine the label
+
+            $da = $a*180/M_PI;
+            if( $this->iOrdinalEncoding == KEYENCODING_CLOCKWISE ) {
+                $da = 360 - $da;
+            }
+
+            //$da = 360-$da;
+            
+            if( !empty($this->iLabels[$keys[$i]]) ) {
+                $lbl = $this->iLabels[$keys[$i]];
+            }
+            else {
+                $lbl = sprintf($this->iLabelFormatString,$da);
+            }
+
+            if( $this->iLabelPositioning == LBLPOSITION_CENTER ) {
+                $dx = $dy = 0;
+            }
+            else {
+                // LBLPOSIITON_EDGE
+                if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0;
+                if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI;
+                if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1;
+                if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI);
+
+                if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI;
+                if( $a<=M_PI/4 ) $dy=(0.5+$a*2/M_PI);
+                if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1;
+                if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI);
+                if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0;
+            }
+
+            $value->Set($lbl);
+            $th = $value->GetHeight($dblImg);
+            $tw = $value->GetWidth($dblImg);
+            $xt=round($lr*cos($a)+$x) - $dx*$tw;
+            $yt=round($y-$lr*sin($a)) - $dy*$th;
+
+            $value->Stroke($dblImg,$xt,$yt);
+        }
+
+        if( __DEBUG ) {
+            $dblImg->SetColor('red');
+            $dblImg->Circle($xc,$yc,$lr+$r);
+        }
+
+        // Stroke all the legs
+        reset($this->iData);
+        $i=0;
+        foreach($this->iData as $dir => $legdata) {
+            $legdata = array_slice($legdata,1);
+            $nn = count($legdata);
+
+            $a = $txtpos[$i][2];
+            $rri = $ri/$scaling;
+            for( $j=0; $j < $nn; ++$j ) {
+                // We want the non scaled original radius
+                $legr = $this->scale->RelTranslate($legdata[$j],$r/$scaling,$ri/$scaling) ;
+                $this->_StrokeWindLeg($dblImg, $xc, $yc, $a,
+                $rri *$scaling,
+                $legr *$scaling,
+                $this->iLegweights[$j % $nlw] * $scaling,
+                $this->iLegColors[$j % $nlc]);
+                $rri += $legr;
+            }
+            ++$i;
+        }
+    }
+
+    // Translate potential string specified compass labels to their
+    // corresponding index.
+    function FixupIndexes($aDataArray,$num) {
+        $ret = array();
+        $keys = array_keys($aDataArray);
+        foreach($aDataArray as $idx => $data) {
+            if( is_string($idx) ) {
+                $idx = strtoupper($idx);
+                $res = array_search($idx,$this->iAllDirectionLabels);
+                if( $res === false ) {
+                    JpGraphError::RaiseL(22011,$idx); //('Windrose index must be numeric or direction label. You have specified index='.$idx);
+                }
+                $idx = $res;
+                if( $idx % (16 / $num) !== 0 ) {
+                    JpGraphError::RaiseL(22012); //('Windrose radial axis specification contains a direction which is not enabled.');
+                }
+                $idx /= (16/$num) ;
+
+                if( in_array($idx,$keys,1) ) {
+                    JpgraphError::RaiseL(22013,$idx); //('You have specified the look&feel for the same compass direction twice, once with text and once with index (Index='.$idx.')');
+                }
+            }
+            if( $idx < 0 || $idx > 15 ) {
+                JpgraphError::RaiseL(22014); //('Index for copmass direction must be between 0 and 15.');
+            }
+            $ret[$idx] = $data;
+        }
+        return $ret;
+    }
+
+    function _StrokeRegularRose($dblImg,$value,$scaling,$xc,$yc,$r,$ri) {
+        // _StrokeRegularRose($dblImg,$xc,$yc,$r,$ri)
+        // Plot radial grid lines and remember the end position
+        // and the angle for later use when plotting the labels
+        switch( $this->iType ) {
+            case WINDROSE_TYPE4:
+                $num = 4; break;
+            case WINDROSE_TYPE8:
+                $num = 8; break;
+            case WINDROSE_TYPE16:
+                $num = 16; break;
+            default:
+                JpGraphError::RaiseL(22015);//('You have specified an undefined Windrose plot type.');
+        }
+
+        // Check if we should auto-position the angle for the
+        // labels. Basically we try to find a firection with smallest
+        // (or none) data.
+        $this->SetAutoScaleAngle(true);
+
+        $nlc = count($this->iLegColors);
+        $nlw = count($this->iLegweights);
+
+        $this->iRadialColorArray = $this->FixupIndexes($this->iRadialColorArray,$num);
+        $this->iRadialWeightArray = $this->FixupIndexes($this->iRadialWeightArray,$num);
+        $this->iRadialStyleArray = $this->FixupIndexes($this->iRadialStyleArray,$num);
+
+        $txtpos=array();
+        $a = 2*M_PI/$num;
+        $dblImg->SetColor($this->iGridColor2);
+        $dblImg->SetLineStyle($this->iRadialGridStyle);
+        $dblImg->SetLineWeight($this->iRadialGridWeight);
+
+        // Translate any name specified directions to the index
+        // so we can easily use it in the loop below
+        for($i=0; $i < $num; ++$i ) {
+            $xxc = round($xc + cos($a*$i)*$ri);
+            $yyc = round($yc - sin($a*$i)*$ri);
+            $x = round($xc + cos($a*$i)*$r);
+            $y = round($yc - sin($a*$i)*$r);
+            if( empty($this->iRadialColorArray[$i]) ) {
+                $dblImg->SetColor($this->iGridColor2);
+            }
+            else {
+                $dblImg->SetColor($this->iRadialColorArray[$i]);
+            }
+            if( empty($this->iRadialWeightArray[$i]) ) {
+                $dblImg->SetLineWeight($this->iRadialGridWeight);
+            }
+            else {
+                $dblImg->SetLineWeight($this->iRadialWeightArray[$i]);
+            }
+            if( empty($this->iRadialStyleArray[$i]) ) {
+                $dblImg->SetLineStyle($this->iRadialGridStyle);
+            }
+            else {
+                $dblImg->SetLineStyle($this->iRadialStyleArray[$i]);
+            }
+
+            $dblImg->StyleLine($xxc,$yyc,$x,$y);
+            $txtpos[] = array($x,$y,$a*$i);
+        }
+        $dblImg->SetLineWeight(1);
+
+        $lr = $scaling * $this->iLabelMargin;
+        if( $this->iLabelPositioning == LBLPOSITION_CENTER ) {
+            $value->SetAlign('center','center');
+        }
+        else {
+            $value->SetAlign('left','top');
+            $value->SetMargin(0);
+            $lr /= 2 ;
+        }
+
+        for($i=0; $i < $num; ++$i ) {
+            list($x,$y,$a) = $txtpos[$i];
+
+            // Set the position of the label
+            if( $this->iLabelPositioning == LBLPOSITION_CENTER ) {
+                $dx = $dy = 0;
+            }
+            else {
+                // LBLPOSIITON_EDGE
+                if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0;
+                if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI;
+                if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1;
+                if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI);
+
+                if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI;
+                if( $a<=M_PI/4 ) $dy=(0.5+$a*2/M_PI);
+                if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1;
+                if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI);
+                if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0;
+            }
+
+            $value->Set($this->iAllDirectionLabels[$i*(16/$num)]);
+            $th = $value->GetHeight($dblImg);
+            $tw = $value->GetWidth($dblImg);
+            $xt=round($lr*cos($a)+$x) - $dx*$tw;
+            $yt=round($y-$lr*sin($a)) - $dy*$th;
+
+            $value->Stroke($dblImg,$xt,$yt);
+        }
+
+        if( __DEBUG ) {
+            $dblImg->SetColor("red");
+            $dblImg->Circle($xc,$yc,$lr+$r);
+        }
+
+        // Stroke all the legs
+        reset($this->iData);
+        $keys = array_keys($this->iData);
+        foreach($this->iData as $idx => $legdata) {
+            $legdata = array_slice($legdata,1);
+            $nn = count($legdata);
+            if( is_string($idx) ) {
+                $idx = strtoupper($idx);
+                $idx = array_search($idx,$this->iAllDirectionLabels);
+                if( $idx === false ) {
+                    JpGraphError::RaiseL(22016);//('Windrose leg index must be numeric or direction label.');
+                }
+                if( $idx % (16 / $num) !== 0 ) {
+                    JpGraphError::RaiseL(22017);//('Windrose data contains a direction which is not enabled. Please adjust what labels are displayed.');
+                }
+                $idx /= (16/$num) ;
+
+                if( in_array($idx,$keys,1) ) {
+                    JpgraphError::RaiseL(22018,$idx);//('You have specified data for the same compass direction twice, once with text and once with index (Index='.$idx.')');
+
+                }
+            }
+            if( $idx < 0 || $idx > 15 ) {
+                JpgraphError::RaiseL(22019);//('Index for direction must be between 0 and 15. You can\'t specify angles for a Regular Windplot, only index and compass directions.');
+            }
+            $a = $idx * (360 / $num) ;
+            $a *= M_PI/180.0;
+            $rri = $ri/$scaling;
+            for( $j=0; $j < $nn; ++$j ) {
+                // We want the non scaled original radius
+                $legr = $this->scale->RelTranslate($legdata[$j], $r/$scaling,$ri/$scaling) ;
+                $this->_StrokeWindLeg($dblImg, $xc, $yc, $a,
+                $rri *$scaling,
+                $legr *$scaling,
+                $this->iLegweights[$j % $nlw] * $scaling,
+                $this->iLegColors[$j % $nlc]);
+                $rri += $legr;
+            }
+        }
+    }
+
+
+    function getWidth($aImg) {
+
+        $scaling = 1;//$this->iAntiAlias ? 2 : 1 ;
+       	if( $this->iSize > 0 && $this->iSize < 1 ) {
+			$this->iSize *= min($aImg->width,$aImg->height);
+       	}
+
+
+        $value = new Text();
+        $value->SetFont($this->iFontFamily,$this->iFontStyle,$this->iFontSize*$scaling);
+        $value->SetColor($this->iFontColor);
+        // Setup extra size around the graph needed so that the labels
+        // doesn't get cut. For this we need to find the largest label.
+        // The code below gives a possible a little to large margin. The
+        // really, really proper way would be to account for what angle
+        // the label are at
+        $n = count($this->iLabels);
+        if( $n > 0 ) {
+            $maxh=0;$maxw=0;
+            foreach($this->iLabels as $key => $lbl) {
+                $value->Set($lbl);
+                $maxw = max($maxw,$value->GetWidth($aImg));
+            }
+        }
+        else {
+            $value->Set('888.888'); // Dummy value to get width/height
+            $maxw = $value->GetWidth($aImg);
+        }
+        // Add an extra margin of 50% the font size
+        $maxw += round($this->iFontSize*$scaling * 0.4) ;
+
+        $valxmarg = 1.5*$maxw+2*$this->iLabelMargin*$scaling;
+        $w = round($this->iSize*$scaling + $valxmarg);
+
+        // Make sure that the width of the legend fits
+        $legendwidth = $this->_StrokeLegend($aImg,0,0,$scaling,true)+10*$scaling;
+        $w = max($w,$legendwidth);
+
+        return $w;
+    }
+
+    function getHeight($aImg) {
+
+        $scaling = 1;//$this->iAntiAlias ? 2 : 1 ;
+       	if( $this->iSize > 0 && $this->iSize < 1 ) {
+			$this->iSize *= min($aImg->width,$aImg->height);
+       	}
+
+        $value = new Text();
+        $value->SetFont($this->iFontFamily,$this->iFontStyle,$this->iFontSize*$scaling);
+        $value->SetColor($this->iFontColor);
+        // Setup extra size around the graph needed so that the labels
+        // doesn't get cut. For this we need to find the largest label.
+        // The code below gives a possible a little to large margin. The
+        // really, really proper way would be to account for what angle
+        // the label are at
+        $n = count($this->iLabels);
+        if( $n > 0 ) {
+            $maxh=0;$maxw=0;
+            foreach($this->iLabels as $key => $lbl) {
+                $value->Set($lbl);
+                $maxh = max($maxh,$value->GetHeight($aImg));
+            }
+        }
+        else {
+            $value->Set('180.8'); // Dummy value to get width/height
+            $maxh = $value->GetHeight($aImg);
+        }
+        // Add an extra margin of 50% the font size
+        //$maxh += round($this->iFontSize*$scaling * 0.5) ;
+        $valymarg = 2*$maxh+2*$this->iLabelMargin*$scaling;
+
+        $legendheight = round($this->legend->iShow ? 1 : 0);
+        $legendheight *= max($this->legend->iCircleRadius*2,$this->legend->iTxtFontSize*2)+
+        				 $this->legend->iMargin + $this->legend->iBottomMargin + 2;
+        $legendheight *= $scaling;
+        $h = round($this->iSize*$scaling + $valymarg) + $legendheight ;
+
+        return $h;
+    }
+
+    function Stroke($aGraph) {
+
+		$aImg = $aGraph->img;
+
+		if( $this->iX > 0 && $this->iX < 1 ) {
+			$this->iX = round( $aImg->width * $this->iX ) ;
+		}
+
+       	if( $this->iY > 0 && $this->iY < 1 ) {
+       		$this->iY = round( $aImg->height * $this->iY ) ;
+       	}
+
+       	if( $this->iSize > 0 && $this->iSize < 1 ) {
+			$this->iSize *= min($aImg->width,$aImg->height);
+       	}
+
+       	if( $this->iCenterSize > 0 && $this->iCenterSize < 1 ) {
+			$this->iCenterSize *= $this->iSize;
+       	}
+
+        $this->scale->AutoScale(($this->iSize - $this->iCenterSize)/2, round(2.5*$this->scale->iFontSize));
+
+        $scaling = $this->iAntiAlias ? 2 : 1 ;
+
+        $value = new Text();
+        $value->SetFont($this->iFontFamily,$this->iFontStyle,$this->iFontSize*$scaling);
+        $value->SetColor($this->iFontColor);
+
+        $legendheight = round($this->legend->iShow ? 1 : 0);
+        $legendheight *= max($this->legend->iCircleRadius*2,$this->legend->iTxtFontSize*2)+
+        $this->legend->iMargin + $this->legend->iBottomMargin + 2;
+        $legendheight *= $scaling;
+
+        $w = $scaling*$this->getWidth($aImg);
+        $h = $scaling*$this->getHeight($aImg);
+
+        // Copy back the double buffered image to the proper canvas
+        $ww = $w / $scaling ;
+        $hh = $h / $scaling ;
+
+        // Create the double buffer
+        if( $this->iAntiAlias ) {
+            $dblImg = new RotImage($w,$h);
+            // Set the background color
+            $dblImg->SetColor($this->iColor);
+            $dblImg->FilledRectangle(0,0,$w,$h);
+        }
+        else {
+            $dblImg = $aImg ;
+            // Make sure the ix and it coordinates correpond to the new top left center
+            $dblImg->SetTranslation($this->iX-$w/2, $this->iY-$h/2);
+        }
+
+        if( __DEBUG ) {
+            $dblImg->SetColor('red');
+            $dblImg->Rectangle(0,0,$w-1,$h-1);
+        }
+
+        $dblImg->SetColor('black');
+
+        if( $this->iShowBox ) {
+            $dblImg->SetColor($this->iBoxColor);
+            $old = $dblImg->SetLineWeight($this->iBoxWeight);
+            $dblImg->SetLineStyle($this->iBoxStyle);
+            $dblImg->Rectangle(0,0,$w-1,$h-1);
+            $dblImg->SetLineWeight($old);
+        }
+
+        $xc = round($w/2);
+        $yc = round(($h-$legendheight)/2);
+
+        if( __DEBUG ) {
+            $dblImg->SetColor('red');
+            $old = $dblImg->SetLineWeight(2);
+            $dblImg->Line($xc-5,$yc-5,$xc+5,$yc+5);
+			$dblImg->Line($xc+5,$yc-5,$xc-5,$yc+5);
+			$dblImg->SetLineWeight($old);
+        }
+
+        $this->iSize *= $scaling;
+
+        // Inner circle size
+        $ri = $this->iCenterSize/2 ;
+
+        // Full circle radius
+        $r = round( $this->iSize/2 );
+
+        // Get number of grid circles
+        $n = $this->scale->GetNumCirc();
+
+        // Plot circle grids
+        $ri *= $scaling ;
+        $rr = round(($r-$ri)/$n);
+        for( $i = 1; $i <= $n; ++$i ) {
+            $this->_ThickCircle($dblImg,$xc,$yc,$rr*$i+$ri,
+            $this->iCircGridWeight,$this->iGridColor1);
+        }
+
+        $num = 0 ;
+
+        if( $this->iType == WINDROSE_TYPEFREE ) {
+            $this->_StrokeFreeRose($dblImg,$value,$scaling,$xc,$yc,$r,$ri);
+        }
+        else {
+            // Check if we need to re-code the interpretation of the ordinal
+            // number in the data. Internally ordinal value 0 is East and then
+            // counted anti-clockwise. The user might choose an encoding
+            // that have 0 being the first axis to the right of the "N" axis and then
+            // counted clock-wise
+            if( $this->iOrdinalEncoding == KEYENCODING_CLOCKWISE ) {
+                if( $this->iType == WINDROSE_TYPE16 ) {
+                    $const1 = 19; $const2 = 16;
+                }
+                elseif( $this->iType == WINDROSE_TYPE8 ) {
+                    $const1 = 9; $const2 = 8;
+                }
+                else {
+                    $const1 = 4; $const2 = 4;
+                }
+                $tmp = array();
+                $n=count($this->iData);
+                foreach( $this->iData as $key => $val ) {
+                    if( is_numeric($key) ) {
+                        $key = ($const1 - $key) % $const2 ;
+                    }
+                    $tmp[$key] = $val;
+                }
+                $this->iData = $tmp;
+            }
+            $this->_StrokeRegularRose($dblImg,$value,$scaling,$xc,$yc,$r,$ri);
+        }
+
+        // Stroke the labels
+        $this->scale->iFontSize *= $scaling;
+        $this->scale->iZFontSize *= $scaling;
+        $this->scale->StrokeLabels($dblImg,$xc,$yc,$ri,$rr);
+
+        // Stroke the inner circle again since the legs
+        // might have written over it
+        $this->_ThickCircle($dblImg,$xc,$yc,$ri,$this->iCircGridWeight,$this->iGridColor1);
+
+        if( $ww > $aImg->width ) {
+            JpgraphError::RaiseL(22020);
+            //('Windrose plot is too large to fit the specified Graph size. Please use WindrosePlot::SetSize() to make the plot smaller or increase the size of the Graph in the initial WindroseGraph() call.');
+        }
+
+        $x = $xc;
+        $y = $h;
+        $this->_StrokeLegend($dblImg,$x,$y,$scaling);
+
+        if( $this->iAntiAlias ) {
+            $aImg->Copy($dblImg->img, $this->iX-$ww/2, $this->iY-$hh/2, 0, 0, $ww,$hh, $w,$h);
+        }
+
+        // We need to restore the translation matrix
+        $aImg->SetTranslation(0,0);
+
+    }
+
+}
+
+//============================================================
+// CLASS WindroseGraph
+//============================================================
+class WindroseGraph extends Graph {
+    private $posx, $posy;
+    public $plots=array();
+
+    function __construct($width=300,$height=200,$cachedName="",$timeout=0,$inline=1) {
+        parent::__construct($width,$height,$cachedName,$timeout,$inline);
+        $this->posx=$width/2;
+        $this->posy=$height/2;
+        $this->SetColor('white');
+        $this->title->SetFont(FF_VERDANA,FS_NORMAL,12);
+        $this->title->SetMargin(8);
+        $this->subtitle->SetFont(FF_VERDANA,FS_NORMAL,10);
+        $this->subtitle->SetMargin(0);
+        $this->subsubtitle->SetFont(FF_VERDANA,FS_NORMAL,8);
+        $this->subsubtitle->SetMargin(0);
+    }
+
+    function StrokeTexts() {
+        if( $this->texts != null ) {
+            $n = count($this->texts);
+            for($i=0; $i < $n; ++$i ) {
+                $this->texts[$i]->Stroke($this->img);
+            }
+        }
+    }
+
+    function StrokeIcons() {
+        if( $this->iIcons != null ) {
+            $n = count($this->iIcons);
+            for( $i=0; $i < $n; ++$i ) {
+                // Since Windrose graphs doesn't have any linear scale the position of
+                // each icon has to be given as absolute coordinates
+                $this->iIcons[$i]->_Stroke($this->img);
+            }
+        }
+    }
+
+    //---------------
+    // PUBLIC METHODS
+    function Add($aObj) {
+        if( is_array($aObj) && count($aObj) > 0 ) {
+            $cl = $aObj[0];
+        }
+        else {
+            $cl = $aObj;
+        }
+        if( $cl instanceof Text ) {
+            $this->AddText($aObj);
+        }
+        elseif( $cl instanceof IconPlot ) {
+            $this->AddIcon($aObj);
+        }
+        elseif( ($cl instanceof WindrosePlot) || ($cl instanceof LayoutRect) || ($cl instanceof LayoutHor)) {
+            $this->plots[] = $aObj;
+        }
+        else {
+            JpgraphError::RaiseL(22021);
+        }
+    }
+
+    function AddText($aTxt,$aToY2=false) {
+        parent::AddText($aTxt);
+    }
+
+    function SetColor($c) {
+        $this->SetMarginColor($c);
+    }
+
+    // Method description
+    function Stroke($aStrokeFileName="") {
+
+        // If the filename is the predefined value = '_csim_special_'
+        // we assume that the call to stroke only needs to do enough
+        // to correctly generate the CSIM maps.
+        // We use this variable to skip things we don't strictly need
+        // to do to generate the image map to improve performance
+        // as best we can. Therefore you will see a lot of tests !$_csim in the
+        // code below.
+        $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE);
+
+        // We need to know if we have stroked the plot in the
+        // GetCSIMareas. Otherwise the CSIM hasn't been generated
+        // and in the case of GetCSIM called before stroke to generate
+        // CSIM without storing an image to disk GetCSIM must call Stroke.
+        $this->iHasStroked = true;
+
+        if( $this->background_image != "" || $this->background_cflag != "" ) {
+            $this->StrokeFrameBackground();
+        }
+        else {
+            $this->StrokeFrame();
+        }
+
+        // n holds number of plots
+        $n = count($this->plots);
+        for($i=0; $i < $n ; ++$i) {
+     		$this->plots[$i]->Stroke($this);
+        }
+
+        $this->footer->Stroke($this->img);
+        $this->StrokeIcons();
+        $this->StrokeTexts();
+        $this->StrokeTitles();
+
+        // If the filename is given as the special "__handle"
+        // then the image handler is returned and the image is NOT
+        // streamed back
+        if( $aStrokeFileName == _IMG_HANDLER ) {
+            return $this->img->img;
+        }
+        else {
+            // Finally stream the generated picture
+            $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,
+            $aStrokeFileName);
+        }
+    }
+
+} // Class
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/themes/AquaTheme.class.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/themes/AquaTheme.class.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/themes/AquaTheme.class.php	(revision 266)
@@ -0,0 +1,201 @@
+<?php
+
+/**
+* Aqua Theme class
+*/
+class AquaTheme extends Theme 
+{
+    protected $font_color       = '#0044CC';
+    protected $background_color = '#DDFFFF';
+    protected $axis_color       = '#0066CC';
+    protected $grid_color       = '#3366CC';
+
+    function GetColorList() {
+        return array(
+            '#183152',
+            '#C4D7ED',
+            '#375D81',
+            '#ABC8E2',
+            '#E1E6FA',
+            '#9BBAB2',
+            '#3B4259',
+            '#0063BC',
+            '#1D5A73',
+            '#ABABFF',
+            '#27ADC5',
+            '#EDFFCC',
+
+/*
+
+            '#66FFFF',
+            '#00AABB',
+            '#00FFCC',
+            '#33CCFF',
+            '#008866',
+            '#99FFFF',
+            '#0099FF',
+            '#99FFCC',
+            '#3399FF',
+            '#2277FF',
+            '#445588',
+            '#003388',
+            '#338877',
+            '#55DDFF',
+            '#00FF99',
+            '#BBBBBB',
+            '#77AAFF',
+            '#00FFCC',
+*/
+        );
+    }
+
+    function SetupGraph($graph) {
+
+        // graph
+        /*
+        $img = $graph->img;
+        $height = $img->height;
+        $graph->SetMargin($img->left_margin, $img->right_margin, $img->top_margin, $height * 0.25);
+        */
+        $graph->SetFrame(false);
+        $graph->SetMarginColor('white');
+        $graph->SetBackgroundGradient($this->background_color, '#FFFFFF', GRAD_HOR, BGRAD_PLOT);
+
+        // legend
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetFillColor('white');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // xaxis
+        $graph->xaxis->title->SetColor($this->font_color);  
+        $graph->xaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->xaxis->SetTickSide(SIDE_BOTTOM);
+        $graph->xaxis->SetLabelMargin(10);
+                
+        // yaxis
+        $graph->yaxis->title->SetColor($this->font_color);  
+        $graph->yaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->yaxis->SetTickSide(SIDE_LEFT);
+        $graph->yaxis->SetLabelMargin(8);
+        $graph->yaxis->HideLine();
+        $graph->yaxis->HideTicks();
+        $graph->xaxis->SetTitleMargin(15);
+
+        // grid
+        $graph->ygrid->SetColor($this->grid_color);
+        $graph->ygrid->SetLineStyle('dotted');
+
+
+        // font
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+//        $graph->img->SetAntiAliasing();
+    }
+
+
+    function SetupPieGraph($graph) {
+
+        // graph
+        $graph->SetFrame(false);
+
+        // legend
+        $graph->legend->SetFillColor('white');
+
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.80, 'center', 'top');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(4);
+
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // title
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+        $graph->SetAntiAliasing();
+    }
+
+
+    function PreStrokeApply($graph) {
+        if ($graph->legend->HasItems()) {
+            $img = $graph->img;
+            $graph->SetMargin(
+                $img->raw_left_margin, 
+                $img->raw_right_margin, 
+                $img->raw_top_margin, 
+                is_numeric($img->raw_bottom_margin) ? $img->raw_bottom_margin : $img->height * 0.25
+            );
+        }
+    }
+
+    function ApplyPlot($plot) {
+
+        switch (get_class($plot))
+        { 
+            case 'GroupBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'AccBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'BarPlot':
+            {
+                $plot->Clear();
+
+                $color = $this->GetNextColor();
+                $plot->SetColor($color);
+                $plot->SetFillColor($color);
+                //$plot->SetShadow();
+                break;
+            }
+
+            case 'LinePlot':
+            {
+                $plot->Clear();
+                $plot->SetColor($this->GetNextColor());
+                $plot->SetWeight(2);
+//                $plot->SetBarCenter();
+                break;
+            }
+
+            case 'PiePlot':
+            {
+                $plot->SetCenter(0.5, 0.45);
+                $plot->ShowBorder(false);
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+
+            case 'PiePlot3D':
+            {
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+    
+            default:
+            {
+            }
+        }
+    }
+}
+
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/themes/GreenTheme.class.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/themes/GreenTheme.class.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/themes/GreenTheme.class.php	(revision 266)
@@ -0,0 +1,182 @@
+<?php
+
+/**
+* Green Theme class
+*/
+class GreenTheme extends Theme 
+{
+    private $font_color       = '#009900';
+    private $background_color = '#EEFFDD';
+    private $axis_color       = '#00CC00';
+    private $grid_color       = '#33CC33';
+
+    function GetColorList() {
+        return array(
+            '#66CC00',
+            '#009900',
+            '#AAFF77',
+            '#559922',
+            '#00CC33',
+            '#99FF00',
+            '#009966',
+            '#00FF99',
+            '#99BB66',
+            '#33FF00',
+            '#DDFFBB',
+            '#669933',
+            '#BBDDCC',
+            '#77CCBB',
+            '#668833',
+            '#BBEE66',
+        );
+    }
+
+    function SetupGraph($graph) {
+
+        // graph
+        /*
+        $img = $graph->img;
+        $height = $img->height;
+        $graph->SetMargin($img->left_margin, $img->right_margin, $img->top_margin, $height * 0.25);
+        */
+        $graph->SetFrame(false);
+        $graph->SetMarginColor('white');
+        $graph->SetBackgroundGradient($this->background_color, '#FFFFFF', GRAD_HOR, BGRAD_PLOT);
+
+        // legend
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetFillColor('white');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // xaxis
+        $graph->xaxis->title->SetColor($this->font_color);  
+        $graph->xaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->xaxis->SetTickSide(SIDE_BOTTOM);
+        $graph->xaxis->SetLabelMargin(10);
+                
+        // yaxis
+        $graph->yaxis->title->SetColor($this->font_color);  
+        $graph->yaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->yaxis->SetTickSide(SIDE_LEFT);
+        $graph->yaxis->SetLabelMargin(8);
+        $graph->yaxis->HideLine();
+        $graph->yaxis->HideTicks();
+        $graph->xaxis->SetTitleMargin(15);
+
+        // grid
+        $graph->ygrid->SetColor($this->grid_color);
+        $graph->ygrid->SetLineStyle('dotted');
+
+
+        // font
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+//        $graph->img->SetAntiAliasing();
+    }
+
+
+    function SetupPieGraph($graph) {
+
+        // graph
+        $graph->SetFrame(false);
+
+        // legend
+        $graph->legend->SetFillColor('white');
+        /*
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        */
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // title
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+        $graph->SetAntiAliasing();
+    }
+
+
+    function PreStrokeApply($graph) {
+        if ($graph->legend->HasItems()) {
+            $img = $graph->img;
+            $graph->SetMargin(
+                $img->raw_left_margin, 
+                $img->raw_right_margin, 
+                $img->raw_top_margin, 
+                is_numeric($img->raw_bottom_margin) ? $img->raw_bottom_margin : $img->height * 0.25
+            );
+        }
+    }
+
+    function ApplyPlot($plot) {
+
+        switch (get_class($plot))
+        { 
+            case 'GroupBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'AccBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'BarPlot':
+            {
+                $plot->Clear();
+
+                $color = $this->GetNextColor();
+                $plot->SetColor($color);
+                $plot->SetFillColor($color);
+                $plot->SetShadow('red', 3, 4, false);
+                break;
+            }
+
+            case 'LinePlot':
+            {
+                $plot->Clear();
+
+                $plot->SetColor($this->GetNextColor().'@0.4');
+                $plot->SetWeight(2);
+                break;
+            }
+
+            case 'PiePlot':
+            {
+                $plot->ShowBorder(false);
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+
+            case 'PiePlot3D':
+            {
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+    
+            default:
+            {
+            }
+        }
+    }
+}
+
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/themes/OceanTheme.class.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/themes/OceanTheme.class.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/themes/OceanTheme.class.php	(revision 266)
@@ -0,0 +1,184 @@
+<?php
+
+/**
+* Ocean Theme class
+*/
+class OceanTheme extends Theme 
+{
+    protected $font_color       = '#0066FF';
+    private $background_color = '#DDEEFF';
+    private $axis_color       = '#0000CC';
+    private $grid_color       = '#3333CC';
+
+    function GetColorList() {
+        return array(
+            '#0066FF',
+            '#CCCCFF',
+            '#0000FF',
+            '#3366FF',
+            '#33CCFF',
+            '#660088',
+            '#3300FF',
+            '#0099FF',
+            '#6633FF',
+            '#0055EE',
+            '#2277EE',
+            '#3300FF',
+            '#AA00EE',
+            '#778899',
+            '#114499',
+            '#7744EE',
+            '#002288',
+            '#6666FF',
+        );
+    }
+
+    function SetupGraph($graph) {
+
+        // graph
+        /*
+        $img = $graph->img;
+        $height = $img->height;
+        $graph->SetMargin($img->left_margin, $img->right_margin, $img->top_margin, $height * 0.25);
+        */
+        $graph->SetFrame(false);
+        $graph->SetMarginColor('white');
+        $graph->SetBackgroundGradient($this->background_color, '#FFFFFF', GRAD_HOR, BGRAD_PLOT);
+
+        // legend
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetFillColor('white');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // xaxis
+        $graph->xaxis->title->SetColor($this->font_color);  
+        $graph->xaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->xaxis->SetTickSide(SIDE_BOTTOM);
+        $graph->xaxis->SetLabelMargin(10);
+                
+        // yaxis
+        $graph->yaxis->title->SetColor($this->font_color);  
+        $graph->yaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->yaxis->SetTickSide(SIDE_LEFT);
+        $graph->yaxis->SetLabelMargin(8);
+        $graph->yaxis->HideLine();
+        $graph->yaxis->HideTicks();
+        $graph->xaxis->SetTitleMargin(15);
+
+        // grid
+        $graph->ygrid->SetColor($this->grid_color);
+        $graph->ygrid->SetLineStyle('dotted');
+
+
+        // font
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+//        $graph->img->SetAntiAliasing();
+    }
+
+
+    function SetupPieGraph($graph) {
+
+        // graph
+        $graph->SetFrame(false);
+
+        // legend
+        $graph->legend->SetFillColor('white');
+        /*
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        */
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // title
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+        $graph->SetAntiAliasing();
+    }
+
+
+    function PreStrokeApply($graph) {
+        if ($graph->legend->HasItems()) {
+            $img = $graph->img;
+            $graph->SetMargin(
+                $img->raw_left_margin, 
+                $img->raw_right_margin, 
+                $img->raw_top_margin, 
+                is_numeric($img->raw_bottom_margin) ? $img->raw_bottom_margin : $img->height * 0.25
+            );
+        }
+    }
+
+    function ApplyPlot($plot) {
+
+        switch (get_class($plot))
+        { 
+            case 'GroupBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'AccBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'BarPlot':
+            {
+                $plot->Clear();
+
+                $color = $this->GetNextColor();
+                $plot->SetColor($color);
+                $plot->SetFillColor($color);
+                $plot->SetShadow('red', 3, 4, false);
+                break;
+            }
+
+            case 'LinePlot':
+            {
+                $plot->Clear();
+
+                $plot->SetColor($this->GetNextColor());
+                $plot->SetWeight(2);
+                break;
+            }
+
+            case 'PiePlot':
+            {
+                $plot->ShowBorder(false);
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+
+            case 'PiePlot3D':
+            {
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+    
+            default:
+            {
+            }
+        }
+    }
+}
+
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/themes/OrangeTheme.class.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/themes/OrangeTheme.class.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/themes/OrangeTheme.class.php	(revision 266)
@@ -0,0 +1,184 @@
+<?php
+
+/**
+* Orange Theme class
+*/
+class OrangeTheme extends Theme 
+{
+    private $font_color       = '#CC4400';
+    private $background_color = '#FFEEDD';
+    private $axis_color       = '#CC6600';
+    private $grid_color       = '#CC6633';
+
+    function GetColorList() {
+        return array(
+            '#FF9900',
+            '#FFCC00',
+            '#AA6600',
+            '#CCCC00',
+            '#CC6600',
+            '#FFFF66',
+            '#CCFF00',
+            '#CC3300',
+            '#669933',
+            '#EE7700',
+            '#AAEE33',
+            '#77AA00',
+            '#CCFF99',
+            '#FF6633',
+            '#885500',
+            '#AADD00',
+            '#99CC44',
+            '#887711',
+        );
+    }
+
+    function SetupGraph($graph) {
+
+        // graph
+        /*
+        $img = $graph->img;
+        $height = $img->height;
+        $graph->SetMargin($img->left_margin, $img->right_margin, $img->top_margin, $height * 0.25);
+        */
+        $graph->SetFrame(false);
+        $graph->SetMarginColor('white');
+        $graph->SetBackgroundGradient($this->background_color, '#FFFFFF', GRAD_HOR, BGRAD_PLOT);
+
+        // legend
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetFillColor('white');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // xaxis
+        $graph->xaxis->title->SetColor($this->font_color);  
+        $graph->xaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->xaxis->SetTickSide(SIDE_BOTTOM);
+        $graph->xaxis->SetLabelMargin(10);
+                
+        // yaxis
+        $graph->yaxis->title->SetColor($this->font_color);  
+        $graph->yaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->yaxis->SetTickSide(SIDE_LEFT);
+        $graph->yaxis->SetLabelMargin(8);
+        $graph->yaxis->HideLine();
+        $graph->yaxis->HideTicks();
+        $graph->xaxis->SetTitleMargin(15);
+
+        // grid
+        $graph->ygrid->SetColor($this->grid_color);
+        $graph->ygrid->SetLineStyle('dotted');
+
+
+        // font
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+//        $graph->img->SetAntiAliasing();
+    }
+
+
+    function SetupPieGraph($graph) {
+
+        // graph
+        $graph->SetFrame(false);
+
+        // legend
+        $graph->legend->SetFillColor('white');
+        /*
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        */
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // title
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+        $graph->SetAntiAliasing();
+    }
+
+
+    function PreStrokeApply($graph) {
+        if ($graph->legend->HasItems()) {
+            $img = $graph->img;
+            $graph->SetMargin(
+                $img->raw_left_margin, 
+                $img->raw_right_margin, 
+                $img->raw_top_margin, 
+                is_numeric($img->raw_bottom_margin) ? $img->raw_bottom_margin : $img->height * 0.25
+            );
+        }
+    }
+
+    function ApplyPlot($plot) {
+
+        switch (get_class($plot))
+        { 
+            case 'GroupBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'AccBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'BarPlot':
+            {
+                $plot->Clear();
+
+                $color = $this->GetNextColor();
+                $plot->SetColor($color);
+                $plot->SetFillColor($color);
+                $plot->SetShadow('red', 3, 4, false);
+                break;
+            }
+
+            case 'LinePlot':
+            {
+                $plot->Clear();
+
+                $plot->SetColor($this->GetNextColor().'@0.4');
+                $plot->SetWeight(2);
+                break;
+            }
+
+            case 'PiePlot':
+            {
+                $plot->ShowBorder(false);
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+
+            case 'PiePlot3D':
+            {
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+    
+            default:
+            {
+            }
+        }
+    }
+}
+
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/themes/PastelTheme.class.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/themes/PastelTheme.class.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/themes/PastelTheme.class.php	(revision 266)
@@ -0,0 +1,179 @@
+<?php
+
+/**
+* Pastel Theme class
+*/
+class PastelTheme extends Theme 
+{
+    private $font_color       = '#0044CC';
+    private $background_color = '#DDFFFF';
+    private $axis_color       = '#0066CC';
+    private $grid_color       = '#3366CC';
+
+    function GetColorList() {
+        return array(
+            '#FFAACC',
+            '#AAEECC',
+            '#AACCFF',
+            '#CCAAFF',
+            '#EEDDFF',
+            '#FFCCAA',
+            '#CCBBDD',
+            '#CCFFAA',
+            '#C7D7C2',
+            '#FFEEDD',
+            '#FFCCEE',
+            '#BFECFA',
+        );
+    }
+
+    function SetupGraph($graph) {
+
+        // graph
+        /*
+        $img = $graph->img;
+        $height = $img->height;
+        $graph->SetMargin($img->left_margin, $img->right_margin, $img->top_margin, $height * 0.25);
+        */
+        $graph->SetFrame(false);
+        $graph->SetMarginColor('white');
+        $graph->SetBackgroundGradient($this->background_color, '#FFFFFF', GRAD_HOR, BGRAD_PLOT);
+
+        // legend
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetFillColor('white');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // xaxis
+        $graph->xaxis->title->SetColor($this->font_color);  
+        $graph->xaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->xaxis->SetTickSide(SIDE_BOTTOM);
+        $graph->xaxis->SetLabelMargin(10);
+                
+        // yaxis
+        $graph->yaxis->title->SetColor($this->font_color);  
+        $graph->yaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->yaxis->SetTickSide(SIDE_LEFT);
+        $graph->yaxis->SetLabelMargin(8);
+        $graph->yaxis->HideLine();
+        $graph->yaxis->HideTicks();
+        $graph->xaxis->SetTitleMargin(15);
+
+        // grid
+        $graph->ygrid->SetColor($this->grid_color);
+        $graph->ygrid->SetLineStyle('dotted');
+
+
+        // font
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+//        $graph->img->SetAntiAliasing();
+    }
+
+
+    function SetupPieGraph($graph) {
+
+        // graph
+        $graph->SetFrame(false);
+
+        // legend
+        $graph->legend->SetFillColor('white');
+
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.80, 'center', 'top');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(4);
+
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // title
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+        $graph->SetAntiAliasing();
+    }
+
+
+    function PreStrokeApply($graph) {
+        if ($graph->legend->HasItems()) {
+            $img = $graph->img;
+            $graph->SetMargin(
+                $img->raw_left_margin, 
+                $img->raw_right_margin, 
+                $img->raw_top_margin, 
+                is_numeric($img->raw_bottom_margin) ? $img->raw_bottom_margin : $img->height * 0.25
+            );
+        }
+    }
+
+    function ApplyPlot($plot) {
+
+        switch (get_class($plot))
+        { 
+            case 'GroupBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'AccBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'BarPlot':
+            {
+                $plot->Clear();
+
+                $color = $this->GetNextColor();
+                $plot->SetColor($color);
+                $plot->SetFillColor($color);
+                $plot->SetShadow('red', 3, 4, false);
+                break;
+            }
+
+            case 'LinePlot':
+            {
+                $plot->Clear();
+                $plot->SetColor($this->GetNextColor().'@0.4');
+                $plot->SetWeight(2);
+//                $plot->SetBarCenter();
+                break;
+            }
+
+            case 'PiePlot':
+            {
+                $plot->SetCenter(0.5, 0.45);
+                $plot->ShowBorder(false);
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+
+            case 'PiePlot3D':
+            {
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+    
+            default:
+            {
+            }
+        }
+    }
+}
+
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/themes/RoseTheme.class.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/themes/RoseTheme.class.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/themes/RoseTheme.class.php	(revision 266)
@@ -0,0 +1,184 @@
+<?php
+
+/**
+* Rose Theme class
+*/
+class RoseTheme extends Theme 
+{
+    private $font_color       = '#CC0044';
+    private $background_color = '#FFDDDD';
+    private $axis_color       = '#CC0000';
+    private $grid_color       = '#CC3333';
+
+    function GetColorList() {
+        return array(
+            '#FF0000',
+            '#FF99FF',
+            '#AA0099',
+            '#FF00FF',
+            '#FF6666',
+            '#FF0099',
+            '#FFBB88',
+            '#AA2211',
+            '#FF6699',
+            '#BBAA88',
+            '#FF2200',
+            '#883333',
+            '#EE7777',
+            '#EE7711',
+            '#FF0066',
+            '#DD7711',
+            '#AA6600',
+            '#EE5500',
+        );
+    }
+
+    function SetupGraph($graph) {
+
+        // graph
+        /*
+        $img = $graph->img;
+        $height = $img->height;
+        $graph->SetMargin($img->left_margin, $img->right_margin, $img->top_margin, $height * 0.25);
+        */
+        $graph->SetFrame(false);
+        $graph->SetMarginColor('white');
+        $graph->SetBackgroundGradient($this->background_color, '#FFFFFF', GRAD_HOR, BGRAD_PLOT);
+
+        // legend
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetFillColor('white');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // xaxis
+        $graph->xaxis->title->SetColor($this->font_color);  
+        $graph->xaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->xaxis->SetTickSide(SIDE_BOTTOM);
+        $graph->xaxis->SetLabelMargin(10);
+                
+        // yaxis
+        $graph->yaxis->title->SetColor($this->font_color);  
+        $graph->yaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->yaxis->SetTickSide(SIDE_LEFT);
+        $graph->yaxis->SetLabelMargin(8);
+        $graph->yaxis->HideLine();
+        $graph->yaxis->HideTicks();
+        $graph->xaxis->SetTitleMargin(15);
+
+        // grid
+        $graph->ygrid->SetColor($this->grid_color);
+        $graph->ygrid->SetLineStyle('dotted');
+
+
+        // font
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+//        $graph->img->SetAntiAliasing();
+    }
+
+
+    function SetupPieGraph($graph) {
+
+        // graph
+        $graph->SetFrame(false);
+
+        // legend
+        $graph->legend->SetFillColor('white');
+        /*
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        */
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // title
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+        $graph->SetAntiAliasing();
+    }
+
+
+    function PreStrokeApply($graph) {
+        if ($graph->legend->HasItems()) {
+            $img = $graph->img;
+            $graph->SetMargin(
+                $img->raw_left_margin, 
+                $img->raw_right_margin, 
+                $img->raw_top_margin, 
+                is_numeric($img->raw_bottom_margin) ? $img->raw_bottom_margin : $img->height * 0.25
+            );
+        }
+    }
+
+    function ApplyPlot($plot) {
+
+        switch (get_class($plot))
+        { 
+            case 'GroupBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'AccBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'BarPlot':
+            {
+                $plot->Clear();
+
+                $color = $this->GetNextColor();
+                $plot->SetColor($color);
+                $plot->SetFillColor($color);
+                $plot->SetShadow('red', 3, 4, false);
+                break;
+            }
+
+            case 'LinePlot':
+            {
+                $plot->Clear();
+
+                $plot->SetColor($this->GetNextColor().'@0.4');
+                $plot->SetWeight(2);
+                break;
+            }
+
+            case 'PiePlot':
+            {
+                $plot->ShowBorder(false);
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+
+            case 'PiePlot3D':
+            {
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+    
+            default:
+            {
+            }
+        }
+    }
+}
+
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/themes/SoftyTheme.class.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/themes/SoftyTheme.class.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/themes/SoftyTheme.class.php	(revision 266)
@@ -0,0 +1,213 @@
+<?php
+
+/**
+* Softy Theme class
+*/
+class SoftyTheme extends Theme 
+{
+    protected $font_color       = '#000000';
+    protected $background_color = '#F7F8F4';
+    protected $axis_color       = '#000000';
+    protected $grid_color       = '#CCCCCC';
+
+    function GetColorList() {
+        return array(
+            '#CFE7FB',
+            '#F9D76F',
+            '#B9D566',
+            '#FFBB90',
+            '#66BBBB',
+            '#E69090',
+            '#BB90BB',
+            '#9AB67C',
+            '#D1CC66',
+
+/*
+
+            '#AFD8F8',
+            '#F6BD0F',
+            '#8BBA00',
+            '#FF8E46',
+            '#008E8E',
+
+            '#D64646',
+            '#8E468E',
+            '#588526',
+            '#B3AA00',
+            '#008ED6',
+
+            '#9D080D',
+            '#A186BE',
+            */
+        );
+    }
+
+    function SetupGraph($graph) {
+
+        // graph
+        $graph->SetFrame(false);
+        $graph->SetMarginColor('white');
+
+        // legend
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetFillColor('white');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // xaxis
+        $graph->xaxis->title->SetColor($this->font_color);  
+        $graph->xaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->xaxis->SetTickSide(SIDE_BOTTOM);
+        $graph->xaxis->SetLabelMargin(10);
+                
+        // yaxis
+        $graph->yaxis->title->SetColor($this->font_color);  
+        $graph->yaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->yaxis->SetTickSide(SIDE_LEFT);
+        $graph->yaxis->SetLabelMargin(8);
+        $graph->yaxis->HideLine();
+        $graph->yaxis->HideTicks();
+        $graph->xaxis->SetTitleMargin(15);
+
+        // y2~
+        if (isset($graph->y2axis)) {
+            $graph->y2axis->title->SetColor($this->font_color);  
+            $graph->y2axis->SetColor($this->axis_color, $this->font_color);    
+            $graph->y2axis->SetTickSide(SIDE_LEFT);
+            $graph->y2axis->SetLabelMargin(8);
+            $graph->y2axis->HideLine();
+            $graph->y2axis->HideTicks();
+        }
+
+        // yn
+        if (isset($graph->y2axis)) {
+            foreach ($graph->ynaxis as $axis) {
+                $axis->title->SetColor($this->font_color);  
+                $axis->SetColor($this->axis_color, $this->font_color);    
+                $axis->SetTickSide(SIDE_LEFT);
+                $axis->SetLabelMargin(8);
+                $axis->HideLine();
+                $axis->HideTicks();
+            }
+        }
+
+        // grid
+        $graph->ygrid->SetColor($this->grid_color);
+        $graph->ygrid->SetLineStyle('dotted');
+        $graph->ygrid->SetFill(true, '#FFFFFF', $this->background_color);
+        $graph->xgrid->Show();
+        $graph->xgrid->SetColor($this->grid_color);
+        $graph->xgrid->SetLineStyle('dotted');
+
+
+        // font
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+//        $graph->img->SetAntiAliasing();
+    }
+
+
+    function SetupPieGraph($graph) {
+
+        // graph
+        $graph->SetFrame(false);
+
+        // title
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+        $graph->SetAntiAliasing();
+    }
+
+
+    function PreStrokeApply($graph) {
+        if ($graph->legend->HasItems()) {
+            $img = $graph->img;
+            $graph->SetMargin(
+                $img->raw_left_margin, 
+                $img->raw_right_margin, 
+                $img->raw_top_margin, 
+                is_numeric($img->raw_bottom_margin) ? $img->raw_bottom_margin : $img->height * 0.25
+            );
+        }
+    }
+
+    function ApplyPlot($plot) {
+
+        switch (get_class($plot))
+        { 
+            case 'BarPlot':
+            {
+                $plot->Clear();
+
+                $color = $this->GetNextColor();
+                $plot->SetColor($color);
+                $plot->SetFillColor($color);
+                $plot->SetShadow('red', 3, 4, false);
+                $plot->value->SetAlign('center', 'center');
+                break;
+            }
+
+            case 'LinePlot':
+            {
+                $plot->Clear();
+
+                $plot->SetColor($this->GetNextColor());
+                $plot->SetWeight(2);
+//                $plot->SetBarCenter();
+                break;
+            }
+
+            case 'PiePlot':
+            {
+                $plot->ShowBorder(false);
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+
+
+            case 'GroupBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'AccBarPlot':
+            {
+                $plot->value->SetAlign('center', 'center');
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                    $_plot->SetValuePos('center');
+                }
+                break;
+            }
+
+            case 'ScatterPlot':
+            {
+                break;
+            }
+
+
+            case 'PiePlot3D':
+            {
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+    
+            default:
+            {
+            }
+        }
+    }
+}
+
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/themes/UniversalTheme.class.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/themes/UniversalTheme.class.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/themes/UniversalTheme.class.php	(revision 266)
@@ -0,0 +1,187 @@
+<?php
+
+/**
+* Universal Theme class
+*/
+class UniversalTheme extends Theme 
+{
+    private $font_color       = '#444444';
+    private $background_color = '#F4F4F4';
+    private $axis_color       = '#888888';
+    private $grid_color       = '#E3E3E3';
+
+    function GetColorList() {
+        return array(
+            '#61a9f3',#blue
+            '#f381b9',#red
+            '#61E3A9',#green
+
+            #'#D56DE2',
+            '#85eD82',
+            '#F7b7b7',
+            '#CFDF49',
+            '#88d8f2',
+            '#07AF7B',
+            '#B9E3F9',
+            '#FFF3AD',
+            '#EF606A',
+            '#EC8833',
+            '#FFF100',
+            '#87C9A5',
+        );
+    }
+
+    function SetupGraph($graph) {
+
+        // graph
+        /*
+        $img = $graph->img;
+        $height = $img->height;
+        $graph->SetMargin($img->left_margin, $img->right_margin, $img->top_margin, $height * 0.25);
+        */
+        $graph->SetFrame(false);
+        $graph->SetMarginColor('white');
+        $graph->SetBox(true, '#DADADA');
+//        $graph->SetBackgroundGradient($this->background_color, '#FFFFFF', GRAD_HOR, BGRAD_PLOT);
+
+        // legend
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetFillColor('white');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // xaxis
+        $graph->xaxis->title->SetColor($this->font_color);  
+        $graph->xaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->xaxis->SetTickSide(SIDE_BOTTOM);
+        $graph->xaxis->SetLabelMargin(10);
+        $graph->xaxis->HideTicks();
+        $graph->xaxis->SetTitleMargin(15);
+        //$graph->xaxis->SetLabelMargin(30);
+                
+        // yaxis
+        $graph->yaxis->title->SetColor($this->font_color);  
+        $graph->yaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->yaxis->SetTickSide(SIDE_LEFT);
+        $graph->yaxis->SetLabelMargin(8);
+//        $graph->yaxis->SetTickPositions(array(50, 100, 150));
+//        $graph->yaxis->HideLine();
+        $graph->yaxis->HideTicks();
+
+        // grid
+        $graph->ygrid->SetColor($this->grid_color);
+        $graph->ygrid->SetFill(true, '#FFFFFF', $this->background_color);
+ //       $graph->ygrid->SetLineStyle('dotted');
+
+
+        // font
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+        $graph->img->SetAntiAliasing();
+    }
+
+
+    function SetupPieGraph($graph) {
+
+        // graph
+        $graph->SetFrame(false);
+
+        // legend
+        $graph->legend->SetFillColor('white');
+
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.80, 'center', 'top');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(4);
+
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // title
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+        $graph->SetAntiAliasing();
+    }
+
+
+    function PreStrokeApply($graph) {
+        if ($graph->legend->HasItems()) {
+            $img = $graph->img;
+            $graph->SetMargin(
+                $img->raw_left_margin, 
+                $img->raw_right_margin, 
+                $img->raw_top_margin, 
+                is_numeric($img->raw_bottom_margin) ? $img->raw_bottom_margin : $img->height * 0.25
+            );
+        }
+    }
+
+    function ApplyPlot($plot) {
+
+        switch (get_class($plot))
+        { 
+            case 'GroupBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'AccBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'BarPlot':
+            {
+                $plot->Clear();
+
+                $color = $this->GetNextColor();
+                $plot->SetColor($color);
+                $plot->SetFillColor($color);
+                $plot->SetShadow('red', 3, 4, false);
+                break;
+            }
+
+            case 'LinePlot':
+            {
+                $plot->Clear();
+                $plot->SetColor($this->GetNextColor().'@0.4');
+                $plot->SetWeight(2);
+                break;
+            }
+
+            case 'PiePlot':
+            {
+                $plot->SetCenter(0.5, 0.45);
+                $plot->ShowBorder(false);
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+
+            case 'PiePlot3D':
+            {
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+    
+            default:
+            {
+            }
+        }
+    }
+}
+
+
+?>
Index: /trunk/client/modules/Elezioni/grafici/themes/VividTheme.class.php
===================================================================
--- /trunk/client/modules/Elezioni/grafici/themes/VividTheme.class.php	(revision 266)
+++ /trunk/client/modules/Elezioni/grafici/themes/VividTheme.class.php	(revision 266)
@@ -0,0 +1,179 @@
+<?php
+
+/**
+* Vivid Theme class
+*/
+class VividTheme extends Theme 
+{
+    private $font_color       = '#0044CC';
+    private $background_color = '#DDFFFF';
+    private $axis_color       = '#0066CC';
+    private $grid_color       = '#3366CC';
+
+    function GetColorList() {
+        return array(
+            '#FFFB11',
+            '#005EBC',
+            '#9AEB67',
+            '#FF4A26',
+            '#FDFF98',
+            '#6B7EFF',
+            '#BCE02E',
+            '#E0642E',
+            '#E0D62E',
+            '#2E97E0',
+            '#02927F',
+            '#FF005A',
+        );
+    }
+
+    function SetupGraph($graph) {
+
+        // graph
+        /*
+        $img = $graph->img;
+        $height = $img->height;
+        $graph->SetMargin($img->left_margin, $img->right_margin, $img->top_margin, $height * 0.25);
+        */
+        $graph->SetFrame(false);
+        $graph->SetMarginColor('white');
+        $graph->SetBackgroundGradient($this->background_color, '#FFFFFF', GRAD_HOR, BGRAD_PLOT);
+
+        // legend
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.85, 'center', 'top');
+        $graph->legend->SetFillColor('white');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(3);
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // xaxis
+        $graph->xaxis->title->SetColor($this->font_color);  
+        $graph->xaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->xaxis->SetTickSide(SIDE_BOTTOM);
+        $graph->xaxis->SetLabelMargin(10);
+                
+        // yaxis
+        $graph->yaxis->title->SetColor($this->font_color);  
+        $graph->yaxis->SetColor($this->axis_color, $this->font_color);    
+        $graph->yaxis->SetTickSide(SIDE_LEFT);
+        $graph->yaxis->SetLabelMargin(8);
+        $graph->yaxis->HideLine();
+        $graph->yaxis->HideTicks();
+        $graph->xaxis->SetTitleMargin(15);
+
+        // grid
+        $graph->ygrid->SetColor($this->grid_color);
+        $graph->ygrid->SetLineStyle('dotted');
+
+
+        // font
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+//        $graph->img->SetAntiAliasing();
+    }
+
+
+    function SetupPieGraph($graph) {
+
+        // graph
+        $graph->SetFrame(false);
+
+        // legend
+        $graph->legend->SetFillColor('white');
+
+        $graph->legend->SetFrameWeight(0);
+        $graph->legend->Pos(0.5, 0.80, 'center', 'top');
+        $graph->legend->SetLayout(LEGEND_HOR);
+        $graph->legend->SetColumns(4);
+
+        $graph->legend->SetShadow(false);
+        $graph->legend->SetMarkAbsSize(5);
+
+        // title
+        $graph->title->SetColor($this->font_color);
+        $graph->subtitle->SetColor($this->font_color);
+        $graph->subsubtitle->SetColor($this->font_color);
+
+        $graph->SetAntiAliasing();
+    }
+
+
+    function PreStrokeApply($graph) {
+        if ($graph->legend->HasItems()) {
+            $img = $graph->img;
+            $graph->SetMargin(
+                $img->raw_left_margin, 
+                $img->raw_right_margin, 
+                $img->raw_top_margin, 
+                is_numeric($img->raw_bottom_margin) ? $img->raw_bottom_margin : $img->height * 0.25
+            );
+        }
+    }
+
+    function ApplyPlot($plot) {
+
+        switch (get_class($plot))
+        { 
+            case 'GroupBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'AccBarPlot':
+            {
+                foreach ($plot->plots as $_plot) {
+                    $this->ApplyPlot($_plot);
+                }
+                break;
+            }
+
+            case 'BarPlot':
+            {
+                $plot->Clear();
+
+                $color = $this->GetNextColor();
+                $plot->SetColor($color);
+                $plot->SetFillColor($color);
+                $plot->SetShadow('red', 3, 4, false);
+                break;
+            }
+
+            case 'LinePlot':
+            {
+                $plot->Clear();
+                $plot->SetColor($this->GetNextColor().'@0.4');
+                $plot->SetWeight(2);
+//                $plot->SetBarCenter();
+                break;
+            }
+
+            case 'PiePlot':
+            {
+                $plot->SetCenter(0.5, 0.45);
+                $plot->ShowBorder(false);
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+
+            case 'PiePlot3D':
+            {
+                $plot->SetSliceColors($this->GetThemeColors());
+                break;
+            }
+    
+            default:
+            {
+            }
+        }
+    }
+}
+
+
+?>
