<?php
/* wppa-picture.php
* Package: wp-photo-album-plus
*
* Make the picture html
* Version 8.0.03.004
*
*/


// This function creates the html for the picture. May be photo, video, audio or photo with audio.
// The size will always be set to 100% width, so the calling wrapper div should take care of sizing.
// This function can be used for both resposive and static displays.
//
// Minimum requirements for input args:
//
// - id, The photo id ( numeric photo db table id )
// - type, Any one of the supported display types: sphoto, mphoto, xphoto, ( to be extended )
//
// Optional args:
//
// - class: Any css class specification.
//
// Returns: The html, or false on error.
// In case of error a red debug message will be printed directly to the output stream.
//
// Additional action: viewcount is bumped by this function if the displayed image is not a thumbnail sized one.
//
function wppa_get_picture_html( $args ) {

	// Init
	$defaults 	= array( 	'id' 		=> '0',
							'type' 		=> '',
							'class' 	=> '',
							'width' 	=> false,
							'height' 	=> false,
						);
	$args 		= wp_parse_args( $args, $defaults );

	$id 		= strval( intval ( $args['id'] ) );
	$type 		= $args['type'];
	$class 		= $args['class'];
	$mocc 		= wppa( 'mocc' );

	if ( wppa_is_pdf( $id ) ) {
		$class = trim( $class . ' smxpdf-' . $mocc );
		$is_pdf = true;
	}
	else {
		$is_pdf = false;
	}

	// Check existance of required args
	foreach( array( 'id', 'type' ) as $item ) {
		if ( ! $args[$item] ) {
			wppa_dbg_msg( 'Missing ' . $item . ' in call to wppa_get_picture_html()', 'red' );
			return false;
		}
	}

	// Check validity of args
	if ( ! wppa_photo_exists( $id ) ) {
		wppa_dbg_msg( 'Photo ' . $id . ' does not exist in call to wppa_get_picture_html(). Type = ' . $type, 'red', 'force' );
		return false;
	}

	$types = array(	'sphoto', 		// Single image with optional border like slideshow border
					'mphoto',		// Media type like single image. Caption should be provided in wrappping div
					'xphoto',		// Like xphoto with extended features
					'cover', 		// Album cover image
					'thumb',		// Normal tumbnail
					'ttthumb',		// Topten
					'comthumb',		// Comment widget
					'fthumb',		// Filmthumb
					'twthumb',		// Thumbnail widget
					'ltthumb',		// Lasten widget
					'albthumb',		// Album widget
					);

	if ( ! in_array( $type, $types ) ) {
		wppa_dbg_msg( 'Unimplemented type ' . $type . ' in call to wppa_get_picture_html()', 'red', 'force' );
		return false;
	}

	// Get other data
	$link 		= wppa_get_imglnk_a( $type, $id );
	$isthumb 	= strpos( $type, 'thumb' ) !== false;
	if ( $isthumb ) {
		$file = wppa_get_thumb_path( $id );
	}
	elseif ( wppa_is_zoomable( $id ) ) {
		$file = wppa_get_o1_source_path( $id );
		if ( ! wppa_is_file( $file ) ) {
			$file = wppa_get_source_path( $id );
			if ( ! wppa_is_file( $file ) ) {
				$file = wppa_get_photo_path( $id );
			}
		}
	}
	else {
		$file = wppa_get_photo_path( $id );
	}

	if ( $args['width'] && $args['height'] ) {
		$href 	= $isthumb ? wppa_get_thumb_url( $id, true, '', $args['width'], $args['height'] ) :
		wppa_get_photo_url( $id, true, '', $args['width'], $args['height'] );
	}
	else {
		$href 	= $isthumb ? wppa_get_thumb_url( $id ) : wppa_get_photo_url( $id );
	}
	if ( $is_pdf || ( wppa_is_zoomable( $id ) && ! $isthumb ) ) {
		$href = wppa_get_hires_url( $id );
	}

	$autocol 	= wppa( 'auto_colwidth' ) || ( wppa( 'fullsize' ) > 0 && wppa( 'fullsize' ) <= 1.0 );
	$title 		= $link ? esc_attr( $link['title'] ) : esc_attr( stripslashes( wppa_get_photo_name( $id ) ) );
	$alt 		= wppa_get_imgalt( $id );

	// Find image style
	switch ( $type ) {
		case 'sphoto':
			$style = 'width:100%;margin:0;';
			if ( ! wppa_in_widget() ) {
				switch ( wppa_opt( 'fullimage_border_width' ) ) {
					case '':
						$style .= 	'padding:0;' .
									'border:none;';
						break;
					case '0':
						$style .= 	'padding:0;' .
									'border:1px solid ' . wppa_opt( 'bcolor_fullimg' ) . ';' .
									'box-sizing:border-box;';
						break;
					default:
						$style .= 	'padding:' . ( wppa_opt( 'fullimage_border_width' ) - '1' ) . 'px;' .
									'border:1px solid ' . wppa_opt( 'bcolor_fullimg' ) . ';' .
									'box-sizing:border-box;' .
									'background-color:' . wppa_opt( 'bgcolor_fullimg' ) . ';';

						// If we do round corners...
						if ( wppa_opt( 'bradius' ) > '0' ) {

							// then also here
							$style .= 'border-radius:' . wppa_opt( 'fullimage_border_width' ) . 'px;';
						}
				}
			}
			break;
		case 'mphoto':
		case 'xphoto':
			$style = 'width:100%;margin:0;padding:0;border:none;';
			break;
		default:
			wppa_dbg_msg( 'Style for type ' . $type . ' is not implemented yet in wppa_get_picture_html()', 'red', 'force' );
			return false;
	}

	if ( wppa_has_audio( $id ) ) {
		$style .= 'min-height:' . wppa_get_audio_control_height() . 'px;';
	}

	if ( $link && $link['is_lightbox'] ) {
		$title = wppa_zoom_in( $id );
	}

	// Create the html. To prevent mis-alignment of the audio control bar or to escape from the <a> tag for the pan controlbar
	// we wrap it in a div with zero fontsize and lineheight.
	$result = '<div style="font-size:0;line-height:0;" >';

	if ( $is_pdf && $mocc ) {
		$result .= wppa_js( 'wppaAutoColumnWidth[' . $mocc . '] = true;wppaAutoColumnFrac[' . $mocc . ']=1;wppaTopMoc=Math.max(wppaTopMoc,' . $mocc . ');' );
	}

	// The link
	if ( $link ) {

		// Link is lightbox
		if ( $link['is_lightbox'] ) {
			$lbtitle 	= wppa_get_lbtitle( $type, $id );
			$videobody 	= esc_attr( wppa_get_video_body( $id ) );
			$audiobody 	= esc_attr( wppa_get_audio_body( $id ) );
			$videox 	= wppa_get_videox( $id );
			$videoy 	= wppa_get_videoy( $id );

			if ( $type == 'photo' || $type == 'mphoto' || $type == 'xphoto' ) {
				$setname = '['.$type.']';
			}
			else {
				$setname = '';
			}

			$result .=
			'<a' .
				' data-id="' . wppa_encrypt_photo( $id ) . '"' .
				' href="' . $link['url'] . '"' .
				( $lbtitle ? ' ' . 'data-lbtitle' . '="'.esc_attr($lbtitle).'"' : '' ) .
				( wppa_is_zoomable( $id ) ? ' data-pantype="zoom"' : '' ) .
				( $videobody ? ' data-videohtml="' . $videobody . '"' : '' ) .
				( $audiobody ? ' data-audiohtml="' . $audiobody . '"' : '' ) .
				( $is_pdf ? ' data-pdfhtml="' . esc_attr( wppa_get_pdf_html( $id ) ) .'"' : '' ) .
				( $videox ? ' data-videonatwidth="' . $videox . '"' : '' ) .
				( $videoy ? ' data-videonatheight="' . $videoy . '"' : '' ) .
				' data-rel="wppa'.$setname.'"' .
				wppa_get_lb_panorama_full_html( $id ) .
				( $link['target'] ? ' target="' . $link['target'] . '"' : '' ) .
				' class="thumb-img"' .
				' id="a-' . $id . '-' . $mocc . '"' .
				' data-alt="' . esc_attr( wppa_get_imgalt( $id, true ) ) . '"' .
				' style="cursor:' . wppa_wait() . ';"' .
				' onclick="return false;"' .
			' >';
		}

		// Link is NOT lightbox
		else {
			$result .= '
			<a
				ontouchstart="wppaStartTime();"
				ontouchend="wppaTapLink(\'' . $id . '\',\'' . $link['url'] . '\');"
				onclick="_bumpClickCount( \'' . $id . '\' );window.open(\'' . $link['url'] . '\', \'' . $link['target'] . '\' )"
				title="' . $link['title'] . '"
				class="thumb-img"
				id="a-' . $id . '-' . $mocc . '"
				style="cursor:pointer;"
			>';
		}
	}

	// The image
	// Panorama? Only if browser supports html5
	if ( wppa_is_panorama( $id ) && wppa_browser_can_html5() ) {
		$result .= wppa_get_panorama_html( array( 	'id' 		=> $id,
													'width' 	=> $args['width'],
													'height'	=> $args['height'],
													'haslink' 	=> $link,
												)
										);
	}

	// Video?
	elseif ( wppa_is_video( $id ) ) {
		$result .=
		wppa_get_video_html( array( 'id' 		=> $id,
									'controls' 	=> ! $link,
									'style' 	=> $style,
									'class' 	=> $class,
									)
							);
	}

	// Pdf?
	elseif ( $is_pdf ) {
		$result .= '
		<iframe
			id="pdf-' . $id . '-' . $mocc . '"
			src="' . $href . '" ' .
			wppa_get_imgalt( $id ) .
			( $class ? ' class="' . $class . '" ' : '' ) .
			( $title ? ' title="' . $title . '" ' : '' ) . '
			style="' . $style . '"
		>
		</iframe>';
	}

	// No video, just a photo
	else {

		// Zoom?
		if ( wppa_is_zoomable( $id ) ) {

			$result .=
			wppa_get_zoom_pan_html( array(
				'mocc' 				=> $mocc,
				'id' 				=> $id,
				'controls' 			=> ( wppa_opt( 'panorama_control' ) == 'all' ) || ( wppa_opt( 'panorama_control' ) == 'mobile' && wppa_is_mobile() ),
				'manual' 			=> true,
				'zoomsensitivity' 	=> wppa_opt( 'panorama_wheel_sensitivity' ),

			) );
		}
		else {
			$imgid = 'ph-'.$id.'-'.$mocc;

			$result .=
			'<img' .
				' id="' . $imgid . '"' .
				' ' . ( wppa_lazy() ? 'data-' : '' ) . 'src="' . $href . '"' .
				' ' . wppa_get_imgalt( $id ) .
				( $class ? ' class="' . $class . '" ' : '' ) .
				( $title ? ' title="' . $title . '" ' : '' ) .
				' style="' . $style . '"' .
				' alt="' . $id . '"' .
			' />';
		}
	}

	// Close the link
	if ( $link ) {
		$result .= '</a>';
	}

	// Add audio?			sphoto
	if ( wppa_has_audio( $id ) ) {

		$result .= '<div style="position:relative;z-index:11;" >';

		// Find style for audio controls
		switch ( $type ) {
			case 'sphoto':
				$pad = ( wppa_opt( 'fullimage_border_width' ) === '' ) ? 0 : wppa_opt( 'fullimage_border_width' );
				$bot = ( wppa_opt( 'fullimage_border_width' ) === '' ) ? 0 : wppa_opt( 'fullimage_border_width' );
				$style = 	'margin:0;' .
							'padding:0 ' . $pad . 'px;' .
							'bottom:' . $bot .'px;';
				$class = 	'size-medium wppa-sphoto wppa-sphoto-' . wppa( 'mocc' );
				break;
			case 'mphoto':
			case 'xphoto':
				$style = 	'margin:0;' .
							'padding:0;' .
							'bottom:0;' .
							'left:0;';
				$class = 	'size-medium wppa-' . $type . ' wppa-' . $type . '-' . wppa( 'mocc' );
				break;
			default:
				$style = 	'margin:0;' .
							'padding:0;';
				$class = 	'';
		}

		// Get the html for audio
		$result .= wppa_get_audio_html( array(	'id' 		=> 	$id,
												'cursor' 	=> 	'cursor:pointer;',
												'style' 	=> 	$style .
												'position:absolute;' .
												'box-sizing:border-box;' .
												'width:100%;' .
												'border:none;' .
												'height:' . wppa_get_audio_control_height() . 'px;' .
												'border-radius:0px;',
												'class' 	=> 	$class,
											)
									);
		$result .= '</div>';
	}

	$result .= '</div>';

	// Update statistics
	if ( ! wppa_in_widget() ) {
		wppa_bump_viewcount( 'photo', $id );
	}

	// Done !
	return $result;
}

