<?php
/**
 * @author		Kano
 * @copyright	Kano Technology Limited
 * @license		Commercial
 */

defined("_JEXEC") or die("Restricted access");

/**
 * Trade helper class.
 *
 * @package     Trade
 * @subpackage  Helpers
 */
class TradeHelper
{
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			'<i class="icon-box-add"></i> '.JText::_('COM_TRADE_SUBMENU_TRADE'), 
			'index.php?option=com_trade&view=trades', 
			$vName == 'trades'
		);
		JHtmlSidebar::addEntry(
			'<i class="icon-box-add"></i> '.JText::_('COM_TRADE_SUBMENU_CART'), 
			'index.php?option=com_trade&view=carts', 
			$vName == 'carts'
		);
		JHtmlSidebar::addEntry(
			'<i class="icon-box-add"></i> '.JText::_('COM_TRADE_SUBMENU_ENQUIRY'), 
			'index.php?option=com_trade&view=enquirys', 
			$vName == 'enquirys'
		);
		JHtmlSidebar::addEntry(
			'<i class="icon-box-add"></i> '.JText::_('COM_TRADE_SUBMENU_LOCATION'), 
			'index.php?option=com_trade&view=locations', 
			$vName == 'locations'
		);

		JHtmlSidebar::addEntry(
			'<i class="icon-box-add"></i> '.JText::_('JCATEGORIES'), 
			'index.php?option=com_categories&extension=com_trade', 
			$vName == 'categories'
		);
		JHtmlSidebar::addEntry(
			'<i class="icon-box-add"></i> Backup', 
			'index.php?option=com_trade&view=backup', 
			$vName == 'backup'
		);
      
		JHtmlSidebar::addEntry(
			'<i class="icon-box-remove"></i> Restore', 
			'index.php?option=com_trade&view=restore', 
			$vName == 'restore'
		);
	}
	
	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @return	JObject
	 * @since	1.6
	 */
	public static function getActions()
	{
		$user	= JFactory::getUser();
		$result	= new JObject;

		$assetName = 'com_trade';

		$actions = array(
			'core.admin', 'core.manage', 'core.create', 'core.edit', 'core.edit.own', 'core.edit.state', 'core.delete'
		);

		foreach ($actions as $action) {
			$result->set($action, $user->authorise($action, $assetName));
		}

		return $result;
	}
	
	public static function getLocation($id)
	{	
		$db	= JFactory::getDBO();
		$db->setQuery("SELECT title FROM #__trade_location WHERE id=".(int)$id);
		return $db->loadResult();
	}
	
	public static function getIndustry($id)
	{	
		$db	= JFactory::getDBO();
		$db->setQuery("SELECT title FROM #__categories WHERE id=".(int)$id);
		return $db->loadResult();
	}
	
	public static function getCategories($catids)
	{	
		$db	= JFactory::getDBO();
		// Get Order
		$db->setQuery("SELECT title FROM #__categories WHERE find_in_set(id,'".$catids."')");
		$categories = $db->loadObjectList();
		$result = "";
		foreach ($categories as $category) 
			$result .= $category->title."<BR>";
		return $result;
	}
	
 	public static function getLastID()
	{	
		$db	= JFactory::getDBO();
		$db->setQuery("SELECT MAX(id) FROM #__trade");
		return $db->loadResult();
	}
	
	public static function listDocuments($folder,$id)
	{	
		$dir = JPATH_ROOT . '/images/trades/'.$id.'/'.$folder;
		if (file_exists($dir)) {
			$files = scandir($dir);

			//echo "<BR><BR>";
			foreach ($files as $file) {
				if (($file!='.') && ($file!='..'))
					echo '<div class="file"><a href="'.JURI::root(). 'images/trades/'.$id.'/'.$folder.'/'.$file.'" target="_blank">'.$file.'</a> <a href="javascript:void(0)" data-path="index.php?option=com_trade&task=remove_document&path='.$id.'/'.$folder.'/'.urlencode($file).'" class="delete"><span class="icon-cancel" style="color:#933"></span></a></div>';
			}
		if ($folder=='photos') {
			if (stripos($folder,'_')===false) echo '<script>
	jQuery(document).ready(function(){

	  // Delete 
	  jQuery(\'.delete\').click(function(){
		// Delete path
		var path = jQuery(this).data(\'path\');
	 
		if (confirm("Delete Record?") == true) {
			jQuery.post(path, function(data) {
			
			//	return true;
			});
			jQuery(this).parents(\'div.file\').hide();
		} 
	  });
	});
	</script>';
		}
		}
	}
	
	public static function listDocumentsOnly($id,$folder)
	{	
		$dir = JPATH_ROOT . '/images/trades/'.$id.'/'.$folder;
		if (file_exists($dir)) {
			$files = scandir($dir);
			//echo "<BR><BR>";
			foreach ($files as $file) {
				if (($file!='.') && ($file!='..'))
					echo '<div class="file"><a href="'.JURI::root(). 'images/trades/'.$id.'/'.$folder.'/'.$file.'" target="_blank">'.$file.'</a></div>';
			}
		} 
	}
	
	public static function listPhotosOnly($id,$folder)
	{	
		$dir = JPATH_ROOT . '/images/trades/'.$id.'/'.$folder;
		if (file_exists($dir)) {
			$files = scandir($dir);
			//echo "<BR><BR>";
			foreach ($files as $file) {
				if (($file!='.') && ($file!='..'))
					echo '<div class="file"><a href="'.JURI::root(). 'images/trades/'.$id.'/'.$folder.'/'.$file.'" target="_blank"><img src="'.JURI::root(). 'images/trades/'.$id.'/'.$folder.'/'.$file.'" width="100" style="padding:2px 3px;"></a></div>';
			}
		} 
	}
	
	public static function deleteDocument($path)
	{	
		if (stripos($path,'..')===false) {
			$file = JPATH_ROOT .'/images/trades/'. $path;
			if (file_exists($file)) {
				unlink($file);
				return true;
			} else {
				return false;
			}
		} 
		return false;
	}
	
	public static function uploadDocument($id,$field='images')
	{	
        $input = JFactory::getApplication()->input;
		if (empty($id))
			$id = self::getLastID()+1;
        // get uploaded file
		
	//	echo $field;
		$files = $input->files->get('jform');
var_dump($files);
		//$docs = $files[$field];
		
		if (array_key_exists('name',$files[$field])) $docs[] =  $files[$field]; else $docs =  $files[$field];
		var_dump($docs);
//exit;	
		foreach ($docs as $file) {			
			// Cleans the name of the file by removing weird characters
			//$ext = '.'.pathinfo($file['name'])['extension'];
			//var_dump($files);
			//exit;
			//$filename =  JFile::makeSafe($file['name']); 
			$filename =  $file['name']; 
			$src  = $file['tmp_name'];
			$dest = JPATH_ROOT . '/images/trades/'.$id.'/documents/'.$filename;
			$dir = JPATH_ROOT . '/images/trades/'.$id.'/documents';
			if (!empty($src)) {
				// Remove old file
				
				// Upload new file
				if (JFile::upload($src, $dest)) 
				{
					//return $filename;
				} 
			}
		}

		return count(scandir($dir))-2;
	}
	
	public static function uploadPhoto($id,$oldname)
	{	
        $input = JFactory::getApplication()->input;
		if (empty($id))
			$id = self::getLastID()+1;
        // get uploaded file
		$files = $input->files->get('jform');

		//$docs = $files['photos'];
		
		if (array_key_exists('name',$files['photos'])) $docs[] =  $files['photos']; else $docs =  $files['photos'];
		foreach ($docs as $file) {			
			// Cleans the name of the file by removing weird characters
			//$ext = '.'.pathinfo($file['name'])['extension'];
			//var_dump($files);
			//exit;
			//$filename =  JFile::makeSafe($file['name']); 
			$filename =  $file['name']; 
			$src  = $file['tmp_name'];
			$dest = JPATH_ROOT . '/images/trades/'.$id.'/photos/'.$filename;
			$dir = JPATH_ROOT . '/images/trades/'.$id.'/photos';
			if (!empty($src)) {
				// Remove old file
				
				// Upload new file
				if (JFile::upload($src, $dest)) 
				{
					return $filename;
				} 
			}
		}
		return $oldname;
	}
	
	
    public static function sendEnquiryEmail($data) 
	{
        $db	= JFactory::getDBO();
        $params = JComponentHelper::getParams('com_trade');
		$config = JFactory::getConfig();
		$sender = array( 
			$config->get( 'mailfrom' ),
			
			$config->get( 'fromname' ) 
		);
		$recipient = $params['email'];
		$rows = "";
		foreach ($data as $key=>$value) {
			if (is_array($value)) {
				$row = JText::_('COM_TRADE_TRADE_ENQUIRY_FIELD_'.strtoupper($key).'_LABEL').": \r\n";
				foreach ($value as $option ) {
					$row.= "    ".$option." - ".self::getTrade($option)."\r\n";
				}
				$rows .= "\r\n\r\n".$row;
			} else {
				switch ($key) {
					case 'industryid':
						$rows .= JText::_('COM_TRADE_TRADE_ENQUIRY_FIELD_'.strtoupper($key).'_LABEL').": ".self::getCategory($value)."\r\n\r\n";
					break;
					case 'locationid':
						$rows .= JText::_('COM_TRADE_TRADE_ENQUIRY_FIELD_'.strtoupper($key).'_LABEL').": ".self::getCategory($value)."\r\n\r\n";
					break;
					case 'time_from':
					    if ($data['time_stage']=='AM') $time_stage= '上午'; else $time_stage= '下午';
						$rows .=JText::_('COM_TRADE_TRADE_ENQUIRY_FIELD_'.strtoupper($key).'_LABEL').": ".$value." - ".$data['time_to']." ".$time_stage."\r\n\r\n";
					break;
					case 'budget':
					case 'role':
					case 'working_status':
					case 'partner':
					case 'experiment':
					case 'gender':
					case 'age':
					case 'enquiry_type':
						$rows .= JText::_('COM_TRADE_TRADE_ENQUIRY_FIELD_'.strtoupper($key).'_LABEL').": ".JText::_('COM_TRADE_TRADE_ENQUIRY_FIELD_'.strtoupper($key).'_OPTION_'.strtoupper($value))."\r\n\r\n";
					break;
					case 'tags':
					case 'time_to':
					case 'time_stage':
					break;
					
					default:
						$rows .= JText::_('COM_TRADE_TRADE_ENQUIRY_FIELD_'.strtoupper($key).'_LABEL').": ".$value."\r\n\r\n";
				}
			}
		}
		//var_dump($data);
		$body = '<div style="font-size:18px">'.nl2br($rows).'</div>';
		echo $body;
		//exit;
		//echo $rows;
		$mailer = JFactory::getMailer();
		$mailer->isHtml(true);
		$mailer->setSender($sender);
      //  $mailer->addReplyTo($params['admin_email']);
		$mailer->addRecipient($recipient);
		if (!empty($bcc)) $mailer->addBcc($bcc);
		$mailer->setSubject('Bosstation Enquiry');
		$mailer->setBody($body);
//exit;
return true;
//		return $mailer->Send();
    }
}

