<?php

require_once 'photosource/Intense-photo.php';

/**
 * Photo Sources used for gallery, widgets, etc.
 */

class Intense_Photo_Source {
    public $source = "wordpress";
    public $wordpress_attachments;
    public $userid;
    public $groupid;
    public $setid;
    public $additionalid;
    public $full_size;

    private $default_full_size = "large";

    function Intense_Photo_Source( $source, $wordpress_attachments, $userid, $groupid, $setid, $additionalid ) {
        global $intense_visions_options;

        $this->source = $source;
        $this->wordpress_attachements = $wordpress_attachments;
        $this->userid = $userid;
        $this->groupid = $groupid;
        $this->setid = $setid;
        $this->additionalid = $additionalid;
        $this->full_size = ( isset( $intense_visions_options['intense_photosource_full_size'] ) ? $intense_visions_options['intense_photosource_full_size'] : $this->default_full_size );
    }

    static function get_wordpress_photo( $id, $size ) {
        $attachment = get_post( $id );

        if ( $attachment && isset( $attachment->post_mime_type ) && $attachment->post_mime_type != 'image/svg+xml' && $attachment->post_mime_type != 'font/svg' ) {
            $attachments = array(
                $attachment->ID => $attachment
            );

            $photo_source = new Intense_Photo_Source( "wordpress", $attachments, null, null, null, null );
            $photos = $photo_source->get_photos( null, null );

            if ( isset( $photos[0] ) ) {
                $photo = $photos[0];
                $photo_size = $photo_source->get_wordpress_size( $size );
                $photo_url = $photo->get_closest_size( $photo_size["width"], $photo_size["height"] );

                return array(
                    'id' => $id,
                    'size' => $size,
                    'width' => $photo_url['width'],
                    'height' => $photo_url['height'],
                    'title' => $photo->title,
                    //'excerpt' => $excerpt,
                    'url' => $photo_url['sourceurl']
                );
            }
        } else {
            $photo_info = wp_get_attachment_image_src( $id, $size );
            if ( !empty( $photo_info ) ) {
                return array(
                    'id' => $id,
                    'size' => $size,
                    'width' => $photo_info[1],
                    'height' => $photo_info[2],
                    'title' => '',
                    'url' => $photo_info[0]
                );
            } else {
                return array(
                    'id' => $id,
                    'size' => $size,
                    'width' => '',
                    'height' => '',
                    'title' => '',
                    'url' => wp_get_attachment_url( $id )
                );
            }
        }
    }

