<?php

/**
 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @package fusionLib
 * @copyright Copyright (c) 2011 - 2014 fusionLib. All rights reserved.
 * @link http://fusionlib.com
 */

/**
 * flBufferJs Class
 *
 * Collect JavaScript together, both files and inline, merging inline where possible.
 *
 * @package fusionLib
 */
class flBufferJs {
	/**
	 * Array of JS.
	 *
	 * @var array
	 */
	private $js = array();

	/**
	 * Flags if the last added was a file
	 *
	 * @var bool
	 */
	private $lastFile = true;

	/**
	 * List of files to ignore.
	 *
	 * @var array
	 */
	private $ignore = array();

	/**
	 * List of files loaded.
	 *
	 * @var array
	 */
	private $files = array();

	/**
	 * The text before inline JavaScript
	 *
	 * @var string
	 */
	private $wrapBefore = "<script type=\"text/javascript\">\n//<![CDATA[\n";

	/**
	 * The text after inline JavaScript
	 *
	 * @var string
	 */
	private $wrapAfter = "//]]>\n</script>";

	/**
	 * Wrap the JS in style tags.
	 */
	private function wrapLast() {
		$this->js[count($this->js) - 1] = $this->wrapBefore . $this->js[count($this->js) - 1] . $this->wrapAfter;
	}

	/**
	 * Set the before and after strings to wrap inline JavaScript with.
	 *
	 * @param string $before The before text.
	 * @param string $after The after text.
	 */
	function setWrap($before, $after) {
		$this->wrapBefore = $before;
		$this->wrapAfter = $after;
	}

	/**
	 * Clear the buffer.
	 */
	function clear() {
		$this->js = array();
		$this->lastFile = true;
		$this->ignore = array();
		$this->files = array();
	}

	/**
	 * Set the list of files to ignore.
	 *
	 * @param array $ignore The list of files to ignore.
	 */
	function setIgnoreList($ignore) {
		$this->ignore = $ignore;
	}

	/**
	 * Get the list of files loaded.
	 *
	 * @return array The file list.
	 */
	function getFileList() {
		return $this->files;
	}

	/**
	 * Buffer inline JavaScript or a file.
	 *
	 * @param string $js The JS to buffer.
	 * @return flBufferJs This object.
	 */
	function buffer($js) {
		// If JS file given
		if(preg_match('/\.js(\?.*)?$/', $js) || preg_match('/^https?:/', $js)) {

			// If last as script then close it
			if(!$this->lastFile)
				$this->wrapLast();

			$this->lastFile = true;

			if(!isset($this->ignore[$js]) && !isset($this->files[$js])) {
				$this->js[] = "<script type=\"text/javascript\" src=\"$js\"></script>";
				$this->files[$js] = 1;
			}
		}
		// Else inline script
		else {
			// If last was a file start new
			if($this->lastFile)
				$this->js[] = "$js\n";
			else
				$this->js[count($this->js) - 1] .= "$js\n";
			$this->lastFile = false;
		}
		return $this;
	}

	/**
	 * Prepend a JavaScript file to the buffer.
	 *
	 * @param string $js The JS file to buffer.
	 * @return flBufferJs This object.
	 */
	function prepend($js) {
		if(!isset($this->ignore[$js]) && !isset($this->files[$js])) {
			array_unshift($this->js, "<script type=\"text/javascript\" src=\"$js\"></script>");
			$this->files[$js] = 1;
		}
		return $this;
	}

	/**
	 * Get the contents of the buffer.
	 *
	 * @return string The buffer contents.
	 */
	function getBuffer() {
		if(!$this->lastFile)
			$this->wrapLast();
		$this->lastFile = true;
		return count($this->js) ? join("\n", $this->js) . "\n" : '';
	}
}