class ImageResize
{
	// https://github.com/eventviva/php-image-resize
	// v1.6.7
    const CROPTOP = 1;
    const CROPCENTRE = 2;
    const CROPCENTER = 2;
    const CROPBOTTOM = 3;
    const CROPLEFT = 4;
    const CROPRIGHT = 5;
    const CROPTOPCENTER = 6;

    public $quality_jpg = 85;
    public $quality_png = 6;
    public $quality_truecolor = TRUE;

    public $interlace = 1;

    public $source_type;

    protected $source_image;

    protected $original_w;
    protected $original_h;

    protected $dest_x = 0;
    protected $dest_y = 0;

    protected $source_x;
    protected $source_y;

    protected $dest_w;
    protected $dest_h;

    protected $source_w;
    protected $source_h;
    
    protected $source_info;

    /**
     * Create instance from a strng
     *
     * @param string $image_data
     * @return ImageResize
     * @throws ImageResizeException
     */
    public static function createFromString($image_data)
    {
		if(empty($image_data) || $image_data === null) {
			throw new ImageResizeException('image_data must not be empty');
		}
        $resize = new self('data://application/octet-stream;base64,' . base64_encode($image_data));
        return $resize;
    }

    /**
     * Loads image source and its properties to the instanciated object
     *
     * @param string $filename
     * @return ImageResize
     * @throws ImageResizeException
     */
    public function __construct($filename)
    {

        if($filename === null || empty($filename) || (substr($filename,0,7) !== 'data:/'.'/' && !is_file($filename))) {
			throw new ImageResizeException('File does not exist');
		}	
		
		$finfo = finfo_open(FILEINFO_MIME_TYPE);
		if(strstr(finfo_file($finfo, $filename),'image') === false) {
			throw new ImageResizeException('Unsupported file type');
		}
		
        if (!$image_info = getimagesize($filename, $this->source_info)) {
            $image_info = getimagesize($filename);
        }

        if (!$image_info) {
            throw new ImageResizeException('Could not read file');
        }

        list (
            $this->original_w,
            $this->original_h,
            $this->source_type
        ) = $image_info;

        switch ($this->source_type) {
            case IMAGETYPE_GIF:
                $this->source_image = imagecreatefromgif($filename);
                break;

            case IMAGETYPE_JPEG:
                $this->source_image = $this->imageCreateJpegfromExif($filename);

                // set new width and height for image, maybe it has changed
                $this->original_w = ImageSX($this->source_image);
                $this->original_h = ImageSY($this->source_image);

                break;

            case IMAGETYPE_PNG:
                $this->source_image = imagecreatefrompng($filename);
                break;

            default:
                throw new ImageResizeException('Unsupported image type');
                break;
        }

        if (!$this->source_image) {
            throw new ImageResizeException('Could not load image');
        }

        return $this->resize($this->getSourceWidth(), $this->getSourceHeight());
    }

