<?php
 
include_once('config.php');
include_once('extendedfpdf.php');
include_once('ccss.php');
include_once('common_attrs_functions.php');

# Emulation de la fonction php 4.3.0 file_get_contents.
if (!function_exists('file_get_contents')){
  function file_get_contents($file) {
    $fp = fopen($file, 'r');
    $content = fread($fp, filesize('test.css'));
    fclose ($fp);  

    return $content;
  }
}
  
class xhtml2pdf
{  
  var $xmlparser;
  var $currenttag;
  var $pdfdata;
  var $css;
  var $pdfdata;
  var $myfpdf;
  var $depth;
  var $databuffer;
  var $currentattr;
  var $attributes;
  var $link;
  var $readytodisplayablock;
  var $fontattr;
  var $bold;
  var $italic;
  var $underline;
  
  function SetClassAttrAsCurrent($classname, $attrname, $herit=1)
  {
    global $attrdefault; # config.php
  
    if ($this->css->GetAttribute($classname, $attrname) != -1) {
      # La valeur de l'attribut pour la classe a été clairement définie
      $this->currentattr[$this->depth][$attrname] = $this->css->GetAttribute($classname, $attrname);
    }
    else {
      if ($this->depth > 1 && isset($this->currentattr[($this->depth-1)][$attrname]) && $herit==1)
        # Sinon, on tente de l'hériter
        $this->currentattr[$this->depth][$attrname] = $this->currentattr[($this->depth-1)][$attrname];
      else 
        # Si pas d'hériage possible, on met une valeur par défaut
          $this->currentattr[$this->depth][$attrname] = $attrdefault[$attrname];
    }  
  }
  
  
  # Cette fonction, appelée normalement avant chaque sortie, va mettre en place les styles de currentattr[$depth]  
  function ApplyCurrentCssSettings()
  {
    global $allowed;
    
    $this->bold = '';
    $this->italic = '';
    $this->underline = '';
    
    if ($this->depth > 0) { 
      if ($allowed['font-size']) {
        $this->myfpdf->SetFontSize($this->currentattr[$this->depth]['font-size']);
      }

      if ($allowed['color']) {
        list($r, $g, $b) = extract_color($this->currentattr[$this->depth]['color']);
        $this->myfpdf->SetTextColor($r, $g, $b);      
      }    

      if ($allowed['font-weight']) {
        if ($this->currentattr[$this->depth]['font-weight'] == 'bolder' || $this->currentattr[$this->depth]['font-weight'] == 'bold')
          $this->bold = 'B';
        else
          $this->bold = '';        
      }   

      if ($allowed['text-decoration']) {
        if ($this->currentattr[$this->depth]['text-decoration'] == 'underline')
          $this->underline = 'U';
        else
          $this->underline = '';          
      } 
      
      if ($allowed['font-style']) {
        if ($this->currentattr[$this->depth]['font-style'] == 'italic')
          $this->italic = 'I'; 
        else
          $this->italic = '';         
      }  

      $this->myfpdf->SetFont('', $this->bold.$this->underline.$this->italic, '');  
      
      if ($allowed['text-transform']) {
        if ($this->currentattr[$this->depth]['text-transform'] == 'uppercase')
          $this->databuffer = strtoupper($this->databuffer);
        else 
        if ($this->currentattr[$this->depth]['text-transform'] == 'lowercase')
          $this->databuffer = strtolower($this->databuffer);      
        else 
        if ($this->currentattr[$this->depth]['text-transform'] == 'capitalize')
          $this->databuffer = ucwords($this->databuffer);   
      } 
      
      if ($allowed['white-space']) {
        if ($this->currentattr[$this->depth]['white-space'] == 'normal') {
          $this->databuffer = str_replace("\n", ' ', $this->databuffer);
          $this->databuffer = preg_replace('`[[:space:]]+`', ' ', $this->databuffer);
        }          
      }
            
    }
  }
 
 
  function OutputBufferedData()
  {
    global $attrdefault; # config.php
    global $allowed; # config.php

    $this->ApplyCurrentCssSettings();

    if (isset($this->currentattr[$this->depth]['font-size']))
      $lineheight = XHTML2PDF_DEFLINESIZE*$this->currentattr[$this->depth]['font-size']/$attrdefault['font-size'];
    else
      $lineheight = XHTML2PDF_DEFLINESIZE;
 
      
    if ($this->currenttag[$this->depth] == 'a')
       $this->myfpdf->Write($lineheight,$this->databuffer, $this->attributes[$this->depth]['HREF']);
    else 
       $this->myfpdf->Write($lineheight,$this->databuffer);

    $this->databuffer = '';
    # Fin de l'affichage  
  }
  