// Get full html for a lightbox pan image, e.g. ' data-panorama="'..."' for use in lightbox anchor link
function wppa_get_lb_panorama_full_html( $id ) {

	$html = wppa_get_lb_panorama_html( $id );
	if ( $html ) {
		$result = ' data-panorama="' . esc_attr( $html ) . '"';

		switch ( wppa_get_photo_item( $id, 'panorama' ) ) {
			case '0': // none
				if ( wppa_is_zoomable( $id ) ) {
					$result .= ' data-pantype="zoom"';
				}
				break;
			case '1': // spheric
				$result .= ' data-pantype="spheric"';
				break;
			case '2': // flat
				$result .= ' data-pantype="flat"';
				break;
			default:
				break;
		}

		return $result;
	}
	else {
		return '';
	}
}

// Get the html for a lightbox pan image
function wppa_get_lb_panorama_html( $id ) {

	return wppa_get_panorama_html( array( 'id' => $id, 'lightbox' 	=> true, ) );
}

// Get the html for a pan image
function wppa_get_panorama_html( $args ) {

	// If no id given, quit
	if ( ! isset( $args['id'] ) ) return;

	$args['controls'] = ( wppa_opt( 'panorama_control' ) == 'all' ) || ( wppa_opt( 'panorama_control' ) == 'mobile' && wppa_is_mobile() );
	$args['manual'] = wppa_opt( 'panorama_manual' ) == 'all' ? true : false;
	$args['autorun'] = wppa_opt( 'panorama_autorun' ) == 'none' ? '' : wppa_opt( 'panorama_autorun' );
	$args['autorunspeed'] = wppa_opt( 'panorama_autorun_speed' );
	$args['zoomsensitivity'] = wppa_opt( 'panorama_wheel_sensitivity' );

	if ( wppa_is_zoomable( $args['id'] ) ) {
		$result = wppa_get_zoom_pan_html( $args );
	}

	else {
		switch( wppa_is_panorama( $args['id'] ) ) {

			case '1':
				$result = wppa_get_spheric_pan_html( $args );

				// Save we have a spheric panorama on board for loading THREE.js
				wppa( 'has_panorama', true );
				break;
			case '2':
				$result = wppa_get_flat_pan_html( $args );
				break;
			default:
				$result = '';
		}
	}

	return $result;
}