    // http://stackoverflow.com/a/28819866
    public function imageCreateJpegfromExif($filename){
      $img = imagecreatefromjpeg($filename);
      
      if (!function_exists('exif_read_data') || !isset($this->source_info['APP1'])  || strpos ($this->source_info['APP1'], 'Exif') !== 0) {
          return $img;
      }
     
      $exif = exif_read_data($filename);

      if (!$exif || !isset($exif['Orientation'])){
        return $img;
      }

      $orientation = $exif['Orientation'];

      if ($orientation === 6 || $orientation === 5){
        $img = imagerotate($img, 270, null);
      } else if ($orientation === 3 || $orientation === 4){
        $img = imagerotate($img, 180, null);
      } else if ($orientation === 8 || $orientation === 7){
        $img = imagerotate($img, 90, null);
      }

      if ($orientation === 5 || $orientation === 4 || $orientation === 7){
       	$max_x = imagesx($img) - 1;
		$half_x = $max_x / 2;
		$sy = imagesy($img);
		$temp_image = imageistruecolor($img)? imagecreatetruecolor(1, $sy): imagecreate(1, $sy);
		for ($x = 0; $x < $half_x; ++$x) {
		  imagecopy($temp_image, $img, 0, 0, $x, 0, 1, $sy);
		  imagecopy($img, $img, $x, 0, $max_x - $x, 0, 1, $sy);
		  imagecopy($img, $temp_image, $max_x - $x, 0, 0, 0, 1, $sy);
		}
		imagedestroy($temp_image);
      }
      return $img;
    }

    /**
     * Saves new image
     *
     * @param string $filename
     * @param string $image_type
     * @param integer $quality
     * @param integer $permissions
     * @return \static
     */
    public function save($filename, $image_type = null, $quality = null, $permissions = null)
    {
        $image_type = $image_type ?: $this->source_type;
        $quality = is_numeric($quality) ? (int) abs($quality) : null;

        switch ($image_type) {
            case IMAGETYPE_GIF:
                $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight());

                $background = imagecolorallocatealpha($dest_image, 255, 255, 255, 1);
                imagecolortransparent($dest_image, $background);
                imagefill($dest_image, 0, 0 , $background);
                imagesavealpha($dest_image, true);
                break;

            case IMAGETYPE_JPEG:
                $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight());

