<?php
	// 
	// index.php
	//
	// This is part of the source code for the EditGallery application.  
	// See also the companion save.php file.
	//
	// This code can be freely copied, modified, and distributed.  
	//    

	// If someone wants to view the source, then dump it out.
	if( isset( $_GET["source"] ) ) {
		echo "<pre>";
		echo htmlentities( file_get_contents( "index.php") );								
		echo "</pre>";
		exit;
	}
	
	// NOTE: Most of the PHP code in this sample is used to manage finding, loading, and saving
	// the images on the disk.  Don't worry too much about how it works -- the Javascript
	// code down below is much more interesting.
	
	// $strRoot will be the URL to this page's parent directory
	$strPath = str_replace( "\\", "/", $_SERVER['REQUEST_URI'] );
	$aPath = explode( "?", $strPath);
	$strRoot = "http://" . $_SERVER['SERVER_NAME'] . ":" . $_SERVER['SERVER_PORT'] . $aPath[0];
	$aSelfBits = explode( "/", $_SERVER['PHP_SELF'] );
	$strFile = $aSelfBits[count($aSelfBits)-1];
	$strRoot = str_replace( $strFile, "", $strRoot );	// remove the name of the page
	if ($strRoot[strlen($strRoot)-1] != "/")
		$strRoot .= "/";

	// We need to find the list of pictures for display.  We'll do a little PHP magic
	// to find all the photos in a directory relative to this page.  If you're running this locally,
	// make sure you've created an "img" directory and put a bunch of .jpg files in there. While
	// you're at it, you should probably add 75x75 square thumbnail versions of your originals
        $dir_handle = opendir( "img" );
        $aImgContents = Array();
        while ( false !== ( $entry = readdir( $dir_handle ) ) )
        { 
            if( $entry == "." ||
                $entry == ".." || 
		is_dir( "img/" . $entry ) ) {
                continue;
            }
            $aImgContents[] = $entry;
        }
	
	// Store info about each image in the $aImages array. Images are stored as name.type.jpg, 
	// where "name" is a unique id for this image, and "type" is the one of "", ""orig_t", edit", or "edit_t".
	$aImages = Array();
	foreach ($aImgContents as $fname) {
		$aNameBits = explode( ".", $fname );
		$strImageId = $aNameBits[0];
		$type = $aNameBits[1] == "jpg" ? "orig" : $aNameBits[1];
		if (isset($aImages[$strImageId])) {
			$oImgFiles = $aImages[$strImageId];
		} else {
			$oImgFiles = Array();
		}
		$oImgFiles[$type] = $strRoot . "img/" . $fname;		
		$aImages[$strImageId] = $oImgFiles;
	}
	
	// Make sure we've got an entry for all for file types, even if it's the wrong size.  This is
	// handy if you haven't fully populated the /img dir with all image types yet.
	foreach ($aImages as $strImageId => $oImgFiles ) {
		if (!isset( $oImgFiles['orig'] )) {
			// current() retrieves first element
			$oImgFiles['orig'] = current( $oImgFiles );	
		}
		if (!isset( $oImgFiles['orig_t'] )) 
			$oImgFiles['orig_t'] = $oImgFiles['orig'];	
		if (!isset( $oImgFiles['edit'] )) 
			$oImgFiles['edit'] = $oImgFiles['orig'];
		if (!isset( $oImgFiles['edit_t'] )) 
			$oImgFiles['edit_t'] = $oImgFiles['orig_t'];
		$aImages[$strImageId] = $oImgFiles;
	}