// Spheric 360deg pan
function wppa_get_spheric_pan_html( $args ) {

	// Init
	$defaults 	= array( 	'id' 				=> '0',
							'mocc' 				=> '0',
							'width' 			=> false,
							'height' 			=> false,
							'haslink' 			=> false,
							'lightbox' 			=> 0,
							'controls' 			=> true,
							'autorun' 			=> '',
							'manual' 			=> true,
							'autorunspeed' 		=> '3',
							'zoomsensitivity' 	=> '3',
						);

	$args 				= wp_parse_args( $args, $defaults );
	$id 				= strval( intval ( $args['id'] ) );

	if ( wppa_is_mobile() ) {
		$url = esc_url( wppa_get_photo_url( $id ) );
		$ratio = wppa_get_photox( $id ) / wppa_get_photoy( $id );
	}
	else {
		$url = esc_url( wppa_get_hires_url( $id ) );
		$ratio = wppa_get_source_ratio( $id );
	}
	if ( ! $ratio ) $ratio = 2;

	$mocc 				= $args['mocc'] ? $args['mocc'] : wppa( 'mocc' );
	$width 				= $args['width'] ? $args['width'] : wppa_get_container_width();
	$height 			= $width / 2; // $args['height'] ? $args['height'] : round( $width / $ratio );
	$haslink 			= $args['haslink'];
	$lightbox 			= $args['lightbox'];
	$icsiz 				= ( $lightbox ? wppa_opt( 'nav_icon_size_lightbox' ) : wppa_opt( 'nav_icon_size_panorama' ) );
	$iconsize 			= $icsiz . 'px;';
	$controls 			= $args['controls'];
	$autorun 			= $args['autorun'];
	$manual 			= $args['manual'];
	$autorunspeed 		= $args['autorunspeed'];
	$zoomsensitivity 	= $args['zoomsensitivity'];

	$result = '';

	if ( $lightbox ) {
		$result .= $id . '.';
	}
	if ( $haslink ) {
		$result .= '</a>';
	}
	if ( $lightbox ) {
		$result .= '<div id="wppa-ovl-sphericpan-container" >';
	}
	if ( $lightbox ) {
		$mocc = '0';
	}

	$result .=
		'<div
			id="wppa-pan-div-' . $mocc . '"
			class="wppa-pan-div wppa-pan-div-' . $mocc . '"
			style="' . ( $controls ? 'margin-bottom:4px;' : '' ) . ( $manual ? 'cursor:grab;': '' ) . 'line-height:0;"
			>
		</div>';

	if ( $controls ) {
		$result .=
		'<div
			id="wppa-pctl-div-' . $mocc . '"
			class="wppa-pctl-div wppa-pctl-div-' . $mocc . ' ' . ( $lightbox ? 'wppa-pctl-div-lb' : '' ) . '"
			style="text-align:center;' . ( $lightbox ? 'visibility:hidden;' : '' ) . '"
			onclick="return false;"
			>';
			if ( $lightbox ) {
				$result .=
				'<span
					id="wppa-pctl-prev-' . $mocc . '"
					class="wppa-pan-prevnext"
					style="margin:0 2px 0 0;float:left;display:inline-block;"
					onclick="wppaOvlShowPrev()"
					>' .
					wppa_get_svghtml( 'Prev-Button', $iconsize, $lightbox ) .
				'</span>
				<span
					id="wppa-ovl-start-btn"
					style="margin:0 2px;float:left;display:none;"
					title="' . esc_attr( __( 'Start', 'wp-photo-album-plus' ) ) . '"
					onclick="wppaOvlStartStop()"
					>' .
					wppa_get_svghtml( 'Play-Button', $iconsize, $lightbox ) .
				'</span>
				<span
					id="wppa-ovl-stop-btn"
					style="margin:0 2px;float:left;display:none;"
					title="' . esc_attr( __( 'Stop', 'wp-photo-album-plus' ) ) . '"
					onclick="wppaOvlStartStop()"
					>' .
					wppa_get_svghtml( 'Pause-Button', $iconsize, $lightbox ) .
				'</span>';
			}

			$result .=
			'<span
				id="wppa-pctl-left-' . $mocc . '"
				style="margin:0 2px;display:inline-block;"
				>' .
				wppa_get_svghtml( 'Left-4', $iconsize, $lightbox ) .
			'</span>
			<span
				id="wppa-pctl-right-' . $mocc . '"
				style="margin:0 2px;display:inline-block;"
				>' .
				wppa_get_svghtml( 'Right-4', $iconsize, $lightbox ) .
			'</span>
			<span
				id="wppa-pctl-up-' . $mocc . '"
				style="margin:0 2px;display:inline-block;"
				>' .
			wppa_get_svghtml( 'Up-4', $iconsize, $lightbox ) .
			'</span>
			<span
				id="wppa-pctl-down-' . $mocc . '"
				style="margin:0 2px;display:inline-block;"
				>' .
				wppa_get_svghtml( 'Down-4', $iconsize, $lightbox ) .
			'</span>
			<span
				id="wppa-pctl-zoomin-' . $mocc . '"
				style="margin:0 2px;display:inline-block;"
				>' .
				wppa_get_svghtml( 'ZoomIn', $iconsize, $lightbox ) .
			'</span>
			<span
				id="wppa-pctl-zoomout-' . $mocc . '"
				style="margin:0 2px;display:inline-block;"
				>' .
				wppa_get_svghtml( 'ZoomOut', $iconsize, $lightbox ) .
			'</span>';

			// If lightbox: next button and fullscreen buttons
			if ( $lightbox ) {
				$result .=
				'<span
					id="wppa-pctl-next-' . $mocc . '"
					class="wppa-pan-prevnext"
					style="margin:0 0 0 2px;float:right;display:inline-block;"
					title="' . esc_attr( __( 'Next image', 'wp-photo-album-plus' ) ) . '"
					onclick="wppaOvlShowNext()"
					>' .
					wppa_get_svghtml( 'Next-Button', $iconsize, $lightbox ) .
				'</span>' .
				'<span
					id="wppa-exit-btn-2"
					class=""
					style="margin:0 2px;float:right;display:inline-block;"
					title="' . esc_attr( __( 'Exit', 'wp-photo-album-plus' ) ) . '"
					onclick="wppaOvlHide()"
					>' .
					wppa_get_svghtml( 'Exit-2', $iconsize, $lightbox ) .
				'</span>';

				// Fs buttons
				if ( wppa_opt( 'fs_policy' ) == 'lightbox' && ! wppa_is_ipad() && ! wppa_is_safari() ) {
					$result .=
					'<span
						id="wppa-fulls-btn-2"
						class="wppa-fulls-btn"
						style="margin:0 2px;float:right;display:none;"
						title="' . esc_attr( __( 'Enter fullscreen', 'wp-photo-album-plus' ) ) . '"
						onclick="wppaFsOn()"
						>' .
						wppa_get_svghtml( 'Full-Screen-2', $iconsize, $lightbox ) .
					'</span>' .
					'<span
						id="wppa-exit-fulls-btn-2"
						class="wppa-exit-fulls-btn"
						style="margin:0 2px;float:right;display:none;"
						title="' . esc_attr( __( 'Leave fullscreen', 'wp-photo-album-plus' ) ) . '"
						onclick="wppaFsOff()"
						>' .
						wppa_get_svghtml( 'Exit-Full-Screen-2', $iconsize, $lightbox ) .
					'</span>';
				}
			}

		$result .=
		'</div>';
	}

	if ( $lightbox ) {
		$result .= '</div>';
	}

	if ( $autorun == 'right' ) {
		$dX = 0.05 * $autorunspeed / 3;
		$run = 'true';
	}
	elseif ( $autorun == 'left' ) {
		$dX = -0.05 * $autorunspeed / 3;
		$run = 'true';
	}
	else {
		$dX = 0;
		$run = 'false';
	}

	$result .=

	'<script>
		var data' . $mocc . ' =
			{	mocc				:' . $mocc . ',
				id					:' . $id . ',
				uId 				:0,
				isLightbox			:' . ( $lightbox ? 'true' : 'false' ) . ',
				height				:' . $height . ',
				width				:' . $width . ',
				url 				:"' . $url . '",
				abort 				:false,
				autorun 			:' . $run . ',
				dX 					:' . $dX . ',
				dY 					:0,
				fov 				:' . wppa_opt( 'panorama_fov' ) . ',
				zoomsensitivity		:' . $zoomsensitivity . ',
				borderWidth			:' . wppa_opt( 'ovl_border_width' ) . ',
				controls			:' . ( $controls ? 'true' : 'false' ) . ',
				initialized			:false,
				icsize				:' . ( $lightbox ? wppa_opt( 'nav_icon_size_lightbox' ) : wppa_opt( 'nav_icon_size_panorama' ) ) . ',
				backgroundColor		:"' . wppa_opt( 'ovl_theme' ) . '",
				borderRadius		:' . wppa_opt( 'ovl_border_radius' ) . ',
				padding				:' . wppa_opt( 'ovl_border_width' ) . ',
				enableManual 		:' . ( $manual ? 'true' : 'false' ) . ',
				vtime 				:0,
			};
		jQuery(document).ready(function(){wppaDoSphericPan(' . $mocc . ', data' . $mocc . ')});' .

	'</script>' .

	( $haslink ? '<a>' : '' ) . '';

	$result = wppa_pan_min( $result );

	return $result;
}