                $background = imagecolorallocate($dest_image, 255, 255, 255);
                imagefilledrectangle($dest_image, 0, 0, $this->getDestWidth(), $this->getDestHeight(), $background);
                break;

            case IMAGETYPE_PNG:
                if (!$this->quality_truecolor && !imageistruecolor($this->source_image)) {
                    $dest_image = imagecreate($this->getDestWidth(), $this->getDestHeight());

                    $background = imagecolorallocatealpha($dest_image, 255, 255, 255, 1);
                    imagecolortransparent($dest_image, $background);
                    imagefill($dest_image, 0, 0 , $background);
                } else {
                    $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight());
                }

                imagealphablending($dest_image, false);
                imagesavealpha($dest_image, true);
                break;
        }

        imageinterlace($dest_image, $this->interlace);

        imagecopyresampled(
            $dest_image,
            $this->source_image,
            $this->dest_x,
            $this->dest_y,
            $this->source_x,
            $this->source_y,
            $this->getDestWidth(),
            $this->getDestHeight(),
            $this->source_w,
            $this->source_h
        );

        switch ($image_type) {
            case IMAGETYPE_GIF:
                imagegif($dest_image, $filename);
                break;

            case IMAGETYPE_JPEG:
                if ($quality === null || $quality > 100) {
                    $quality = $this->quality_jpg;
                }

                imagejpeg($dest_image, $filename, $quality);
                break;

            case IMAGETYPE_PNG:
                if ($quality === null || $quality > 9) {
                    $quality = $this->quality_png;
                }

                imagepng($dest_image, $filename, $quality);
                break;
        }

        if ($permissions) {
            chmod($filename, $permissions);
        }

        imagedestroy($dest_image);

        return $this;
    }

    /**
     * Convert the image to string
     *
     * @param int $image_type
     * @param int $quality
     * @return string
     */
    public function getImageAsString($image_type = null, $quality = null)
    {
        $string_temp = tempnam(sys_get_temp_dir(), '');

        $this->save($string_temp , $image_type, $quality);

        $string = file_get_contents($string_temp);

        unlink($string_temp);

        return $string;
    }

    /**
    * Convert the image to string with the current settings
    *
    * @return string
    */
    public function __toString()
    {
        return $this->getImageAsString();
    }

    /**
     * Outputs image to browser
     * @param string $image_type
     * @param integer $quality
     */
    public function output($image_type = null, $quality = null)
    {
        $image_type = $image_type ?: $this->source_type;

        header('Content-Type: ' . image_type_to_mime_type($image_type));

        $this->save(null, $image_type, $quality);
    }

    /**
     * Resizes image according to the given short side (short side proportional)
     *
     * @param integer $max_short
     * @param boolean $allow_enlarge
     * @return \static
     */
    public function resizeToShortSide($max_short, $allow_enlarge = false)
    {
        if ($this->getSourceHeight() < $this->getSourceWidth()) {
            $ratio = $max_short / $this->getSourceHeight();
            $long = $this->getSourceWidth() * $ratio;

            $this->resize($long, $max_short, $allow_enlarge);
        } else {
            $ratio = $max_short / $this->getSourceWidth();
            $long = $this->getSourceHeight() * $ratio;

            $this->resize($max_short, $long, $allow_enlarge);
        }
        
        return $this;
    }

    /**
     * Resizes image according to the given long side (short side proportional)
     *
     * @param integer $max_long
     * @param boolean $allow_enlarge
     * @return \static
     */
    public function resizeToLongSide($max_long, $allow_enlarge = false)
    {
        if ($this->getSourceHeight() > $this->getSourceWidth()) {
            $ratio = $max_long / $this->getSourceHeight();
            $short = $this->getSourceWidth() * $ratio;

            $this->resize($short, $max_long, $allow_enlarge);
        } else {
            $ratio = $max_long / $this->getSourceWidth();
            $short = $this->getSourceHeight() * $ratio;

            $this->resize($max_long, $short, $allow_enlarge);
        }
        
        return $this;
    }

    /**
     * Resizes image according to the given height (width proportional)
     *
     * @param integer $height
     * @param boolean $allow_enlarge
     * @return \static
     */
    public function resizeToHeight($height, $allow_enlarge = false)
    {
        $ratio = $height / $this->getSourceHeight();
        $width = $this->getSourceWidth() * $ratio;

        $this->resize($width, $height, $allow_enlarge);

        return $this;
    }

    /**
     * Resizes image according to the given width (height proportional)
     *
     * @param integer $width
     * @param boolean $allow_enlarge
     * @return \static
     */
    public function resizeToWidth($width, $allow_enlarge = false)
    {
        $ratio  = $width / $this->getSourceWidth();
        $height = $this->getSourceHeight() * $ratio;

        $this->resize($width, $height, $allow_enlarge);

        return $this;
    }

    /**
     * Resizes image to best fit inside the given dimensions
     *
     * @param integer $max_width
     * @param integer $max_height
     * @param boolean $allow_enlarge
     * @return \static
     */
    public function resizeToBestFit($max_width, $max_height, $allow_enlarge = false)
    {
        if($this->getSourceWidth() <= $max_width && $this->getSourceHeight() <= $max_height && $allow_enlarge === false){
            return $this;
        }

        $ratio  = $this->getSourceHeight() / $this->getSourceWidth();
        $width = $max_width;
        $height = $width * $ratio;

        if($height > $max_height){
            $height = $max_height;
            $width = $height / $ratio;
        }

        return $this->resize($width, $height, $allow_enlarge);
    }

    /**
     * Resizes image according to given scale (proportionally)
     *
     * @param integer|float $scale
     * @return \static
     */
    public function scale($scale)
    {
        $width  = $this->getSourceWidth() * $scale / 100;
        $height = $this->getSourceHeight() * $scale / 100;

        $this->resize($width, $height, true);

        return $this;
    }

    /**
     * Resizes image according to the given width and height
     *
     * @param integer $width
     * @param integer $height
     * @param boolean $allow_enlarge
     * @return \static
     */
    public function resize($width, $height, $allow_enlarge = false)
    {
        if (!$allow_enlarge) {
            // if the user hasn't explicitly allowed enlarging,
            // but either of the dimensions are larger then the original,
            // then just use original dimensions - this logic may need rethinking

            if ($width > $this->getSourceWidth() || $height > $this->getSourceHeight()) {
                $width  = $this->getSourceWidth();
                $height = $this->getSourceHeight();
            }
        }

        $this->source_x = 0;
        $this->source_y = 0;

        $this->dest_w = $width;
        $this->dest_h = $height;

        $this->source_w = $this->getSourceWidth();
        $this->source_h = $this->getSourceHeight();

        return $this;
    }

    /**
     * Crops image according to the given width, height and crop position
     *
     * @param integer $width
     * @param integer $height
     * @param boolean $allow_enlarge
     * @param integer $position
     * @return \static
     */
    public function crop($width, $height, $allow_enlarge = false, $position = self::CROPCENTER)
    {
        if (!$allow_enlarge) {
            // this logic is slightly different to resize(),
            // it will only reset dimensions to the original
            // if that particular dimenstion is larger

            if ($width > $this->getSourceWidth()) {
                $width  = $this->getSourceWidth();
            }

            if ($height > $this->getSourceHeight()) {
                $height = $this->getSourceHeight();
            }
        }

        $ratio_source = $this->getSourceWidth() / $this->getSourceHeight();
        $ratio_dest = $width / $height;

        if ($ratio_dest < $ratio_source) {
            $this->resizeToHeight($height, $allow_enlarge);

            $excess_width = ($this->getDestWidth() - $width) / $this->getDestWidth() * $this->getSourceWidth();

            $this->source_w = $this->getSourceWidth() - $excess_width;
            $this->source_x = $this->getCropPosition($excess_width, $position);

            $this->dest_w = $width;
        } else {
            $this->resizeToWidth($width, $allow_enlarge);

            $excess_height = ($this->getDestHeight() - $height) / $this->getDestHeight() * $this->getSourceHeight();

            $this->source_h = $this->getSourceHeight() - $excess_height;
            $this->source_y = $this->getCropPosition($excess_height, $position);

            $this->dest_h = $height;
        }

        return $this;
    }

    /**
     * Crops image according to the given width, height, x and y
     *
     * @param integer $width
     * @param integer $height
     * @param integer $x
     * @param integer $y
     * @return \static
     */
    public function freecrop($width, $height, $x = false, $y = false)
    {
        if($x === false or $y === false){
          return $this->crop($width, $height);
        }
        $this->source_x = $x;
        $this->source_y = $y;
        if($width > $this->getSourceWidth() - $x){
          $this->source_w = $this->getSourceWidth() - $x;
        } else {
          $this->source_w = $width;
        }

        if($height > $this->getSourceHeight() - $y){
          $this->source_h = $this->getSourceHeight() - $y;
        } else {
          $this->source_h = $height;
        }

        $this->dest_w = $width;
        $this->dest_h = $height;

        return $this;
    }

    /**
     * Gets source width
     *
     * @return integer
     */
    public function getSourceWidth()
    {
        return $this->original_w;
    }

    /**
     * Gets source height
     *
     * @return integer
     */
    public function getSourceHeight()
    {
        return $this->original_h;
    }

    /**
     * Gets width of the destination image
     *
     * @return integer
     */
    public function getDestWidth()
    {
        return $this->dest_w;
    }

    /**
     * Gets height of the destination image
     * @return integer
     */
    public function getDestHeight()
    {
        return $this->dest_h;
    }

    /**
     * Gets crop position (X or Y) according to the given position
     *
     * @param integer $expectedSize
     * @param integer $position
     * @return integer
     */
    protected function getCropPosition($expectedSize, $position = self::CROPCENTER)
    {
        $size = 0;
        switch ($position) {
            case self::CROPBOTTOM:
            case self::CROPRIGHT:
                $size = $expectedSize;
                break;
            case self::CROPCENTER:
            case self::CROPCENTRE:
                $size = $expectedSize / 2;
                break;
            case self::CROPTOPCENTER:
                $size = $expectedSize / 4;
                break;
        }
        return $size;
    }
}