?>
<html>
<head>
	<title>Picnik Sample: The Edit Gallery</title>	
	<!-- These two files are requried to enable Picnik-in-a-box -->
	<script type="text/javascript" src="http://www.picnik.com/picnikbox/picnikbox_2_0.js"></script>
	<link href="http://www.picnik.com/picnikbox/picnikbox_2_0.css" rel="stylesheet" type="text/css" media="screen"/>
	
	<!-- some javascript to enable our dynamic ajaxyness -->
	<script type="text/javascript">
		// utility function
		function ExtractArgs() {
			var args = new Object();
			var query = location.search.substring(1);  		// Get query string.
			var pairs = query.split("&");              		// Break at ampersand.
			for (var i = 0; i < pairs.length; i++) {
				var pos = pairs[i].indexOf('=');    	// Look for "name=value".
				if (pos == -1) continue;              	// If not found, skip.
				var argname = pairs[i].substring(0,pos); 	// Extract the name.
				var value = pairs[i].substring(pos+1); 	// Extract the value.
				args[argname] = unescape(value);
			}
			return args;
		}
	
		// our default picnik api parameters
		var strPicnikUrl = "http://www.picnik.com/service/?";	// $strPicnikUrl is the URL that we use to launch Picnik.
		var strRoot = <?php echo '"' . $strRoot . '"' ?>;
		var aPicnikParams = { 
			_apikey: "2121789cd164f9a89cefbc259495c9cf", // get your own API key at http://www.picnik.com/info/api
			_export: strRoot + "save.php",			// tell Picnik where to send the exported image	
			_close_target: strRoot + "save.php",		// turn on the close button, and tell it where to go
			_export_method: "GET",				// use GET to send us the result
			_export_agent: "browser",				// send the result via a browser redirect
			_export_title: "Save My Changes",			// give the export button a title
			_replace: "yes",					// always replace (required to have _imageid sent back
			_host_name: "The Edit Gallery",		// tell Picnik our name.  It'll be used in a few places as appropriate
			_thumbs: "yes",					// We want to receive thumbnails	
			_out_maxsize: "400",				// We don't really need huge images, so keep the size small	
			_exclude: "out"					// turn off the "Save & Share" tab so users don't get confused
		};
		
		// an array of all the images we know about
		var aImages = { <?php
			// initialize the array with all the data we found inside the /img directory
			$fFirst = true;
			foreach( $aImages as $id => $files ) {
				if (!$fFirst) echo ",";
				$fFirst = false;
				
				echo "\n$id: {";
				echo "\n  orig: '" . $files['orig'] . "',";
				echo "\n  orig_t: '" . $files['orig_t'] . "',";
				echo "\n  edit: '" . $files['edit'] . "',";
				echo "\n  edit_t: '" . $files['edit_t'] . "'";
				echo "}";
			}
		?> };
		
		
		// stores new image files for the given image id and refreshes the display
		function refreshById( strImageId, oImgFiles) {
			for (var strFile in oImgFiles)
				aImages[strImageId][strFile] = oImgFiles[strFile];
			refreshNavById( strImageId );
			displayImageById( strImageId );
		}
		
		// creates the HTML for the navigation bar at the top
		function refreshNav() {
			var elNav = $("nav");
			if (!elNav) return;
			elNav.innerHTML = "";
			for ( var strImageId in aImages ) {
				elNav.innerHTML += "<span id='" + strImageId + "_nav' align='center' style='padding:5px'>loading...</span> ";
				refreshNavById( strImageId );
			}
		}
		
		// creates the HTML for an individual picture in the nav bar
		function refreshNavById( strImageId ) {
			var oImgFiles = aImages[strImageId];
			var elHolder = $(strImageId + "_nav");
			if (!elHolder) return;
			
			var strHtml = "";
			strHtml += "<a href='#' onclick='" + "javascript:displayImageById(\"" + strImageId + "\");" + "'>";
			strHtml += "<img width='75' height='75' src='" + oImgFiles['edit_t'] + "?" + (new Date).valueOf() + "'>";
 			strHtml += "</a>";
			elHolder.innerHTML = strHtml;
		}
		
		// creates the HTML for a big view of an image and the picnik edit link
		function displayImageById( strImageId ) {
			if (! (strImageId in aImages)) return;
			var oImgFiles = aImages[strImageId];
			var elHolder = $("content");
			if (!elHolder) return;

			// create the picnik edit URL.  Mostly we just use the defaults; we just change
			// the _imageid and _import parameters for each image.
			aPicnikParams['_imageid'] = strImageId;
			aPicnikParams['_import'] = oImgFiles['orig'];
			var strApiUrl = strPicnikUrl;
			for( var strKey in aPicnikParams ) {
				strApiUrl += strKey + "=" + encodeURIComponent( aPicnikParams[strKey] ) + "&";
			}
			
			// generate the HTML to display the image in the big green rectangle
			var strHtml = "";
			strHtml += "<div>";
			strHtml += "<img align='left' border='1' width='75' height='75' src='" + oImgFiles['orig_t'] + "?" + (new Date).valueOf() + "'>";
			strHtml += "<font size='+1'><b>" + strImageId + "</b></font><br/>original<br/><br/>";
			strHtml += " <a href='" + strApiUrl + "' class='pbox' id='" +strImageId + "_link'>"
			strHtml += "<b>Create your own version of " + strImageId + "!</b></a>";
			strHtml += "</div>";
			strHtml += "<div style='clear:both; padding: 20px;'>Current Edit:</br>"
			strHtml += "<img border='1' src='" + oImgFiles['edit'] + "?" + (new Date).valueOf() + "'>";
			strHtml += "</div>";
			elHolder.innerHTML = strHtml;
			
			// because we're creating our Picnik links dynamically, and not at load-time, then we need 
			// manually tell PicnikBox to turn this link into a PicnikBox link.
			PicnikBox.AddLink( $(strImageId+"_link") );
		}
		
		var strOldTitle = document.title;
		function OnPicnikActivate( elLink ) {
			// You can do all kinds of interesting things just before Picnik launches.  You could change
			// the header of your page to say something like "You're now in Picnik Mode"; you could disable
			// some buttons (but not others) to make Picnik editing semi-modal; or you could adjust the Picnik
			// borders or margins to accurately position it on your page.  
			
			// All we do is change the document's title.
			document.title = strOldTitle + ": You're currently inside the Picnik Box!";
		}
		
		function OnPicnikDeactivate( elLink ) {
			// In here you should reset anything you did in the activate function.
			// We reset the document's title.
			document.title = strOldTitle;		
		}
		
	</script>
