<?php

/**
 * RokGallery_Model_Slice
 *
 * This class has been auto-generated by the Doctrine ORM Framework
 *
 * @package    RokGallery
 * @subpackage models
 * @author     RocketTheme LLC <support@rockettheme.com>
 * @version    SVN: $Id: Slice.php 39573 2011-07-06 09:59:45Z btowles $
 */
class RokGallery_Model_Slice extends RokGallery_Model_Base_Slice
{
    /**
     * @param Doctrine_Event $event
     * @return void
     */
    public function preDelete($event)
    {
        RokGallery_Model_SliceFilter::cleanThumbInfo();
        // Add slice to be removed
        RokGallery_Queue_FileDelete::add($this->getFullPath());

        // Add thumb to be removed
        RokGallery_Queue_FileDelete::add($this->getThumbFullPath());

        // Remove the admin thumb
        RokGallery_Queue_FileDelete::add($this->getThumbFullPath('admin-thumb'));

        // Remove the admin thumb
        RokGallery_Queue_FileDelete::add($this->getThumbFullPath('mini-admin-thumb'));
    }

	/**
	 * @param \Doctrine_Event $event
	 * @return void
	 */
    public function postDelete($event)
    {

        //Make sure all linked tables are clean

        //RokGallery_Model_SliceTags
        $q = Doctrine_Query::create()
            ->delete('RokGallery_Model_SliceTags st')
            ->andWhere('st.slice_id NOT IN (SELECT s.id from RokGallery_Model_Slice s)');
        $q->execute();
        $q->free();

        //rokgallery_slices_index
        $conn = Doctrine_Manager::connection();
        $dbh = $conn->getDbh();
        $stmt = $dbh->prepare('delete from ' . RokCommon_Doctrine::getPlatformInstance()->setTableName('rokgallery_slices_index')
                . ' where id NOT IN (SELECT s.id from ' . RokGallery_Model_SliceTable::getInstance()->getTableName() . ' s)');
        $stmt->execute();

    }

    /**
     * @param Doctrine_Event $event
     * @return void
     */
    public function preUpdate($event)
    {
        RokGallery_Model_SliceFilter::cleanThumbInfo();
        $record = $event->getInvoker();
        $modified = $record->getModified();
        $original = $record->getModified(true);

        // Dont let a direct change from the admin thumb happen
        if (array_key_exists('admin_thumb', $modified)
            && $modified['admin_thumb'] == false
            && $original['admin_thumb'] == true
        ) {
            $this->admin_thumb = true;
        }

        if (empty($this->title)) {
            $this->title = $this->File->title;
        }
        if (empty($this->caption)) {
            $this->caption = $this->File->description;
        }

        if (array_key_exists('manipulations', $modified)) {
            $this->processImages();
        }

        // set background color to transparent
        if (empty($this->thumb_background))
        {
             $this->thumb_background = 'transparent';
        }
    }

    /**
     * @param   Doctrine_Event $event
     * @return void
     */
    public function preInsert($event)
    {
        RokGallery_Model_SliceFilter::cleanThumbInfo();
        if (empty($this->title)) {
            $this->title = $this->File->title;
        }
        if (empty($this->caption)) {
            $this->caption = $this->File->description;
        }

        // set background color to transparent
        if (empty($this->thumb_background))
        {
             $this->thumb_background = 'transparent';
        }
        $this->processImages();
    }


    /**
     * @return void
     */
    protected function processImages()
    {
        // create the actual slice image with manipulations
        $this->applyManipulations();

        // create the thumbnails
        $this->generateAdminThumbnail();
        $this->generateMiniAdminThumbnail();
        $this->generateDefaultThumbnail();
    }


    /**
     * @param RokGallery_Model_File $file
     * @param string $title
     * @param string|null $caption
     * @param bool $publish
     * @param bool $admin_thumb
     * @return RokGallery_Model_Slice
     */
    public static function &createNew(RokGallery_Model_File &$file, $title = null, $caption = null, $publish = false, $admin_thumb = false)
    {

        $slice = new RokGallery_Model_Slice();
        $slice->guid = RokGallery_Helper::createUUID();
        $slice->title = $title;
        $slice->caption = $caption;
        $slice->admin_thumb = $admin_thumb;
        $slice->published = $publish;
        $file->Slices[] = $slice;

        return $slice;
    }

