<?php
require_once 'vendor/excel/PHPExcel.php';
require_once 'vendor/excel/PHPExcel/IOFactory.php';
require_once 'vendor/excel/PHPExcel/Writer/Excel2007.php';
require_once 'application/webroot/Excel/Interfaces/GeneratExcelInterface.php';

final class GenerateExcel extends PHPExcel implements GeneratExcelInterface
{

    private $style;

    private $arrayCSV;

    private $alphabet;

    private $urlExcel;

    /**
     *
     * Cette fonction est le constructeur qui va permettre de generer le fichier Excel
     * La fonction fait appel à plusieur fonction de la class
     *
     * @param string $file
     *            : chemin du fichier CSV
     * @param string $parser
     *            : le type de separateur (exemple => ";")
     * @param int $sizeTitle
     *            : la taille des caracteres des titres (exemple => "18")
     * @param string $colorTitle
     *            : la couleur des titres (exemple => "FFFFFF")
     *            
     * @return void
     *
     */
    public function __construct($sizeTitle = null, $colorTitle = null)
    {
        $this->setAlphabet();
        $this->setStyle($sizeTitle, $colorTitle);
    }

    /**
     *
     * @param string $file
     *            : chemin du fichier CSV
     * @param string $parser
     *            : le type de separateur (exemple => ";")
     *            
     * @return : String (nom du fichier)
     */
    public function generat($file, $parser)
    {
        $objPHPExcel = new PHPExcel();
        $sheet = $objPHPExcel->getActiveSheet();
        
        $styleArray = $this->style;
        $conteurFournisseur = 0;
        
        foreach ($this->parseCsv($file, $parser) as $attribut) {
            $conteurTitre = 1;
            $conteurCelluleReel = 0;
            $wordFirst = trim($attribut[0]);
            $conteurFournisseur ++;
            
            if ($wordFirst == 'T') {
                $i = 1;
                $titreActive = 1;
            } else {
                $i = 0;
                $titreActive = 0;
            }
            
            for ($i; $i < count($attribut); $i ++) {
                $trimAttribut = trim($attribut[$i]);
                
                if ($trimAttribut == 'R') {
                    $this->cellColor($objPHPExcel, $this->alphabet[$conteurCelluleReel] . $conteurFournisseur, 'DF013A');
                } else if ($trimAttribut == 'V') {
                    $this->cellColor($objPHPExcel, $this->alphabet[$conteurCelluleReel] . $conteurFournisseur, '04B404');
                } else if ($trimAttribut == 'O') {
                    $this->cellColor($objPHPExcel, $this->alphabet[$conteurCelluleReel] . $conteurFournisseur, 'DBA901');
                } else if ($attribut[$i] == 'B') {
                    $this->cellColor($objPHPExcel, $this->alphabet[$conteurCelluleReel] . $conteurFournisseur, 'FFFFFF');
                } else if ($trimAttribut != 'O' && $trimAttribut != 'V' && $trimAttribut != 'R' && $wordFirst != 'C' && $i != 0) {
                    $conteurCelluleReel ++;
                    $sheet->setCellValue($this->alphabet[$conteurCelluleReel + $titreActive] . $conteurFournisseur, utf8_encode($attribut[$i]));
                    
                    if ($titreActive && utf8_encode($trimAttribut) != '') {
                        $this->cellColor($objPHPExcel, $this->alphabet[$conteurCelluleReel + $titreActive] . $conteurFournisseur, 'A4A4A4');
                        $sheet->getStyle($this->alphabet[$conteurCelluleReel + $titreActive] . $conteurFournisseur)
                            ->getAlignment()
                            ->setTextRotation(90)
                            ->setWrapText(true);
                        $sheet->getStyle($this->alphabet[$conteurCelluleReel + $titreActive] . $conteurFournisseur)->applyFromArray($styleArray);
                    }
                    
                    if (! $titreActive && $wordFirst == 'F' && $i == 1) {
                        $this->cellColor($objPHPExcel, $this->alphabet[$conteurCelluleReel + $titreActive] . $conteurFournisseur, 'A4A4A4');
                        $sheet->getStyle($this->alphabet[$conteurCelluleReel + $titreActive] . $conteurFournisseur)->applyFromArray($styleArray);
                    }
                } else if ($wordFirst == 'C') {
                    if (isset($attribut[$i + 1]) && is_numeric($attribut[$i + 1])) {
                        $sheet->mergeCells($this->alphabet[$conteurTitre + 1] . $conteurFournisseur . ':' . $this->alphabet[$conteurTitre + trim($attribut[$i + 1])] . $conteurFournisseur);
                        $sheet->setCellValue($this->alphabet[$conteurTitre + 1] . $conteurFournisseur, utf8_encode($attribut[$i]));
                        $this->cellColor($objPHPExcel, $this->alphabet[$conteurTitre + 1] . $conteurFournisseur, 'A4A4A4');
                        $sheet->getStyle($this->alphabet[$conteurTitre + 1] . $conteurFournisseur)->applyFromArray($styleArray);
                        
                        $conteurTitre = $conteurTitre + $attribut[$i + 1];
                    }
                    
                    if ($attribut[$i] == '' && $i > 1) {
                        $conteurTitre ++;
                    }
                }
            }
        }
        
        $sheet->getColumnDimensionByColumn('A')->setWidth(35);
        
        $_SESSION['EmplacementFichier'] = 'tmp';
        
        $nomFichier = $_SESSION['NomFichier'] = 'S3907_' . $_SESSION['id_user'] . '_' . uniqid() . '.xlsx';
        
        $directoryTmp = Fichier::getCheminTmp();
        $this->urlExcel = $directoryTmp . $nomFichier;
        
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
        $objWriter->save($this->urlExcel);
        $_SESSION['UrlFichier'] = $nomFichier;
        
        return $nomFichier;
    }