// Non 360 flat pan
function wppa_get_flat_pan_html( $args ) {

	// Init
	$defaults 	= array( 	'id' 				=> '0',
							'mocc' 				=> '0',
							'width' 			=> false,
							'height' 			=> false,
							'haslink' 			=> false,
							'lightbox' 			=> 0,
							'controls' 			=> true,
							'autorun' 			=> '',
							'manual' 			=> true,
							'autorunspeed' 		=> '3',
							'zoomsensitivity' 	=> '3',
							);

	$args 				= wp_parse_args( $args, $defaults );

	$id 				= strval( intval ( $args['id'] ) );
	$mocc 				= $args['mocc'] ? $args['mocc'] : wppa( 'mocc' );
	$width 				= $args['width'] ? $args['width'] : wppa_get_container_width();
	$height 			= $args['height'] ? $args['height'] : round( $width * wppa_get_photoy( $id ) / wppa_get_photox( $id ) );
	$haslink 			= $args['haslink'];
	$lightbox 			= $args['lightbox'];
	if ( $lightbox ) $mocc = '0';
	$icsiz 				= ( $lightbox ? wppa_opt( 'nav_icon_size_lightbox' ) : wppa_opt( 'nav_icon_size_panorama' ) );
	$iconsize 			= $icsiz . 'px;';
	$controls 			= $args['controls'];
	$autorun 			= $args['autorun'];
	$manual 			= $args['manual'];
	$autorunspeed 		= $args['autorunspeed'];
	$zoomsensitivity 	= $args['zoomsensitivity'];

	switch ( $autorun ) {
		case 'right':
			 $deltaX = $autorunspeed / 3;
			 break;
		case 'left':
			 $deltaX = - $autorunspeed / 3;
			 break;
		default:
			 $deltaX = '0';
	}

	$url 	= esc_url( wppa_is_mobile() ? wppa_get_photo_url( $id ) : wppa_get_hires_url( $id ) );

	$result = '';

	if ( $lightbox ) {
		$result .= $id . '.';
	}

	if ( $haslink ) {
		$result .= '</a>';
	}

	// The overall container
	if ( $lightbox ) {
		$result .= '<div id="wppa-ovl-flatpan-container" >';
	}

	// The canvas container
	$result .=
	'<div
		id="wppa-pan-div-' . $mocc . '"
		class="wppa-pan-div wppa-pan-div-' . $mocc . '"
		style="' . ( $controls ? 'margin-bottom:4px;' : '' ) . 'line-height:0;"
		>' .

		// The actual drawing area
		'<canvas
			id="wppa-pan-canvas-' . $mocc . '"
			style="background-color:black;' . ( $manual ? 'cursor:grab;' : '' ) . '"
			width="' . $width . '"
			height="' . ( $width / 2 ) . '"' .
			( $lightbox ? '
				ontouchstart="wppaTouchStart( event, \'wppa-pan-canvas-' . $mocc . '\', -1 );"
				ontouchend="wppaTouchEnd( event );"
				ontouchmove="wppaTouchMove( event );"
				ontouchcancel="wppaTouchCancel( event );"' : ''
			) . '
			>
		</canvas>' .

		// The preview image
		'<canvas
			id="wppa-pan-prev-canvas-' . $mocc . '"
			style="margin-top:4px;background-color:black;"
			width="' . $width . '"
			height="' . $height . '"
			>
		</canvas>
	</div>';

	// The controlbar
	if ( $controls ) {
		$result .=
		'<div
			id="wppa-pctl-div-' . $mocc . '"
			class="wppa-pctl-div wppa-pctl-div-' . $mocc . ' ' . ( $lightbox ? 'wppa-pctl-div-lb' : '' ) . '"
			style="text-align:center;' . ( $lightbox ? 'visibility:hidden;' : '' ) . '"
			onclick="return false;"
			>';

		// If lightbox: prev button
		if ( $lightbox ) {
			$result .=
			'<span
				id="wppa-pctl-prev-' . $mocc . '"
				class="wppa-pan-prevnext"
				style="margin:0 2px 0 0;float:left;display:inline-block;"
				onclick="wppaOvlShowPrev()"
				>' .
				wppa_get_svghtml( 'Prev-Button', $iconsize, $lightbox ) .
			'</span>
			<span
				id="wppa-ovl-start-btn"
				style="margin:0 2px;float:left;display:none;"
				title="' . esc_attr( __( 'Start', 'wp-photo-album-plus' ) ) . '"
				onclick="wppaOvlStartStop()"
				>' .
				wppa_get_svghtml( 'Play-Button', $iconsize, $lightbox ) .
			'</span>
			<span
				id="wppa-ovl-stop-btn"
				style="margin:0 2px;float:left;display:none;"
				title="' . esc_attr( __( 'Stop', 'wp-photo-album-plus' ) ) . '"
				onclick="wppaOvlStartStop()"
				>' .
				wppa_get_svghtml( 'Pause-Button', $iconsize, $lightbox ) .
			'</span>';
		}

		// The nav buttons
		$result .=
		'<span
			id="wppa-pctl-left-' . $mocc . '"
			style="margin:0 2px;display:inline-block;"
			>' .
			wppa_get_svghtml( 'Left-4', $iconsize, $lightbox ) .
		'</span>
		<span
			id="wppa-pctl-right-' . $mocc . '"
			style="margin:0 2px;display:inline-block;"
			>' .
			wppa_get_svghtml( 'Right-4', $iconsize, $lightbox ) .
		'</span>
		<span
			id="wppa-pctl-up-' . $mocc . '"
			style="margin:0 2px;display:inline-block;"
			>' .
			wppa_get_svghtml( 'Up-4', $iconsize, $lightbox ) .
		'</span>
		<span
			id="wppa-pctl-down-' . $mocc . '"
			style="margin:0 2px;display:inline-block;"
			>' .
			wppa_get_svghtml( 'Down-4', $iconsize, $lightbox ) .
		'</span>
		<span
			id="wppa-pctl-zoomin-' . $mocc . '"
			style="margin:0 2px;display:inline-block;"
			>' .
			wppa_get_svghtml( 'ZoomIn', $iconsize, $lightbox ) .
		'</span>
		<span
			id="wppa-pctl-zoomout-' . $mocc . '"
			style="margin:0 2px;display:inline-block;"
			>' .
			wppa_get_svghtml( 'ZoomOut', $iconsize, $lightbox ) .
		'</span>';

		// If lightbox: next button
		if ( $lightbox ) {
			$result .=
			'<span
				id="wppa-pctl-next-' . $mocc . '"
				class="wppa-pan-prevnext"
				style="margin:0 0 0 2px;float:right;display:inline-block;"
				onclick="wppaOvlShowNext()"
				>' .
				wppa_get_svghtml( 'Next-Button', $iconsize, $lightbox ) .
			'</span>
			<span
				id="wppa-exit-btn-2"
				class=""
				style="margin:0 2px;float:right;display:inline-block;"
				title="' . esc_attr( __( 'Exit', 'wp-photo-album-plus' ) ) . '"
				onclick="wppaOvlHide()"
				>' .
				wppa_get_svghtml( 'Exit-2', $iconsize, $lightbox ) .
			'</span>';

			// Fs buttons
			if ( wppa_opt( 'fs_policy' ) == 'lightbox' && ! wppa_is_ipad() && ! wppa_is_safari() ) {
				$result .=
				'<span
					id="wppa-fulls-btn-2"
					class="wppa-fulls-btn"
					style="margin:0 2px;float:right;display:none;"
					title="' . esc_attr( __( 'Enter fullscreen', 'wp-photo-album-plus' ) ) . '"
					onclick="wppaFsOn()"
					>' .
					wppa_get_svghtml( 'Full-Screen-2', $iconsize, $lightbox ) .
				'</span>' .
				'<span
					id="wppa-exit-fulls-btn-2"
					class="wppa-exit-fulls-btn"
					style="margin:0 2px;float:right;display:none;"
					title="' . esc_attr( __( 'Leave fullscreen', 'wp-photo-album-plus' ) ) . '"
					onclick="wppaFsOff()"
					>' .
					wppa_get_svghtml( 'Exit-Full-Screen-2', $iconsize, $lightbox ) .
				'</span>';
			}
		}

		$result .=
		'</div>';
	}

	// wppa-ovl-flatpan-container
	( $lightbox ? '</div>' : '' );

	// The js part
	$result .=
		'<script>' .

			// Create image object and add the image url to it
			'var image' . $mocc . ' = new Image();
			image' . $mocc . '.src = "' . $url . '";' .
			'var wppaFlatLastRenderTime = [];
			var wppaFlatId = [];' .

			// When document complete, run the main proc
			'jQuery(document).ready(function(){wppaDoFlatPanorama' . $mocc . '("' . $id . '");});' .

			// The main proccedure
			'function wppaDoFlatPanorama' . $mocc . '(id){' .

				// Wait until the image file has been completely loaded
				'if (!image' . $mocc . '.complete){setTimeout( wppaDoFlatPanorama' . $mocc . ', 200 );return;}' .

				'wppaFlatId['.$mocc.'] = id;' .

				// Var declarations
				'var
				$ 				= jQuery,
				mocc 			= ' . $mocc . ',
				manualControl 	= false,
				zoomsensitivity = ' . $zoomsensitivity . ',
				deltaX 			= ' . $deltaX . ',
				deltaY 			= 0,
				deltaFactor 	= 1.0,
				autorun 		= ' . ( $autorun ? 'true' : 'false' ) . ',
				run 			= deltaX ? 5 : 4,
				abort 			= false,
				div 			= $("#wppa-pan-div-' . $mocc . '"),
				canvas 			= document.getElementById("wppa-pan-canvas-' . $mocc . '"),
				prevCanvas 		= document.getElementById("wppa-pan-prev-canvas-' . $mocc . '"),
				left 			= $("#wppa-pctl-left-' . $mocc . '"),
				right 			= $("#wppa-pctl-right-' . $mocc . '"),
				up 				= $("#wppa-pctl-up-' . $mocc . '"),
				down 			= $("#wppa-pctl-down-' . $mocc . '"),
				zoomin 			= $("#wppa-pctl-zoomin-' . $mocc . '"),
				zoomout 		= $("#wppa-pctl-zoomout-' . $mocc . '"),
				prev 			= $("#wppa-pctl-prev-' . $mocc . '"),
				next 			= $("#wppa-pctl-next-' . $mocc . '"),
				canvasWidth 	= $(div).parent().width(),
				canvasHeight 	= canvasWidth / 2,
				savedCanvasX 	= 0,
				savedCanvasY 	= 0,
				fromHeight 		= image' . $mocc . '.height / 2,
				fromWidth 		= fromHeight * 2,
				fromX 			= ( image' . $mocc . '.width - fromWidth ) / 2,
				fromY 			= ( image' . $mocc . '.height - fromHeight ) / 2,
				centerX 		= fromX + fromWidth / 2,
				centerY 		= fromY + fromHeight / 2;' .

				'wppaFlatLastRenderTime[mocc] = 0;' .

				// Install listeners

					'right.off("touchstart");
					right.on("touchstart", onRightMouseDown);
					right.off("touchend");
					right.on("touchend", onButtonUp);
					left.off("touchstart");
					left.on("touchstart", onLeftMouseDown);
					left.off("touchend");
					left.on("touchend", onButtonUp);
					up.off("touchstart");
					up.on("touchstart", onUpMouseDown);
					up.off("touchend");
					up.on("touchend", onButtonUp);
					down.off("touchstart");
					down.on("touchstart", onDownMouseDown);
					down.off("touchend");
					down.on("touchend", onButtonUp);
					zoomin.off("touchstart");
					zoomin.on("touchstart", onZoomInMouseDown);
					zoomin.off("touchend");
					zoomin.on("touchend", onButtonUp);
					zoomout.off("touchstart");
					zoomout.on("touchstart", onZoomOutMouseDown);
					zoomout.off("touchend");
					zoomout.on("touchend", onButtonUp);'
				.
				( $manual ?
					'canvas.removeEventListener("mousedown", onCanvasMouseDown);
					canvas.addEventListener("mousedown", onCanvasMouseDown);
					canvas.removeEventListener("mousemove", onCanvasMouseMove);
					canvas.addEventListener("mousemove", onCanvasMouseMove);
					canvas.removeEventListener("mouseup", onCanvasMouseUp);
					canvas.addEventListener("mouseup", onCanvasMouseUp);
					canvas.addEventListener("mouseout", onCanvasMouseUp);
					canvas.removeEventListener("mouseout", onCanvasMouseUp);
					document.getElementById("wppa-pan-canvas-' . $mocc . '").removeEventListener("wheel", onDivWheel);
					document.getElementById("wppa-pan-canvas-' . $mocc . '").addEventListener("wheel", onDivWheel);
					prevCanvas.removeEventListener("mousedown", onCanvasMouseDown);
					prevCanvas.addEventListener("mousedown", onCanvasMouseDown);
					prevCanvas.removeEventListener("mousemove", onPrevCanvasMouseMove);
					prevCanvas.addEventListener("mousemove", onPrevCanvasMouseMove);
					prevCanvas.removeEventListener("mouseup", onCanvasMouseUp);
					prevCanvas.addEventListener("mouseup", onCanvasMouseUp);
					prevCanvas.removeEventListener("mouseout", onCanvasMouseUp);
					prevCanvas.addEventListener("mouseout", onCanvasMouseUp);'
				: '' ) .

					'right.off("mousedown");
					right.on("mousedown", onRightMouseDown);
					right.off("mouseup");
					right.on("mouseup", onButtonUp);
					left.off("mousedown");
					left.on("mousedown", onLeftMouseDown);
					left.off("mouseup");
					left.on("mouseup", onButtonUp);
					up.off("mousedown");
					up.on("mousedown", onUpMouseDown);
					up.off("mouseup");
					up.on("mouseup", onButtonUp);
					down.off("mousedown");
					down.on("mousedown", onDownMouseDown);
					down.off("mouseup");
					down.on("mouseup", onButtonUp);
					zoomin.off("mousedown");
					zoomin.on("mousedown", onZoomInMouseDown);
					zoomin.off("mouseup");
					zoomin.on("mouseup", onButtonUp);
					zoomout.off("mousedown");
					zoomout.on("mousedown", onZoomOutMouseDown);
					zoomout.off("mouseup");
					zoomout.on("mouseup", onButtonUp);'
				 .

				// Install Resize handler
				'$(window).off("DOMContentLoaded load resize orientationchange",onResize' . $mocc . ');' .
				'$(window).on("DOMContentLoaded load resize orientationchange",onResize' . $mocc . ');' .

				// Lightbox exit handler
				( $lightbox ?
				'$("body").off("quitimage",quitImage);' .
				'$("body").on("quitimage",quitImage);' .
				'$("#wppa-pctl-div-'.$mocc.'").on("click", function(e){wppaKillEvent(e)});' :
				'' ) .

				// Remove spinner
				'$("#wppa-ovl-spin").hide();' .

				// Disable right click
				'wppaProtect();' .

				// Do the rendering
				'render();' .

				// Resize
				'onResize' . $mocc . '();' .

				// The render function
				'function render(){' .

					( $lightbox ? 'if (!wppaOvlOpen) abort=true;' : 'if (!wppaIsElementInViewport(canvas)) {setTimeout(render,200);return;}' ) .

					'if (abort) {
						ctx = null;
						prevctx = null;
						return;
					}
					if (run==0) {
						return;
					}' .

					// Duplicate loops?
					'var curTime = timnow();
					if ( autorun && curTime < wppaFlatLastRenderTime[mocc] + 25 ) {
						return;
					}
					wppaFlatLastRenderTime[mocc] = curTime;' .

					// manualControl is true when a drag on the canvas is being performed
					'if(!manualControl){' .

						// Panning
						'fromX += deltaX;
						fromY += deltaY;' .

						// Zooming
						'var newHeight = fromHeight / deltaFactor;
						var newWidth = fromWidth / deltaFactor;' .

						// Keep zooming in range
						'if ( deltaFactor != 1 && newHeight <= image' . $mocc . '.height && newHeight > 50 ) {
							fromX -= ( newWidth - fromWidth ) / 2;
							fromY -= ( newHeight - fromHeight ) / 2;
							fromWidth = newWidth;
							fromHeight = newHeight;
						}
					}' .

					// Keep viewport within image boundaries
					'fromX = Math.max(0, Math.min(image' . $mocc . '.width-fromWidth, fromX));' .
					'fromY = Math.max(0, Math.min(image' . $mocc . '.height-fromHeight, fromY));' .

					// Check for turningpoint in case autrun
					'if ( autorun ) {
						if ( fromX == 0 || fromX == ( image' . $mocc . '.width-fromWidth ) ) {
						deltaX *= -1;
						}
					}' .

					// Draw the image
					'var ctx = canvas.getContext("2d");
					ctx.drawImage(image' . $mocc . ',fromX,fromY,fromWidth,fromHeight,0,0,canvas.width,canvas.height);' .

					// Draw the preview image
					'var prevctx = prevCanvas.getContext("2d");
					prevctx.clearRect(0, 0, prevCanvas.width, prevCanvas.height);
					prevctx.drawImage(image' . $mocc . ',0,0,image' . $mocc . '.width,image' . $mocc . '.height,0,0,prevCanvas.width,prevCanvas.height);' .

					// Draw viewport rect on preview image
					'var factor = prevCanvas.width / image' . $mocc . '.width;
					prevctx.strokeRect(factor*fromX,factor*fromY,factor*fromWidth,factor*fromHeight);' .

					// Re-render if needed
					'if (run>0) {
						if (autorun){timer=setTimeout(function(){render()},25);}
						else {timer=setTimeout(function(){render()},25);}
					}
					if(run<5)run--;' .

					// Make controlbar visible
					'setTimeout(function(){jQuery("#wppa-pctl-div-"+' . $mocc . ').css({visibility:"visible"});}, 100);

				}' .

				// Horizontal movement by button
				'function onRightMouseDown(e){
					e.preventDefault();
					autorun=false;
					run=5;
					deltaX=3;
					deltaY=0;
					render();
				}' .

				'function onLeftMouseDown(e){
					e.preventDefault();
					autorun=false;
					run=5;
					deltaX=-3;
					deltaY=0;
					render();
				}' .

				// Vertical movement by button
				'function onUpMouseDown(e){
					e.preventDefault();
					autorun=false;
					run=5;
					deltaX=0;
					deltaY=-3;
					render();
				}' .

				'function onDownMouseDown(e){
					e.preventDefault();
					autorun=false;
					run=5;
					deltaX=0;
					deltaY=3;
					render();
				}' .

				// Zooming
				'function onZoomInMouseDown(e){
					e.preventDefault();
					deltaX=0;
					deltaY=0;
					autorun=false;
					run=5;
					deltaFactor=1.005;
					render();
				}' .

				'function onZoomOutMouseDown(e){
					e.preventDefault();
					deltaX=0;
					deltaY=0;
					autorun=false;
					run=5;
					deltaFactor=0.995;
					render();
				}' .

				// Mouse wheel
				'function onDivWheel(e) {
					e.preventDefault();
					deltaX=0;
					deltaY=0;
					autorun=false;
					run=4;
					deltaFactor = 1 + e.deltaY * zoomsensitivity / ( wppaIsChrome ? 10000 : 1000 );
					render();
					setTimeout(function(){deltaFactor = 1}, 25);
					e.stopPropagation();
				}' .

				// When a navigation button is released, stop and reset all deltas
				'function onButtonUp(e) {
					e.preventDefault();
					autorun=false;deltaX=0;deltaY=0;deltaFactor=1;
					run=4;
				}' .

				// When a (responsive) resize is required, we resize the wppaScene
				'function onResize' . $mocc . '(e){

					if (abort) return;' .

					( $lightbox ?

					// Show image container
					'$("#wppa-overlay-fpc").css("display", "");' .

					// There are 4 possiblilities: all combi of 'Width is the limit or not' and 'Mode is normal or fullscreen'
					'var widthIsLim,
					modeIsNormal = ! wppaIsFs();' .

					// First find container dimensions dependant of mode
					'var contWidth,	contHeight;

					if ( modeIsNormal ) {
						contWidth = window.innerWidth ? window.innerWidth : screen.width;
						contHeight = window.innerHeight ? window.innerHeight : screen.height;
					}
					else {
						contWidth = screen.width;
						contHeight = screen.height;
					}
					newWidth = parseInt(newWidth);
					newHeight = parseInt(newHeight);
					' .

					// Initialize new display sizes
					'var newWidth,
					newHeight,
					topMarg,
					leftMarg,
					extraX = 8,
					extraY = 24 + ' . ( $controls ? $icsiz : 0 ) . ' + contWidth * ' . $height . ' / ' . $width . ' + 40;' .

					// Add borderwidth in case of mode == normal
					'if ( modeIsNormal ) {
						extraX += 2 * ' . wppa_opt( 'ovl_border_width' ) . ';
						extraY += 2 * ' . wppa_opt( 'ovl_border_width' ) . ';
					}
					' .

					// Find out if the width is the limitng dimension
					'widthIsLim = ( contHeight > ( ( contWidth / 2 ) + extraY ) );' .

					// Compute new sizes and margins
					'if ( widthIsLim ) {
						newWidth = contWidth - extraX;
						newHeight = newWidth / 2;
						topMarg = ( contHeight - newHeight - extraY ) / 2 + 20;
					}
					else {
						newWidth = 2 * ( contHeight - ' . ( $controls ? $icsiz : 0 ) . ' - 24 - 40 ) / ( 1 + 2 * ' . $height . ' / ' . $width . ' );
						newHeight = newWidth / 2;
						topMarg = 20;
					}' .

					// Set css common for all 4 situations
					'$("#wppa-ovl-flatpan-container").css({top:topMarg,marginTop:0});

					canvas.width = newWidth;
					canvas.height = newHeight;
					prevCanvas.width = newWidth;
					prevCanvas.height = newWidth * ' . $height . ' / ' . $width . ';' .

					// Now set css for all 4 situations: Mode is normal
					'if ( modeIsNormal ) {' .

						// Common for mode normal
						'$("#wppa-ovl-flatpan-container").css({
							backgroundColor:"' . wppa_opt( 'ovl_theme' ) . '",
							padding:"' . wppa_opt( 'ovl_border_width' ) . 'px",
							borderRadius:"' . wppa_opt( 'ovl_border_radius' ) . 'px",
							width:newWidth,
							marginLeft:0
						});' .

						// Limit specific
						'if ( widthIsLim ) {
							$("#wppa-overlay-fpc").css({left:4});
						}
						else {
							$("#wppa-overlay-fpc").css({left:(contWidth-newWidth)/2});
						}
						wppaAdjustControlbar();
					}' .

					// Mode is fullscreen
					'else {' .

						// Common for mode fullscreen
						'$("#wppa-overlay-fpc").css({marginLeft:0});
						$("#wppa-ovl-flatpan-container").css({
							backgroundColor:"transparent",
							padding:0,
							borderRadius:"0px",
							width:newWidth,
							left:(contWidth-newWidth)/2
						});' .
						'wppaAdjustControlbar();' .

					'}' .

					'run=(autorun?5:4);
					render();
					' :

					// Not lightbox
					'canvasWidth = $(div).parent().width();
					canvasHeight = canvasWidth / 2;
					canvas.width = canvasWidth;
					canvas.height = canvasHeight;
					prevCanvas.width = canvasWidth;
					prevCanvas.height = canvasWidth * ' . $height . ' / ' . $width . ';
					run=(autorun?5:4);
					render();'
					) .

				'}' .

				// when the mouse is pressed on the canvas, we switch to manual control and save current coordinates
				'function onCanvasMouseDown(e){
					e.preventDefault();
					manualControl = true;
					autorun=false;
					deltaX=0;
					savedCanvasX = e.offsetX;
					savedCanvasY = e.offsetY;
					run=5;
					render();
				}' .

				'function onCanvasMouseMove(e){
					if ( manualControl ){
						autorun=false;
						deltaX=0;
						var factor = canvas.width / fromWidth;
						var x = ( savedCanvasX - e.offsetX ) / factor + fromX;
						var y = ( savedCanvasY - e.offsetY ) / factor + fromY;

						if ( x > 0 && y > 0 && ( x + fromWidth ) < image' . $mocc . '.width && ( y + fromHeight ) < image' . $mocc . '.height ) {
							fromX = x;
							fromY = y;
							savedCanvasX = e.offsetX;
							savedCanvasY = e.offsetY;
						}
					}
				}' .

				'function onPrevCanvasMouseMove(e){
					var factor = prevCanvas.width / image' . $mocc . '.width;

					if (e.offsetX > factor * fromX &&
						e.offsetX < factor * ( fromX + fromWidth ) &&
						e.offsetY > factor * fromY &&
						e.offsetY < factor * ( fromY + fromHeight ) ) {
							$(prevCanvas).css("cursor","grab");
					}
					else {
						$(prevCanvas).css("cursor","default");
					}

					if ( manualControl ){
						autorun=false;
						deltaX=0;
						if (e.offsetX > factor * fromX &&
						e.offsetX < factor * ( fromX + fromWidth ) &&
						e.offsetY > factor * fromY &&
						e.offsetY < factor * ( fromY + fromHeight ) ) {
							fromX = ( e.offsetX - savedCanvasX ) / factor + fromX;
							fromY = ( e.offsetY - savedCanvasY ) / factor + fromY;
							savedCanvasX = e.offsetX;
							savedCanvasY = e.offsetY;
						}
					}
				}' .

				'function onCanvasMouseUp(e){
					if ( manualControl ) {
						run=4;
						manualControl = false;
					}
				}' .

				'function timnow() {
					d = new Date();
					return d.getTime();
				}' .

				// Clean up
				'function quitImage(e) {
					abort = true;
					run = 0;
					autorun = false;
					clearTimeout(timer);
					$(canvas).hide();
					$(prevCanvas).hide();
					$("#wppa-pctl-div-0").hide();
				}' .
			'}

		</script>
		' . ( $haslink ? '<a>' : '' ) . '';

	return wppa_pan_min( $result );
}