	/**
	 * Applies an array of RokGallery_Manipulation_Action objects to a slice and saves the resulting image as the slice
	 * These manipulations are applied in order.
	 *
	 * @return void
	 */
    public function applyManipulations()
    {

        $slice_image_path = $this->getFullPath();

        // Get the base image
        RokGallery_Memory::adjustLimitForImage($this->File->xsize, $this->File->ysize);
        $start_image = WideImage::loadFromFile($this->File->getFullPath());
        $changed_image = $start_image;
        $working_image = $changed_image;

        // Apply the changes to the image
        foreach ($this->manipulations as $change)
        {
	        if (!isset($working_image)) $working_image = $changed_image;
            // Get the base image
            RokGallery_Memory::adjustLimitForImage($working_image->getWidth(), $working_image->getHeight());
            // apply the change to the working image
            $changed_image = $change->apply($working_image);

            // free the working image
            $working_image->destroy();
            unset($working_image);
        }

        $changed_image->saveToFile($slice_image_path, RokGallery_Helper::getImageQuality($this->File->type));
        RokGallery_Queue_FileCreate::add($slice_image_path);

        // record slice info
        $this->xsize = $changed_image->getWidth();
        $this->ysize = $changed_image->getHeight();
        $this->filesize = @filesize($slice_image_path);

        // free the working image
        $changed_image->destroy();
        unset($changed_image);
    }

	/**
	 *
	 * @return void
	 */
	public function generateDefaultThumbnail()
    {
        if ($this->gallery_id != null) {
            $this->generateThumbnail($this->Gallery->thumb_xsize, $this->Gallery->thumb_ysize, $this->Gallery->thumb_keep_aspect, $this->Gallery->thumb_background);
            $this->thumb_xsize = $this->Gallery->thumb_xsize;
            $this->thumb_ysize = $this->Gallery->thumb_ysize;
            $this->thumb_keep_aspect = $this->Gallery->thumb_keep_aspect;
            $this->thumb_background = $this->Gallery->thumb_background;
        }
        else
        {
            $xsize = $this->thumb_xsize;
            $ysize = $this->thumb_ysize;
            $keep = $this->thumb_keep_aspect;
            $background = $this->thumb_background;

            if (($xsize == null || $xsize == 0) && ($ysize == null || $ysize == 0))
            {
                $xsize = RokGallery_Config::getOption(RokGallery_Config::OPTION_DEFAULT_THUMB_XSIZE, RokGallery_Config::DEFAULT_DEFAULT_THUMB_XSIZE);
                $ysize = RokGallery_Config::getOption(RokGallery_Config::OPTION_DEFAULT_THUMB_YSIZE, RokGallery_Config::DEFAULT_DEFAULT_THUMB_YSIZE);
                $keep = RokGallery_Config::getOption(RokGallery_Config::OPTION_DEFAULT_THUMB_KEEP_ASPECT, RokGallery_Config::DEFAULT_DEFAULT_THUMB_KEEP_ASPECT);
                $background =  RokGallery_Config::getOption(RokGallery_Config::OPTION_DEFAULT_THUMB_BACKGROUND, RokGallery_Config::DEFAULT_DEFAULT_THUMB_BACKGROUND);
                $this->thumb_xsize = $xsize;
                $this->thumb_ysize = $ysize;
                $this->thumb_keep_aspect = $keep;
                $this->thumb_background = $background;
            }
            $this->generateThumbnail($xsize, $ysize, $keep, $background);

        }
    }

    /**
     * @return void
     */
    public function generateAdminThumbnail()
    {
        $this->generateThumbnail(RokGallery_Config::DEFAULT_ADMIN_THUMB_XSIZE, RokGallery_Config::DEFAULT_ADMIN_THUMB_YSIZE, true, RokGallery_Config::getOption(RokGallery_Config::OPTION_ADMIN_THUMB_BACKGROUND), "admin-thumb");

    }