    /**
     *
     * fonction qui permet de changer la couleur d'une cellule
     *
     * @param PHPExcel $objPHPExcel
     *            (reference)
     * @param String $cells
     *            : Code de la cellule (exemple => A1)
     * @param String $color
     *            : Code couleur qu'on veut attribuer à la celulle (exemple : FFFFFF)
     *            
     * @return void
     *
     */
    public function cellColor(PHPExcel &$objPHPExcel, $cells, $color)
    {
        $objPHPExcel->getActiveSheet()
            ->getStyle($cells)
            ->getFill()
            ->applyFromArray(array(
            'type' => PHPExcel_Style_Fill::FILL_SOLID,
            'startcolor' => array(
                'rgb' => $color
            )
        ));
    }

    /**
     * Cette fonction renseigne la variable $style (private)
     *
     * @param int $size
     *            : la taille de la police
     * @param string $color
     *            : couleur de la police
     *            
     * @return void
     */
    public function setStyle($size = null, $color = null)
    {
        if (is_null($size))
            $size = 11;
        
        if (is_null($color))
            $color = '000000';
        
        $this->style = array(
            'font' => array(
                'bold' => true,
                'color' => array(
                    'rgb' => $color
                ),
                'size' => $size,
                'name' => 'Verdana',
                'alignment' => array(
                    'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER
                )
            ),
            'borders' => array(
                'allborders' => array(
                    'style' => PHPExcel_Style_Border::BORDER_THIN,
                    'color' => array(
                        'rgb' => 'DDDDDD'
                    ),
                    'size' => 10
                )
            )
        );
    }

    /**
     *
     * GETTER : $style
     *
     * @return array
     */
    public function getStyle()
    {
        return $this->style;
    }

    /**
     * Cette fonction permet de parser le CSV
     *
     * @param String $folder
     *            : le chemin du fichier CSV
     * @param string $parseur
     *            : par quoi on parse le CSV : exemple (";")
     *            
     * @return array
     */
    public function parseCsv($folder, $parseur)
    {
        $handle = fopen($folder, "r");
        
        while (($data = fgetcsv($handle, 0, $parseur)) !== FALSE) {
            $this->setArrayCSV($data);
        }
        
        return $this->getArrayCsv();
    }

    /**
     * SETTER $arrayCSV
     *
     * @param array $data
     *            return void
     */
    public function setArrayCSV(& $data)
    {
        $this->arrayCSV[] = $data;
    }

    /**
     * GETTER : $arrayCSV
     *
     * @return array
     */
    public function &getArrayCsv()
    {
        return $this->arrayCSV;
    }

    /**
     * GETTER : $urlExcel
     *
     * @return String
     */
    public function &getUrlExcel()
    {
        return $this->urlExcel;
    }

    /**
     * SETTER : $alphabet
     *
     * @return void
     */
    public function setAlphabet()
    {
        $this->alphabet[0] = 'init';
        for ($alpha = 'a'; $alpha <= 'zz'; $alpha ++) {
            $this->alphabet[] = strtoupper($alpha);
        }
    }

    /**
     * GETTER : $alphabet
     *
     * @return array
     */
    public function getAlphabet()
    {
        return $this->alphabet;
    }

    /**
     *
     * Fonction clonnage d'un fichier excel => tentative pour contourner le timeout
     *
     * @return fichier Excel
     *        
     */
    public function cloneFichier()
    {
        /*
         * Cas de test avec la ressource 3
         */
        $objPHPExcel = PHPExcel_IOFactory::load("../ressources/3.xlsx");
        $clonedSheet = clone $objPHPExcel->getActiveSheet();
        
        for ($i = 1; $i < 10000; $i ++) {
            $clonedSheet->setCellValue('A' . $i, 'Goodbye')
                ->setCellValue('A' . $i, 'cruel')
                ->setCellValue('C' . $i, 'Goodbye')
                ->setCellValue('C' . $i, 'cruel');
            $objPHPExcel->getActiveSheet()
                ->getStyle('A' . $i)
                ->getFill()
                ->applyFromArray(array(
                'type' => PHPExcel_Style_Fill::FILL_SOLID,
                'startcolor' => array(
                    'rgb' => 'DBA901'
                )
            ));
        }
        
        /*
         * renomme le worksheet
         */
        echo date('H:i:s'), " Rename cloned worksheet", EOL;
        $clonedSheet->setTitle('Simple Clone');
        $objPHPExcel->addSheet($clonedSheet);
        
        $objPHPExcel->setActiveSheetIndex(0);
        
        echo date('H:i:s'), " Write to Excel2007 format", EOL;
        $callStartTime = microtime(true);
        
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
        $objWriter->save("../ressources/extract/10.xlsx");
    }

    /**
     *
     * fonction qui permet de fusionner deux fichiers Excel => tentative pour contourner le timeout
     *
     * @param string $file1
     * @param string $file2
     *
     * @return Fichier Excel
     *        
     */
    public function fusionnerFichier($file1, $file2)
    {
        $objPHPExcel1 = PHPExcel_IOFactory::load($file1);
        $objPHPExcel2 = PHPExcel_IOFactory::load($file2);
        
        $objPHPExcel1->getActiveSheet()->fromArray($objPHPExcel2->getActiveSheet()
            ->toArray(), null, 'A' . ($objPHPExcel1->getActiveSheet()
            ->getHighestRow() + 1));
        
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel1, 'Excel2007');
        
        $objWriter->save("../ressources/extract/baba.xlsx");
    }
}