  function begintag($parser, $name, $attrs)
  {
    global $allowed; # config.php
    
    $name = strtolower($name); # tous les noms de classe st en lowercase
    
    $this->OutputBufferedData();
    $this->depth++;

    $this->currenttag[$this->depth] = $name;
    $this->attributes[$this->depth] = $attrs;
    
    foreach ($allowed as $tag => $value) {
      if ($value == 1)
        $this->SetClassAttrAsCurrent($name, $tag);
    }
    
    if ($attrs['STYLE'] != '') {
      $inlinestyles = explode(';', $attrs['STYLE']);
      foreach ($inlinestyles as $inlinestyle) {
        $inlinestyle = trim($inlinestyle);
        if (strlen($inlinestyle) > 0){
          list($inlineattribute, $inlinevalue) = explode(':', $inlinestyle);
          $this->currentattr[$this->depth][$inlineattribute] = $inlinevalue;  
        }
      }
    }    
    
    if ($name == 'br')
      $this->myfpdf->ln(XHTML2PDF_DEFLINESIZE);
          
    if ($allowed['display']) {
      $this->SetClassAttrAsCurrent($this->currenttag[$this->depth], 'display', 0); # La propriété display ne s'hérite pas
      if ($this->currentattr[$this->depth]['display'] == 'block') {
        if ($this->readytodisplayablock == 0) {
          if (isset($this->currentattr[$this->depth-1]['font-size']))
            $this->myfpdf->ln($this->currentattr[$this->depth-1]['font-size']); 
        }
        if ($allowed['margin-top']) {
          if (isset($this->currentattr[$this->depth]['margin-top']))
            $this->myfpdf->ln(converttomm($this->currentattr[$this->depth]['margin-top']));
        }    
        if ($allowed['margin-left']) {
          if ($this->currentattr[$this->depth]['display'] == 'block')
            $this->myfpdf->SetLeftMargin(converttomm($this->currentattr[$this->depth]['margin-left'])+$this->myfpdf->GetLeftMargin());
        }        
      }
    }  
    
        

  }

  function endtag($parser, $name)
  {
    global $allowed; # config.php

    $name = strtolower($name);
    
    if(preg_match('`h[1-6]`',$name)) {
        $this->myfpdf->Bookmark($this->databuffer, $name[1]-1, -1);        
    }

    if ($allowed['text-transform']) {
      if ($this->currentattr[$this->depth]['text-transform'] == 'uppercase')
        $this->databuffer = strtoupper($this->databuffer);
      else 
      if ($this->currentattr[$this->depth]['text-transform'] == 'lowercase')
        $this->databuffer = strtolower($this->databuffer);      
      else 
      if ($this->currentattr[$this->depth]['text-transform'] == 'capitalize')
        $this->databuffer = ucwords($this->databuffer);   
    }  
       
    $this->OutputBufferedData();

    # Rétablissement des paramètres
    if ($allowed['display'] && $this->currentattr[$this->depth]['display'] == 'block') {
      $this->myfpdf->ln($this->currentattr[$this->depth]['font-size']); # Conversion pt > mm 
      $this->readytodisplayablock = 1;
      
      if ($allowed['margin-left']) {
        $this->myfpdf->SetLeftMargin($this->myfpdf->GetLeftMargin()-converttomm($this->currentattr[$this->depth]['margin-left']));
      }       
      
      if ($allowed['margin-bottom']) {
        if (isset($this->currentattr[$this->depth]['margin-bottom']))
          $this->myfpdf->ln(converttomm($this->currentattr[$this->depth]['margin-bottom']));
      }   
    }

    $this->depth--;
  }


  # Fonction de rappel - on bufferise les données
  function handledata($parser, $data)
  { 
    if ($this->depth > 1 && $this->currenttag[1] == 'body' && $this->readytodisplayablock == 1 && trim($data) != '')
      $this->readytodisplayablock = 0;
      
    if ($this->depth > 1 && $this->currenttag[1] == 'body')
      $this->databuffer .= $data;
  }



  function xhtml2pdf($xhtmlfile, $cssfile)
  {
    $this->currentattr = array();
    $this->depth = -1; # la première balise (html) aura la profondeur 0
    $this->readytodisplayablock = 1;
    
    if (file_exists('html.css'))
      $content = file_get_contents('html.css');
    else
      return -1;  
    $this->css = new ccss;    
    $this->css->read($content);
    if (file_exists($cssfile))
      $content = file_get_contents($cssfile);
    else
      return -1; 
    $this->css->read($content);
  
  
    $this->myfpdf = new XFPDF();
    $this->myfpdf->SetFont('Arial','',12);
    $this->myfpdf->AddPage();  
 
  
    $this->xml_parser = xml_parser_create();
    xml_set_object($this->xml_parser, $this);    
    xml_set_element_handler($this->xml_parser, "begintag", "endtag");    
    xml_set_character_data_handler($this->xml_parser, "handledata");
    
    $content = file_get_contents($xhtmlfile);
    xml_parse($this->xml_parser, $content);  
    xml_parser_free($this->xml_parser);
  }

  function output()
  {
    $this->myfpdf->Output();    
  }


}
  
?>
