<?php

/******************************************************************************
 *
 * Purpose: export query results as Shapefile
 * Author:  Armin Burger
 *
 ******************************************************************************
 *
 * Copyright (c) 2003-2008 Armin Burger
 *
 * This file is part of p.mapper.
 *
 * p.mapper is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * p.mapper is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/


/**
 * Export results to CSV files
 * 1 file per result group
 */
class ExportSHP extends ExportQuery
{
    
    /**
     * Init function
     */
    function __construct($json, $map)
    {
        parent::__construct($json);
        
        $msVersion = $_SESSION['MS_VERSION']; 
        $grouplist   = $_SESSION["grouplist"];
        //pm_logDebug(3, $grouplist, "grouplist in exportSHP");
        
        $groups = (array)$this->jsonList[0];
        $fileList = array();
        
        $this->tempFilePath = $_SESSION['web_imagepath'] . "shp_" . session_id();
        @mkdir($this->tempFilePath, 0700);
        
        foreach ($groups as $grp) {
            $layerNameList = array();
            $layerList = array();
            $valueList = array();
            $values = $grp->values;
            if (!$values[0][0]->shplink) continue;
            
            $dbfFieldList = array();
            foreach ($values as $vList) {
                $dbfRow = array();
                
                foreach ($vList as $n=>$v) {
                    if ($shplink = $v->shplink) {
                        //pm_logDebug(3, $shplink, "shplink");
                        $layerName = $shplink[0];
                        $shpIdx = $shplink[1];
                        if (!in_array($layerName, $layerNameList)) {
                            $typeList = array(MS_SHP_POINT, MS_SHP_ARC, MS_SHP_POLYGON);
                            $srcLayer = $map->getLayerByName($layerName);
                            $srcLayerType = $srcLayer->type;
                            //error_log("type: $srcLayerType");
                            $layerNameList[] = $layerName;
                            $layerList[] = $srcLayer;
                            $valueList[$layerName] = array();
                            
                            $srcLayer->open();
                            if ($srcLayer->getMetadata("RESULT_FIELDS")) {
                                $layerItems = preg_split('/[\s,]+/', $srcLayer->getMetadata("RESULT_FIELDS"));
                            } else {
                                $layerItems = $srcLayer->getItems();
                            }
                            //pm_logDebug(3, $layerItems);

                            $outShpFname = $this->tempFilePath . "/" . $layerName;
                            $shpFile = ms_newShapeFileObj($outShpFname, $typeList[$srcLayerType]);
                            $dbfFileName = $outShpFname.".dbf";
                            
                            $fileList[] = $outShpFname.".shp";
                            $fileList[] = $outShpFname.".shx";
                            $fileList[] = $dbfFileName;
                        }
                        $srcShp = PMCommon::resultGetShape($msVersion, $srcLayer, null, $shpIdx, -1);  // changed for compatibility with PG layers and MS >= 5.6
                        $shpFile->addShape($srcShp);
                    } else {
                        $hyperlink = $v->hyperlink;
                        if ($hyperlink) {
                            $val = $hyperlink[2];            
                        } else {
                            $val = $v;
                        }
                        
                        $fldName = $layerItems[$n-1];
                        $dbfRow[] = utf8_decode($val);
                        $dbfFieldList[$fldName] = $this->getFieldType(trim($val), $dbfFieldList[$fldName]);
                    }
                }
                
                $valueList[$layerName][] = $dbfRow;
            }
            
            // write dBase file
            $this->writeDbf($dbfFileName, $dbfFieldList, $valueList[$layerName]);
            
            // some clean up
            PMCommon::freeMsObj($shpFile);
            foreach ($layerList as $l) {
                $l->close();
            }
        }
                 
        // Write all files to zip and remove tmp dir
        $this->tempFileLocation = $_SESSION['web_imageurl'] . "shp_" . session_id() . ".zip" ;
        $zipFilePath = $this->tempFilePath . ".zip";
        PMCommon::packFilesZip($zipFilePath, $fileList, true, true);
        
        rmdir($this->tempFilePath);
        
    }

    
    
    function writeDbf($dbfFileName, $dbfFieldList, $valueList) 
    {
        foreach ($dbfFieldList as $name=>$def) {
            $defList[] = array_merge(array(substr($name, 0, 10)), $def);
        }
        pm_logDebug(3, $defList, "defList");
        
        $dbfFile = dbase_create($dbfFileName, $defList); //array(array("PROG_ID", "N", 5, 0)));
        
        foreach ($valueList as $row) {
            pm_logDebug(3, $row, "row");
            dbase_add_record($dbfFile, $row);
        }
        
        dbase_close($dbfFile);
        
    }
    
    function getFieldType($val, $fldList)
    {
        if (is_numeric($val) && $fldList[0] != "C") { 
            if (intval($val) == $val) {
                $int_len = max(strlen(strval($val)), $fldList[1]) ;
                $list = array("N", $int_len, 0); 
            } else {
                $dL = explode('.', $val);
                $list = array("N", strlen(strval($dl[0])), strlen(strval($dl[1]))); 
            }
        } elseif (is_bool($val)) {
            $list = array("L");
        } elseif (strtotime($str)) {
            $list = array("D");
        } else {
            $str_len = max(strlen($val), $fldList[1]) + 2;
            $list = array("C", $str_len); 
        }
        
        return $list;
    }
    
    

   
}

?>