	/**
	 *
	 * @return void
	 */
	public function generateMiniAdminThumbnail()
    {
        $this->generateThumbnail(RokGallery_Config::DEFAULT_MINI_ADMIN_THUMB_XSIZE, RokGallery_Config::DEFAULT_MINI_ADMIN_THUMB_YSIZE, true, RokGallery_Config::getOption(RokGallery_Config::OPTION_ADMIN_THUMB_BACKGROUND), "mini-admin-thumb");
    }

    /**
     * Generates a thumbnail image for a slice
     *
     * @param $thumb_x
     * @param $thumb_y
     * @param bool $keep_aspect
     * @param null $background_color
     * @param string $extension
     *
     * @return
     */
    public function generateThumbnail($thumb_x, $thumb_y, $keep_aspect = true, $background_color = null, $extension = "thumb")
    {
        $slices_dir = dirname($this->File->getFullPath());
        $thumb_path = $this->getThumbFullPath($extension);

        // get the slice image
        RokGallery_Memory::adjustLimitForImage($this->xsize, $this->ysize);
	    try{
            $slice_image = WideImage::loadFromFile($this->getFullPath());
	    }
	    catch(WideImage_InvalidImageSourceException $e){
		    return;
	    }

        if ($background_color == 'transparent' || empty($background_color)){
            $background_color = null;
        }

        // if he image size is smaller then the thumbnail size
        // resize the canvas with optioned color and place in center
        if ($this->xsize < $thumb_x && $this->ysize < $thumb_y) {
            // Resize canvas
            RokGallery_Memory::adjustLimitForImage($thumb_x, $thumb_y);
            $thumb_image = $slice_image->resizeCanvas($thumb_x, $thumb_y, 'center', 'center',
                                                      ($background_color == null) ? $background_color
                                                              : $slice_image->allocateColor(RokGallery_Helper::html2rgb($background_color)));
            $slice_image->destroy();
            unset($slice_image);

            // write out image
            $thumb_image->saveToFile($thumb_path, RokGallery_Helper::getImageQuality($this->File->type));
            RokGallery_Queue_FileCreate::add($thumb_path);
            $thumb_image->destroy();
            unset($thumb_image);
        }
        else
        {
            if ($keep_aspect) {
                // Keep the aspect Ratio
                RokGallery_Memory::adjustLimitForImage($thumb_x, $thumb_y);
                $thumb_image_after_resize = $slice_image->resize($thumb_x, $thumb_y);
                $slice_image->destroy();
                unset($slice_image);

                // fill in blank space
                RokGallery_Memory::adjustLimitForImage($thumb_x, $thumb_y);
                $thumb_image = $thumb_image_after_resize->resizeCanvas($thumb_x, $thumb_y, 'center', 'center',
                                                                       ($background_color == null) ? $background_color
                                                                               : $thumb_image_after_resize->allocateColor(RokGallery_Helper::html2rgb($background_color)));
                $thumb_image_after_resize->destroy();
                unset($thumb_image_after_resize);

                // write out image
                $thumb_image->saveToFile($thumb_path, RokGallery_Helper::getImageQuality($this->File->type));
                RokGallery_Queue_FileCreate::add($thumb_path);
                $thumb_image->destroy();
                unset($thumb_image);
            }
            else
            {
                // Create thumbnail but dont make thumbnail keep the aspect ratio
                $source_aspect_ratio = $this->xsize / $this->ysize;
                $desired_aspect_ratio = $thumb_x / $thumb_y;

                $temp_width = $thumb_x;
                $temp_height = $thumb_y;
                $temp_left = 0;
                $temp_top = 0;

                if ($source_aspect_ratio > $desired_aspect_ratio) // wider image
                {
                    $temp_height = $thumb_y;
                    $temp_width = ( int )round($thumb_y * $source_aspect_ratio);
                    $temp_left = (int)round(($temp_width - $thumb_x) / 2);
                    $temp_top = 0;

                }
                elseif ($source_aspect_ratio < $desired_aspect_ratio) // taller image
                {
                    $temp_width = $thumb_x;
                    $temp_height = ( int )round($thumb_x / $source_aspect_ratio);
                    $temp_left = 0;
                    $temp_top = (int)round(($temp_height - $thumb_y) / 2);
                }

                RokGallery_Memory::adjustLimitForImage($temp_width, $temp_height);
                $thumb_image_after_resize = $slice_image->resize($temp_width, $temp_height);
                $slice_image->destroy();
                unset($slice_image);

                RokGallery_Memory::adjustLimitForImage($thumb_x, $thumb_y);
                $thumb_image = $thumb_image_after_resize->crop($temp_left, $temp_top, $thumb_x, $thumb_y);
                $thumb_image_after_resize->destroy();
                unset($thumb_image_after_resize);

                // write out image
                $thumb_image->saveToFile($thumb_path, RokGallery_Helper::getImageQuality($this->File->type));
                RokGallery_Queue_FileCreate::add($thumb_path);
                $thumb_image->destroy();
                unset($thumb_image);
            }
        }
    }