// Just zoomable/pannable
function wppa_get_zoom_pan_html( $args ) {

	// Init
	$defaults 	= array( 	'id' 				=> '0',
							'mocc' 				=> '0',
							'width' 			=> false,
							'height' 			=> false,
							'haslink' 			=> false,
							'lightbox' 			=> 0,
							'controls' 			=> true,
							'autorun' 			=> '',
							'manual' 			=> true,
							'autorunspeed' 		=> '3',
							'zoomsensitivity' 	=> '3',
							);

	$args 				= wp_parse_args( $args, $defaults );

	$id 				= strval( intval ( $args['id'] ) );
	$mocc 				= $args['mocc'] ? $args['mocc'] : wppa( 'mocc' );
	$itemid 			= $mocc . '-' . $id;
	$width 				= $args['width'] ? $args['width'] : wppa_get_container_width();
	$height 			= $args['height'] ? $args['height'] : round( $width * wppa_get_photoy( $id ) / wppa_get_photox( $id ) );
	$haslink 			= $args['haslink'];
	$lightbox 			= $args['lightbox'];
	$icsiz 				= ( $lightbox ? wppa_opt( 'nav_icon_size_lightbox' ) : wppa_opt( 'nav_icon_size_panorama' ) );
	$iconsize 			= $icsiz . 'px;';
	$controls 			= $args['controls'];
	$zoomsensitivity 	= $args['zoomsensitivity'];
	$url 				= esc_url( wppa_is_mobile() ? wppa_get_photo_url( $id ) : wppa_get_hires_url( $id ) );
	$manual 			= $args['manual'];

	// Fake mooc = 0 for lightbox
	if ( $lightbox ) {
		$mocc = '0';
		$itemid = '0-' . $id;
	}

	$result = '';

	// Lightbox starts with 'PhotoID.'
	if ( $lightbox ) {
		$result .=
		$id . '.';
	}

	// Close possible link
	if ( $haslink ) {
		$result .=
		'</a>';
	}

	// The overall container
	if ( $lightbox ) {
		$result .=
		'<div
			id="wppa-ovl-zoom-container"
			style="background-color:' . wppa_opt( 'ovl_theme' ) . ';"
			>';
	}

		// The canvas container
		$result .=
		'<div
			id="wppa-pan-div-' . $itemid . '"
			class="wppa-pan-div wppa-pan-div-' . $mocc . '"
			style="' . ( $controls ? 'margin-bottom:4px;' : '' ) . 'line-height:0;"
			>' .

			// The actual drawing area
			'<canvas
				id="wppa-pan-canvas-' . $itemid . '"
				style="' . ( $manual ? 'cursor:grab;' : '' ) . ';"
			/>

		</div>';

		// The controlbar
		if ( $controls ) {

			// Open controlbar
			$result .=
			'<div
				id="wppa-pctl-div-' . $itemid . '"
				class="wppa-pctl-div wppa-pctl-div-' . $itemid . ' wppa-pctl-div-' . $mocc . ' ' . ( $lightbox ? 'wppa-pctl-div-lb' : '' ) . '"
				style="text-align:center;' . ( $lightbox ? 'visibility:hidden;' : '' ) . '"
				onclick="return false;"
				>';

				// If lightbox: prev button, start / stop buttons
				if ( $lightbox ) {
					$result .=
					'<span
						id="wppa-pctl-prev-' . $itemid . '"
						class="wppa-pan-prevnext"
						style="margin:0 2px 0 0;float:left;display:inline-block;"
						title="' . esc_attr( __( 'Previous image', 'wp-photo-album-plus' ) ) . '"
						onclick="wppaOvlShowPrev()"
						>' .
						wppa_get_svghtml( 'Prev-Button', $iconsize, $lightbox ) .
					'</span>' .
					'<span
						id="wppa-ovl-start-btn"
						style="margin:0 2px;float:left;display:none;"
						title="' . esc_attr( __( 'Start', 'wp-photo-album-plus' ) ) . '"
						onclick="wppaOvlStartStop()"
						>' .
						wppa_get_svghtml( 'Play-Button', $iconsize, $lightbox ) .
					'</span>' .
					'<span
						id="wppa-ovl-stop-btn"
						style="margin:0 2px;float:left;display:none;"
						title="' . esc_attr( __( 'Stop', 'wp-photo-album-plus' ) ) . '"
						onclick="wppaOvlStartStop()"
						>' .
						wppa_get_svghtml( 'Pause-Button', $iconsize, $lightbox ) .
					'</span>';
				}

				// Always The nav buttons
				$result .=
				'<span
					id="wppa-pctl-left-' . $itemid . '"
					style="margin:0 2px;display:inline-block;"
					title="' . esc_attr( __( 'Camera left', 'wp-photo-album-plus' ) ) . '"
					data-mocc="' . $mocc . '"
					>' .
					wppa_get_svghtml( 'Left-4', $iconsize, $lightbox ) .
				'</span>' .
				'<span
					id="wppa-pctl-right-' . $itemid . '"
					style="margin:0 2px;display:inline-block;"
					title="' . esc_attr( __( 'Camera right', 'wp-photo-album-plus' ) ) . '"
					data-mocc="' . $mocc . '"
					>' .
					wppa_get_svghtml( 'Right-4', $iconsize, $lightbox ) .
				'</span>' .
				'<span
					id="wppa-pctl-up-' . $itemid . '"
					style="margin:0 2px;display:inline-block;"
					title="' . esc_attr( __( 'Camera up', 'wp-photo-album-plus' ) ) . '"
					data-mocc="' . $mocc . '"
					>' .
					wppa_get_svghtml( 'Up-4', $iconsize, $lightbox ) .
				'</span>' .
				'<span
					id="wppa-pctl-down-' . $itemid . '"
					style="margin:0 2px;display:inline-block;"
					title="' . esc_attr( __( 'Camera down', 'wp-photo-album-plus' ) ) . '"
					data-mocc="' . $mocc . '"
					>' .
					wppa_get_svghtml( 'Down-4', $iconsize, $lightbox ) .
				'</span>' .
				'<span
					id="wppa-pctl-zoomin-' . $itemid . '"
					style="margin:0 2px;display:inline-block;"
					title="' . esc_attr( __( 'Zoom in', 'wp-photo-album-plus' ) ) . '"
					data-mocc="' . $mocc . '"
					>' .
					wppa_get_svghtml( 'ZoomIn', $iconsize, $lightbox ) .
				'</span>' .
				'<span
					id="wppa-pctl-zoomout-' . $itemid . '"
					style="margin:0 2px;display:inline-block;"
					title="' . esc_attr( __( 'Zoom out', 'wp-photo-album-plus' ) ) . '"
					data-mocc="' . $mocc . '"
					>' .
					wppa_get_svghtml( 'ZoomOut', $iconsize, $lightbox ) .
				'</span>';

				// If lightbox: next button and fullscreen buttons
				if ( $lightbox ) {
					$result .=
					'<span
						id="wppa-pctl-next-' . $itemid . '"
						class="wppa-pan-prevnext"
						style="margin:0 0 0 2px;float:right;display:inline-block;"
						title="' . esc_attr( __( 'Next image', 'wp-photo-album-plus' ) ) . '"
						onclick="wppaOvlShowNext()"
						>' .
						wppa_get_svghtml( 'Next-Button', $iconsize, $lightbox ) .
					'</span>' .
					'<span
						id="wppa-exit-btn-2"
						class=""
						style="margin:0 2px;float:right;display:inline-block;"
						title="' . esc_attr( __( 'Exit', 'wp-photo-album-plus' ) ) . '"
						onclick="wppaOvlHide()"
						>' .
						wppa_get_svghtml( 'Exit-2', $iconsize, $lightbox ) .
					'</span>';

					// Fs buttons
					if ( wppa_opt( 'fs_policy' ) == 'lightbox' && ! wppa_is_ipad() && ! wppa_is_safari() ) {
						$result .=
						'<span
							id="wppa-fulls-btn-2"
							class="wppa-fulls-btn""
							style="margin:0 2px;float:right;display:none;"
							title="' . esc_attr( __( 'Enter fullscreen', 'wp-photo-album-plus' ) ) . '"
							onclick="wppaFsOn()"
							>' .
							wppa_get_svghtml( 'Full-Screen-2', $iconsize, $lightbox ) .
						'</span>' .
						'<span
							id="wppa-exit-fulls-btn-2"
							class="wppa-exit-fulls-btn"
							style="margin:0 2px;float:right;display:none;"
							title="' . esc_attr( __( 'Leave fullscreen', 'wp-photo-album-plus' ) ) . '"
							onclick="wppaFsOff()"
							>' .
							wppa_get_svghtml( 'Exit-Full-Screen-2', $iconsize, $lightbox ) .
						'</span>';
					}
				}

			// End controlbar
			$result .=
			'</div>';
		}

	// wppa-ovl-zoom-container
	if ( $lightbox ) {
		$result .=
		'</div>';
	}

	// The js part
	$result .=
		'<script>' .

			// Create image object and add the image url to it
			( $lightbox ?
				'var image = document.getElementById(\'wppa-pre-curr\');' :
				'var image = new Image();'
			) .
			'image.src = "' . $url . '";' .

			'var data' . $mocc . ' =
				{	mocc				:' . $mocc . ',
					id					:' . $id . ',
					itemId				:"' . $itemid . '",
					isLightbox			:' . ( $lightbox ? 'true' : 'false' ) . ',
					image				:image,
					abort 				:false,
					zoomsensitivity		:' . $zoomsensitivity . ',
					borderWidth			:' . wppa_opt( 'ovl_border_width' ) . ',
					controls			:' . ( $controls ? 'true' : 'false' ) . ',
					height				:' . $height . ',
					width				:' . $width . ',
					initialized			:false,
					icsize				:' . ( $lightbox ? wppa_opt( 'nav_icon_size_lightbox' ) : wppa_opt( 'nav_icon_size_panorama' ) ) . ',
					backgroundColor		:\'' . wppa_opt( 'ovl_theme' ) . '\',
					borderRadius		:' . wppa_opt( 'ovl_border_radius' ) . ',
					padding				:' . wppa_opt( 'ovl_border_width' ) . '
				};

			jQuery(document).ready(function(){wppaDoZoomPan(' . $mocc . ', data' . $mocc . ');});

		</script>
		' . ( $haslink ? '<a>' : '' ) . '';

	return wppa_pan_min( $result );
}

// Minimize inine mixed html / js code
function wppa_pan_min( $result ) {

	// Remove tabs
	$result = str_replace( "\t", '', $result );

	// Remove newlines
	$result = str_replace( array( "\r\n", "\n\r", "\n", "\r" ), ' ', $result );

	// Trim operators
	$result = str_replace( array( ' = ',' + ',' * ',' / ' ), array( '=','+','*','/' ), $result );

	// Replace multiple spaces by one
	$olen = 0;
	$nlen = strlen( $result );
	do {
		$olen = $nlen;
		$result = str_replace( '  ', ' ', $result );
		$nlen = strlen( $result );
	} while ( $nlen != $olen );

	// Trim , ; and !
	$result = str_replace( array( ', ', '; ', '! ' ), array( ',', ';', '!' ), $result );

	// Trim braces
	$result = str_replace( array(  ' ) ', ') ', ' )' ), ')', $result );
	$result = str_replace( array(  ' ( ', '( ', ' (' ), '(', $result );

	// Remove space between html tags
	$result = str_replace( '> <', '><', $result );

	return $result;
}