class BackupHelper
{
    protected static $_data;
	protected static $zipped;
	protected static $fp;
	protected static $isopen;
	//protected $filename;
	const NAME = 'trade';

    public static function store()
    {
		$db	= JFactory::getDBO();
		$config = JFactory::getConfig();
		$dbname = $config->get('db');
		
		$dbprefix = 'wos_'.self::NAME;
		$component = 'com_'.self::NAME;
		$gzip	= JRequest::getVar( 'gzip', '', 'post', 'string' );
		$alltables = JRequest::getVar( 'alltables', '', 'post', 'string' );
		$dataonly = JRequest::getVar( 'dataonly', '1', 'post', 'string' );
		
		if ($alltables == "yes")
			$sql = "SHOW TABLE STATUS FROM `".$dbname."`";		
		else 
			$sql = "SHOW TABLE STATUS FROM `".$dbname."` LIKE '".$dbprefix."%'";
		$db->setQuery($sql);
		$tables = $db->loadObjectList();	
//var_dump($tables);
		// Create SQL Header
		$sql_file = $component.".sql";
		$sql_file2 = $component."_".date("Ymd_Hi").".sql";
		
		// Create Backups folder
		if (!file_exists('backups/')) {
			mkdir('backups/', 0755, true);
		}
		self::createFile("backups/".$sql_file);	
		self::makeHeaderTableDefJob($dbname, count($tables));		
		
		// Create SQL Content		
		$key = 0;
		
		$table_names = array();
		while ($key < count($tables)){
			if (!$dataonly)
				self::makeTableDef($dbname, $tables[$key]->Name);

			self::makeTableContent($tables[$key]->Name,$tables[$key]->Rows);
			
			if ($tables[$key]->Rows>0)$table_names[] = $tables[$key]->Name;
			$key++;
		}
		self::makeCategory($component);
		self::closeFile();
		copy("backups/".$sql_file, "backups/".$sql_file2);
      
		// Compress as gzip
		if ($gzip=="yes") {
			self::compressFile("backups/".$sql_file);
			unlink("backups/".$sql_file);
		}
		
		$app = JFactory::getApplication();
		$app->enqueueMessage('Data of "'.implode('", "',$table_names).'" are backuped!', 'success');
		$app->redirect('index.php?option='.$component);
		//return true;
    }