	/**
	 * Gets the full path to the Thumbnail file;
	 *
	 * @param string $extension
	 *
	 * @return string
	 */
    public function getThumbFullPath($extension = 'thumb')
    {
        return dirname($this->File->getFullPath()) . DS . $this->guid . '-' . $extension . '.' . $this->File->type;
    }

	/**
	 * Returns the thumbnail path relative to the RokGallery image root.
	 *
	 * @param string $seperator
	 * @param string $extension
	 * @return string
*/
    public function getRelativeThumbPath($seperator = '/', $extension = 'thumb')
    {
        return RokGallery_Helper::getPathFromGUID($this->File->guid, $seperator) . $seperator . $this->guid . '-' . $extension . '.' . $this->File->type;
    }

    /**
     * Returns the full path to the slice image
     *
     * @return string
     */
    public function getFullPath()
    {
        return dirname($this->File->getFullPath()) . DS . $this->guid . '.' . $this->File->type;
    }

    /**
     * Returns the relative path to the slice image
     *
     * @param string $seperator
     * @return string
     */
    public function getRelativePath($seperator = '/')
    {
        return RokGallery_Helper::getPathFromGUID($this->File->guid, $seperator) . $seperator . $this->guid . '.' . $this->File->type;
    }

    /**
     * See if the slice has the passed tag
     * @param $searchtag
     * @return bool
     */
    public function hasTag($searchtag)
    {
        foreach ($this->FileTags as &$filetag)
        {
            if ($filetag->tag == $searchtag) {
                return true;
            }
        }
        foreach ($this->Tags as &$tag)
        {
            if ($tag->tag == $searchtag) {
                return true;
            }

        }
        return false;
    }

    /**
     * Add tag if it doesn't already exists;
     *
     * @param $tagtext
     * @return
     */
    public function addTag($tagtext)
    {
        $dbtag = null;
        if ($this->hasTag($tagtext)) return;
        $dbtag = new RokGallery_Model_SliceTags();
        $dbtag->tag = $tagtext;
        $this->Tags[] = $dbtag;
        return;
    }

    /**
     * @return void
     */
    public function incrementView()
    {
        $this->File->incrementView();
    }

    /**
     * @return void
     */
    public function incrementLoves()
    {
        $this->File->incrementLoves();
    }

    /**
     * @return void
     */
    public function decrementLoves()
    {
        $this->File->decrementLoves();
    }

	/**
	 * @return array
	 */
	public function &getCombinedTags()
    {
        $out = $this->Tags->toArray('false');
        $out = array_merge($out, $this->File->Tags->toArray('false'));
        return $out;
    }

	/**
	 *
	 * @return void
	 */
	public function populateFilterInfo()
    {
        $this->imageurl;
        $this->thumburl;
        $this->adminthumburl;
        $this->adminthumbxsize;
        $this->adminthumbysize;
        $this->miniadminthumburl;
        $this->miniadminthumbxsize;
        $this->miniadminthumbysize;
    }
}