</head>
<body>
<div style="width: 300px; height:100px; float:left; padding: 5px;">
	<div>
	<b>The Edit Gallery</b><br/>
	This is a <b>sample gallery application</b> demonstrating the use of the <b>Picnik API</b> and embedded <b>Picnik-in-a-Box</b> integration in a Javascript web app.
	<br/><br/>
	</div>
</div>
<div id="nav" style="width:400px; height:100px; overflow:auto; padding: 5px; border:1px solid #888; background-color: #DDD; ">
</div>
<div id="content" valign="top" style="clear:both; width:700px; height: 500px; margin-top: 10px; padding: 10px; background-color: #DEC; border: 1px solid #897">
	<b>Click any of the above images.</b>
</div>
<div id="footer" style="width:700px; padding-top:10px; text-align:right;">
	You can view the PHP / Javascript source code <a href="index.php?source">for this page</a> and <a href="save.php?source">the companion save script</a>.<br/>
	For more information about the Picnik API, visit <a href="http://www.picnik.com/info/api">the Picnik API documentation</a>.
	
</div>

<script type="text/javascript">
	//
	// We can configure a few things via the PicnikBox API.
	//
	// create a wide top margin so that the control UI is visible (but inactive)
	// this shows the user the she hasn't left the original website
	PicnikBox.SetPicnikMargins( 125, 0, 0, 0 );	

	// give us a 1px border on the top
	PicnikBox.SetPicnikBorders( 2, 0, 0, 0 );
	
	// tell PicnicBox.js to call us just before Picnik gets launched and after it closes
	PicnikBox.SetActivateCallback( OnPicnikActivate );
	PicnikBox.SetDeactivateCallback( OnPicnikDeactivate );
	
	// Create the navigation bar and all its little images.
	refreshNav();
	
	// In some cases, Picnik will navigate the user out to a 3rd-party site and
	// then back to Picnik.com, and we'll lose our Picnik-in-a-box-ness.  This typically
	// only happens if the user is authenticating with a site such as Facebook or Flickr.
	// To handle this case, we need to be able to recreate the state the user was in
	// before launching Picnik.  In our case, we look for a an image id (which will be
	// passed in to us via the save script) and we select that image.
	var aArgs = ExtractArgs();
	if ("id" in aArgs) displayImageById( aArgs["id"] );
</script>

</body>
</html>