    public static function delete()
    {
		// Initialize variables
		$cid	= JRequest::getVar( 'cid', array(), 'post', 'array' );
		$n		= count( $cid );
		
		for ($i=0;$i<$n;$i++)
			unlink("backups/".$cid[$i]);		
		return true;
    }
	
	public static function restore ()
	{
		$db	= JFactory::getDBO();
		$offset =0;
		$multiLine = false;
		$SQL_Lines  =0;
		$query = '';
		$comments[0] = "#";
		$comments[1] = "--";
		$filename = JRequest::getVar( 'filename', 'com_'.self::NAME.'.sql', 'get', 'string' );
		
		if (self::open2Read("backups/".$filename)) {
			self::seekBuffer($offset);
		} else {
			//mosRedirect("index.php?option=com_backup", "Error opening SQL Dump file ".$filename);
			echo "Error opening SQL Dump file ".$filename;
		}
		while (!self::is_EOF()){
			$buffer = self::readBuffer(4096);
			//$buffer = trim($buffer);
			//$buffer = ereg_replace("\r\n$", "\n", $buffer);
			//$buffer = ereg_replace("\r$", "\n", $buffer);
			
			$skipline = false;
			foreach ($comments as $comment_value){
				if (strpos($buffer, $comment_value) === 0){
					$skipline = true;
                }
			}
			
			if (!$skipline && (strlen($buffer)!= 0))
			{
             if (!$multiLine){
				if (strrpos(trim($buffer), ";") >0){
					$SQL_Lines++;
					$query.= $buffer;
					$db->setQuery($query);
					$result = $db->query();
					echo $query."<BR><BR>";
					if (!$result) break;
					$query = "";
					} else {
						$multiLine = true;
						$query.= $buffer;
					}
				} else {
					if (strrpos(trim($buffer), ";") >0) {
						$multiLine = false;
						$SQL_Lines++;
						$query.= $buffer;
						$db->setQuery($query);
						$result = $db->query();
						echo $query."<BR><BR>";
					if (!$result) break;
						$query = "";
					} else {
						$query.= $buffer;
					}
				}
			}
	
		}
		
		$app = JFactory::getApplication();
		$app->enqueueMessage('Data restored!', 'success');
		$app->redirect('index.php?option='.'com_'.self::NAME);
		//return true;
	}

	public static function compressFile($source, $level=false){
		$dest = $source.'.gz';
		$mode = 'wb'.$level;
		$error = false;
		if ($fp_out=gzopen($dest,$mode)) {
			if ($fp_in=fopen($source,'rb')) {
				while(!feof($fp_in))
					gzwrite($fp_out,fread($fp_in,1024*512));
				fclose($fp_in);
			}
			else $error=true;
			gzclose($fp_out);
		} else
			$error=true;
		if ($error)
			return false;
		else
			return $dest;
	}

	public static function createFile($filename) {
		//$filename = $filename;
		if (self::$fp = fopen($filename, "wb")) {
			@chmod ($configfile, 0777);
			self::$isopen = true;
			return $filename;
		} else {
			self::$isopen = false;
			return FALSE;
		}
	}

	public static function openFile($filename){
		//$filename = $filename;
		if (self::$fp = fopen($filename, "ab")) {
			self::$isopen = true;
			return $filename;
		} else {
			self::$isopen = false;
			return false;
		}
	}

	public static function open2Read($filename){
		//$filename = $filename;
		$path_parts = pathinfo($filename);
		if (strtolower($path_parts["extension"]) == "gz") {
			self::$zipped = true;
			if (self::$fp = gzopen($filename, "rb")) {
				self::$isopen = true;
				return true;
			} else {
				self::$isopen = false;
				return false;
			}
		} else {
			self::$zipped = false;
			if (self::$fp = fopen($filename, "rb")) {
				self::$isopen = true;
				return true;
			} else {
				self::$isopen = false;
				return false;
			}
		}
	}

	public static function readBuffer($buf_size){
		if (self::$isopen) {
			if (self::$zipped){
				return gzgets(self::$fp, $buf_size);
			} else {
				return fgets(self::$fp, $buf_size);
			}
		} else {
			return false;
		}
	}