    static function get_wordpress_photo_sizes( $size = '' ) {
        global $_wp_additional_image_sizes;

        $sizes = array();
        $get_intermediate_image_sizes = get_intermediate_image_sizes();

        // Create the full array with sizes and crop info
        foreach ( $get_intermediate_image_sizes as $_size ) {
            if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
                $sizes[ $_size ]['width'] = get_option( $_size . '_size_w' );
                $sizes[ $_size ]['height'] = get_option( $_size . '_size_h' );
                $sizes[ $_size ]['crop'] = (bool) get_option( $_size . '_crop' );
            } elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
                $sizes[ $_size ] = array(
                    'width' => $_wp_additional_image_sizes[ $_size ]['width'],
                    'height' => $_wp_additional_image_sizes[ $_size ]['height'],
                    'crop' =>  $_wp_additional_image_sizes[ $_size ]['crop']
                );
            }
        }

        $intense_sizes = Intense_Photo_Source::get_intense_photo_sizes();

        $sizes = array_merge( $sizes, $intense_sizes );

        // Get only 1 size if found
        if ( $size ) {
            if ( isset( $sizes[ $size ] ) ) {
                return $sizes[ $size ];
            } else {
                return false;
            }
        }

        return $sizes;
    }

    static function get_intense_photo_sizes() {
        global $intense_visions_options;

        $sizes = array();

        $active_image_sizes = $intense_visions_options['intense_active_image_sizes'];

        $image_sizes = array(
            "square75" => array( "name" => "square75", "width" => 75, "height" => 75, "crop" => true ),
            "square150" => array( "name" => "square150", "width" => 150, "height" => 150, "crop" => true ),
            "square400" => array( "name" => "square400", "width" => 400, "height" => 400, "crop" => true ),
            "small240" => array( "name" => "small240", "width" => 240, "height" => 160, "crop" => true ),
            "small320" => array( "name" => "small320", "width" => 320, "height" => 213, "crop" => true ),
            "medium500" => array( "name" => "medium500", "width" => 500, "height" => 333, "crop" => true ),
            "medium640" => array( "name" => "medium640", "width" => 640, "height" => 427, "crop" => true ),
            "medium800" => array( "name" => "medium800", "width" => 800, "height" => 534, "crop" => true ),
            "large1024" => array( "name" => "large1024", "width" => 1024, "height" => 683, "crop" => true ),
            "large1600" => array( "name" => "large1600", "width" => 1600, "height" => 1067, "crop" => true ),
            "large2048" => array( "name" => "large2048", "width" => 2048, "height" => 1365, "crop" => true ),
            "portraitSmall" => array( "name" => "portraitSmall", "width" => 400, "height" => 500, "crop" => false ),
            "portraitMedium" => array( "name" => "portraitMedium", "width" => 800, "height" => 1000, "crop" => false ),
            "portraitLarge" => array( "name" => "portraitLarge", "width" => 1600, "height" => 2000, "crop" => false ),
            "postWide" => array( "name" => "postWide", "width" => 940, "height" => 383, "crop" => true ),
            "postExtraWide" => array( "name" => "postExtraWide", "width" => 1410, "height" => 575, "crop" => true ),
            "postFull" => array( "name" => "postFull", "width" => 940, "height" => 623, "crop" => true )
        );

        foreach ( $image_sizes as $key => $image_size ) {
            if ( !empty( $active_image_sizes[ $image_size['name'] ] ) && $active_image_sizes[ $image_size['name'] ] ) {
                $sizes[ $image_size['name'] ] = array(
                    'width' => $image_size['width'],
                    'height' => $image_size['height'],
                    'crop' => $image_size['crop']
                );
            }
        }

        if ( isset( $intense_visions_options['intense_custom_image_sizes'] ) && $intense_visions_options['intense_custom_image_sizes'] != '' ) {
            foreach ( $intense_visions_options['intense_custom_image_sizes'] as $key => $value ) {
                $custom_image_size = explode( "|", $value );

                if ( !empty( $custom_image_size[0] ) && !empty( $custom_image_size[1] ) && !empty( $custom_image_size[2] ) && !empty( $custom_image_size[3] ) ) {
                    $sizes[ $custom_image_size[2] ] = array(
                        'width' => $custom_image_size[0],
                        'height' => $custom_image_size[1],
                        'crop' => $custom_image_size[3]
                    );
                }
            }
        }

        return $sizes;
    }

    /**
     * Gets random wordpress size that is between min and max sizes
     *
     * @param string  $min
     * @param string  $max
     * @return array
     */
    static function get_random_wordpress_size( $min = null, $max = null ) {
        $sizes = Intense_Photo_Source::get_wordpress_photo_sizes();

        if ( !isset( $min ) ) {
            $available_sizes = array_keys( $sizes );
            $min = $available_sizes[0];
        }

        if ( !isset( $max ) ) {
            $available_sizes = array_keys( $sizes );
            $max = $available_sizes[ count( $sizes ) - 1 ];
        }

        $start_offset = Intense_Photo_Source::array_offset( $sizes, $min );
        $end_offset = Intense_Photo_Source::array_offset( $sizes, $max );
        $random_offset = rand( $start_offset, $end_offset );
        $sizes = array_values( $sizes );

        return $sizes[ $random_offset ];
    }

    static function array_offset( $array, $offset_key ) {
        $offset = 0;
        foreach ( $array as $key=>$val ) {
            if ( $key == $offset_key )
                return $offset;
            $offset++;
        }
        return -1;
    }

    static function get_wordpress_size( $size ) {
        $wordpress_sizes = Intense_Photo_Source::get_wordpress_photo_sizes();
        $wordpress_size = ( isset( $wordpress_sizes[ $size ] ) ? $wordpress_sizes[ $size ] : $wordpress_sizes[ 'large' ] );

        return $wordpress_size;
    }

    function get_full_size() {
        $wordpress_sizes = Intense_Photo_Source::get_wordpress_photo_sizes();
        $wordpress_full_size = $wordpress_sizes[ $this->full_size ];

        return $wordpress_full_size;
    }

    function get_cache_key( $pagesize, $page ) {
        // echo '<pre>'; echo(
        //     "source: " . ( isset( $this->source ) ? $this->source : '' ).
        //     " attachments: " . ( isset( $this->wordpress_attachements ) ? json_encode( array_keys( $this->wordpress_attachements ) ) : '' ).
        //     " userid: " . ( isset( $this->userid ) ? $this->userid : '' ).
        //     " groupid: " . ( isset( $this->groupid ) ? $this->groupid : '' ).
        //     " setid: " . ( isset( $this->setid ) ? $this->setid : '' ).
        //     " additionalid: " . ( isset( $this->additionalid ) ? $this->additionalid : '' ).
        //     " fullsize: " . ( isset( $this->full_size ) ? $this->full_size : '' ).
        //     " pagesize: " . ( isset( $pagesize ) ? $pagesize : '' ).
        //     " page: " . ( isset( $page ) ? $page : '' ) ); echo '</pre>';

        return hash( 'sha1',
            ( isset( $this->source ) ? $this->source : '' ).
            ( isset( $this->wordpress_attachements ) ? json_encode( array_keys( $this->wordpress_attachements ) ) : '' ).
            ( isset( $this->userid ) ? $this->userid : '' ).
            ( isset( $this->groupid ) ? $this->groupid : '' ).
            ( isset( $this->setid ) ? $this->setid : '' ).
            ( isset( $this->additionalid ) ? $this->additionalid : '' ).
            ( isset( $this->full_size ) ? $this->full_size : '' ).
            ( isset( $pagesize ) ? $pagesize : '' ).
            ( isset( $page ) ? $page : '' ) );
    }

    function get_cache( $pagesize, $page ) {
        $photos = null;
        $key = $this->get_cache_key( $pagesize, $page );
        $uploads = wp_upload_dir();

        $intense_cache_dir = trailingslashit( $uploads['basedir'] . '/intense-cache/photosource/' );

        if ( !is_dir( $intense_cache_dir ) ) {
            mkdir( $intense_cache_dir, 0777, true );
        }

        $cache_file = $intense_cache_dir . $key . '.cache';
        $exists = file_exists( $cache_file );

        if ( $exists && ( filemtime( $cache_file ) > ( time() - 60 * 30 ) ) ) {            
            $raw_photos = file_get_contents( $cache_file );
            $photos = unserialize( $raw_photos );
        } else if ( $exists ) {
            try {
                unlink( $cache_file );
            } catch (Exception $e) {

            }
        }

        return $photos;
    }

    function set_cache( $photos, $pagesize, $page ) {
        $key = $this->get_cache_key( $pagesize, $page );
        $raw_photos = serialize( $photos );
        $uploads = wp_upload_dir();

        $intense_cache_dir = trailingslashit( $uploads['basedir'] . '/intense-cache/photosource/' );

        if ( !is_dir( $intense_cache_dir ) ) {
            mkdir( $intense_cache_dir, 0777, true );
        }

        $cache_file = $intense_cache_dir . $key . '.cache';

        if ( !file_exists( $intense_cache_dir ) ) {
            mkdir( $intense_cache_dir, 0777, true );
        }

        file_put_contents( $cache_file, $raw_photos );
    }

    function get_photos( $pagesize, $page ) {
        $photos = $this->get_cache( $pagesize, $page );

        if ( !isset( $photos ) ) {

            switch ( $this->source ) {
            case 'flickr':
                require_once INTENSE_PLUGIN_FOLDER . '/inc/photosource/Intense-flickr.php';

                $flickr = new Intense_Flickr();
                $photos = $flickr->get_photos( $this->userid, $this->setid, $this->groupid, $page, $pagesize );
                break;
            case 'smugmug':
                require_once INTENSE_PLUGIN_FOLDER . '/inc/photosource/Intense-smugmug.php';

                $smugmug = new Intense_SmugMug();
                $photos = $smugmug->get_photos( $this->userid, $this->setid, $page, $pagesize );
                break;
            case 'zenfolio':
                require_once INTENSE_PLUGIN_FOLDER . '/inc/photosource/Intense-zenfolio.php';

                $zenfolio = new Intense_Zenfolio();
                $photos = $zenfolio->get_photos( $this->setid, $page, $pagesize );
                break;
            case 'instagram':
                require_once INTENSE_PLUGIN_FOLDER . '/inc/photosource/Intense-instagram.php';

                $instagram = new Intense_Instagram();
                $photos = $instagram->get_photos( $this->userid, $this->groupid, $page, $pagesize );
                break;
            case 'deviantart':
                require_once INTENSE_PLUGIN_FOLDER . '/inc/photosource/Intense-deviantart.php';

                $deviantART = new Intense_DeviantArt();
                $photos = $deviantART->get_photos( $this->userid, $page, $pagesize );
                break;
            case 'facebook':
                require_once INTENSE_PLUGIN_FOLDER . '/inc/photosource/Intense-facebook.php';

                $facebook = new Intense_Facebook();
                $photos = $facebook->get_photos( $this->userid, $this->additionalid, $this->groupid, $this->setid, $page, $pagesize );
                break;
            case "500px":
                require_once INTENSE_PLUGIN_FOLDER . '/inc/photosource/Intense-500px.php';

                $px500 = new Intense_500px();
                $photos = $px500->get_photos( $this->userid, $page );
                break;
            case "picasa":
            case "google+":
                require_once INTENSE_PLUGIN_FOLDER . '/inc/photosource/Intense-picasa.php';

                $picasa = new Intense_Picasa();
                $photos = $picasa->get_photos( $this->userid, $this->setid, $page, $pagesize ); //groupid = album, setid = tag
                break;
            default:
                require_once INTENSE_PLUGIN_FOLDER . '/inc/photosource/Intense-wordpress.php';

                $wordpress_sizes = $this->get_wordpress_photo_sizes();
                $wordpress = new Intense_WordPress();
                $photos = $wordpress->get_photos( $this->wordpress_attachements, $wordpress_sizes );
                break;
            }

            $this->set_cache( $photos, $pagesize, $page );
        }

        return $photos;
    }
}