	public static function is_EOF(){
		if (self::$isopen){
			if (self::$zipped){
				return gzeof(self::$fp);
			} else {
				return feof(self::$fp);
			}
		}
	}

	public static function seekBuffer($offset){
		if (self::$isopen){
			if (self::$zipped){
				return gzseek(self::$fp, $offset);
			} else {
				return fseek(self::$fp, $offset);
			}
		}
	}

	public static function getOffset(){
		if (self::$isopen){
			if (self::$zipped){
				return gztell(self::$fp);
			}else{
				return ftell(self::$fp);
			}
		}
	}

	public static function writeFile($data){
		fwrite(self::$fp, $data);
	}

	public static function closeFile(){
		if (self::$zipped){
			self::compressFile($filename, 9);
			fclose(self::$fp);
			unlink($filename);
			self::$isopen = false;
		} else {
			fclose(self::$fp);
			self::$isopen = false;
		}
	}

	public static function getFileSize(){
		$size = 0;
		if (!self::$isopen){
			if (self::$zipped){
				$size = filesize($filename.".gz");
			}else{
				$size = filesize($filename);
			}
		}
		return $size;
	}

	public static function getFileInfo($filename){
		$info       = "";
		$path_parts = pathinfo($filename);
		if (strtolower($path_parts["extension"]) == "gz"){
			$file = gzopen($filename, "r");
			while (!gzeof($file)){
				$buffer = trim(gzgets($file, MAX_LINE_LENGTH));
				if (strlen($buffer)== 0){
					break;
				}else{
					$info.= str_replace(' ', "&nbsp;", $buffer)."<br />";
				}
			}
			gzclose($file);
			return $info;
		} else {
		$file = fopen($filename, "r");
			while (!feof($file)){
				$buffer = trim(fgets($file, MAX_LINE_LENGTH));
				if (strlen($buffer)== 0){
					break;
				} else {
					$info.= str_replace(' ', "&nbsp;", $buffer)."<br />";
				}
			}
			fclose($file);
			return $info;
		}

	}

	public static function makeHeaderTableDefJob($item, $tab_count){

		$crlf          = "\r\n";

		$header = "# ===============================================================$crlf";
		$header.= "# $crlf";
		$header.= "# Name of Database   : $item $crlf";
		$header.= "# Backup created at  : ".date('Y-m-d H:i:s')."$crlf";
		$header.= "# Tables             : $tab_count $crlf";
		$header.= "# $crlf";
		$header.= "# Environment$crlf";
		$header.= "#   MySQL Server     : ".mysqli_get_server_info()."$crlf";
		$header.= "#   MySQL Client     : ".mysqli_get_client_info()."$crlf";
		$header.= "#   PHP Version      : ".phpversion()."$crlf";
		$header.= "# $crlf";
		$header.= "# ===============================================================$crlf$crlf";
		self::writeFile($header);
	}

	public static function makeTableDef($base, $table){
		$db	= JFactory::getDBO();
		$crlf="\r\n";
		$create = "";
		$config_drop = 1;
		$config_autoinc = 0;
		$config_utf8 = 1;
		$config_not_exists = 1;
	//	$database->setQuery('SET @@SESSION.SQL_MODE="'.$settings->o_sql_compat.'"');
	//	$database->Query();

		$result = $db->setQuery("SHOW CREATE TABLE `".$table."`");
		$rows   = $db->loadrow();
		$create_query = $rows[1];
		$create_query = preg_replace('/ AUTO_INCREMENT=(\d{1,2,3})/','',$create_query);

		if (strpos($create_query, "(\r\n ")) {
			$create_query = str_replace("\r\n", $crlf, $create_query);
		} elseif (strpos($create_query, "(\n ")) {
			$create_query = str_replace("\n", $crlf, $create_query);
		} elseif (strpos($create_query, "(\r ")) {
			$create_query = str_replace("\r", $crlf, $create_query);
		}

		if ($config_drop != "") {
			$create = "DROP TABLE IF EXISTS `".$table."`;".$crlf;
		} else {
			$create = "";
		}
		if (!strpos($create_query, "CREATE TABLE")){
			if ($config_not_exists != "") {
				$create.= str_replace("CREATE TABLE", "CREATE TABLE IF NOT EXISTS", $create_query);
			} else {
				$create.= $create_query;
			}
		} else {
			$create.= $create_query;
		}
		
		if ($config_utf8)
			$create.=" CHARACTER SET `utf8`";

		$create.=";".$crlf.$crlf;

		

		$header = "# ===============================================================$crlf"
				."# $crlf"
				."# Table Structure for `$table` $crlf"
				."# $crlf"
				."# ===============================================================$crlf$crlf";
		self::writeFile($header.$create);
	}

	public static function makeTableContent($table,$rows){
		$db	= JFactory::getDBO();
		$crlf="\r\n";
		if ($rows>0) {

			$header = "# ===============================================================$crlf"
					."# $crlf"
					."# Data for Table `$table` $crlf"
					."# No. of rows: ".$rows.$crlf
					."# $crlf"
					."# ===============================================================$crlf$crlf";
			self::writeFile($header);
		}

		$sql = "SELECT * FROM ".$table;
		$db->setQuery($sql);
		$result = $db->loadObjectList();
		
		//while ($row = mysql_fetch_assoc($result)){
		for ($i=0;$i<count($result);$i++) {
			$row = $result[$i];

				$item_list = "(";
				foreach ($row as $col => $value) {
						$item_list.= "`".addslashes($col)."`, ";
				}
				$item_list = substr($item_list, 0, -2);
				$item_list.= ")";
				$insert = "INSERT INTO `$table` $item_list VALUES (";
				// $insert = "INSERT INTO `$table` VALUES (";
				
			$data = "";
			foreach ($row as $value) {
					if (!isset($value)) {
					$data.= " NULL,";
					} elseif ($value != "") {
					$data.= " '".addslashes($value)."',";
					} else {
					$data.= " '',";
					}
			}
			$insert.= substr($data, 0, -1);
			$insert.= ");".$crlf;
			self::writeFile($insert);
		}
		return true;
	}

	public static function makeCategory($component){
		$db	= JFactory::getDBO();
		$crlf="\r\n";

		$sql = "SELECT * FROM #__categories WHERE extension='".$component."'";
		$db->setQuery($sql);
		$result = $db->loadObjectList();

		if (count($result)>0) {

			$header = "# ===============================================================$crlf"
					."# $crlf"
					."# Data for Category `$component $crlf"
					."# No. of rows: ".count($result).$crlf
					."# $crlf"
					."# ===============================================================$crlf$crlf";
			self::writeFile($header);
		}

		//while ($row = mysql_fetch_assoc($result)){
		for ($i=0;$i<count($result);$i++) {
			$row = $result[$i];

				$item_list = "(";
				foreach ($row as $col => $value) {
						$item_list.= "`".addslashes($col)."`, ";
				}
				$item_list = substr($item_list, 0, -2);
				$item_list.= ")";
				$insert = "INSERT INTO `#__categories` $item_list VALUES (";
				// $insert = "INSERT INTO `$component` VALUES (";
				
			$data = "";
			foreach ($row as $value) {
					if (!isset($value)) {
					$data.= " NULL,";
					} elseif ($value != "") {
					$data.= " '".addslashes($value)."',";
					} else {
					$data.= " '',";
					}
			}
			$insert.= substr($data, 0, -1);
			$insert.= ");".$crlf;
			self::writeFile($insert);
		}
		return true;
	}
}


class ExcelHelper
{
    public static function export($query,$filename)
    {
        try {
            if ($file_path = self::getExportedFile($query,$filename)) {
                //$file_name = basename($file_path);

                header('Content-type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
                header('Content-Disposition:attachment;filename=' . $filename.'.xlsx');

                readfile($file_path);
            }
        } catch (\Exception $e) {
            return false;
        }

        exit;
    }
	
	public static function getExportHeaders()
	{
		$table = JTable::getInstance('##Singular##', 'HkpcTable');
		$fields = array_keys($table->getFields());
		
        $header = [];
        foreach ($fields as $it) {
            switch ($it) {
                case 'id':
                    $header[$it] = 'ID';
                    break;
                
                case 'published':
                    $header[$it] = JText::_('JPUBLISHED');
                    break;

                case 'created':
                    $header[$it] = JText::_('JGLOBAL_CREATED');
                    break;

                case 'created_by':
                    $header[$it] = JText::_('JGLOBAL_FIELD_CREATED_BY_LABEL');
                    break;

                case 'modified':
                    $header[$it] = JText::_('JGLOBAL_FIELD_MODIFIED_LABEL');
                    break;

                case 'modified_by':
                    $header[$it] = JText::_('JGLOBAL_FIELD_MODIFIED_BY_LABEL');
                    break;

                case 'ordering':
                    $header[$it] = JText::_('JFIELD_ORDERING_LABEL');
                    break;

                case 'state':
                    $header[$it] = JText::_('JSTATUS');
                    break;

                case 'access':
                    $header[$it] = JText::_('JFIELD_ACCESS_LABEL');
                    break;

                case 'alias':
                    $header[$it] = JText::_('JFIELD_ALIAS_LABEL');
                    break;

                default:
                    $header[$it] = JText::_('COM_HKPC_##TABLE##_FIELD_' . strtoupper($it) . '_LABEL');
                    break;
            }
        }
		return $header;
	}
	
	public static function getExportedFile($query,$filename)
	{
		$writer = \Box\Spout\Writer\WriterFactory::create(\Box\Spout\Common\Type::XLSX);
	    $export_tmp_file = JPATH_ROOT . '/tmp/'.$filename.'.xlsx';
	
	    $db = JFactory::getDBO();
	    $db->setQuery($query);
	    $results = $db->loadAssocList();
	
		//$header = self::getExportHeaders();
		$header_orders = array_keys($results[0]);

	    $data = [];
	    foreach ($results as $key => $record) {
	    	$row = [];
	        foreach ($header_orders as $key) {
	            $value = isset($record[$key]) ? $record[$key] : null;
	            array_push($row, $value);
	        }

	        $data[] = $row;
	    }
		
	    try {
			$writer->openToFile($export_tmp_file);

	        $writer->addRow($header_orders);
	        $writer->addRows($data);
	    } catch (\Exception $e) {
	        $this->setError($e->getMessage());
	        $writer->close();
	        return false;
	    }

	    $writer->close();

	    return $export_tmp_file;
	}
	
	public static function createFromString($image_data)
    {
        $model = $this->getModel('##Plural##', 'HkpcModel');

        try {
            if ($file_path = $model->export()) {
                $file_name = basename($file_path);

                header('Content-type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
                header('Content-Disposition:attachment;filename=' . $file_name);

                readfile($file_path);
            }
        } catch (\Exception $e) {
            $this->setMessage($e->getMessage(), 'error');
            $this->setRedirect(JRoute::_('index.php?option=com_hkpc&view=##plural##', false));
        }

        exit;
    }
}
