/*
Copyright (c) 2003-2008, Frederico Caldeira Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
 */

CKRELEASER.load( 'ckreleaser.includes.xml' );

CKRELEASER.samplesProcessor = function( release )
{
};

( function()
{
	var template, templateLocation, templateDocument, processedFiles = {}, copiedFiles = {};

	var regexLib = {
		head :Pattern.compile( '<head.*?<\\/head>', Pattern.DOTALL ),
		body :Pattern.compile( '<body.*?<\\/body>', Pattern.DOTALL ),
		script :Pattern.compile( '<script ([^>]+)/>' )
	};

	/**
	 * Remove node and initial text node (with white space characters only)
	 */
	function removeNode( node )
	{
		var sibling = node.getPreviousSibling();

		if ( sibling && sibling.getNodeType() == org.w3c.dom.Node.TEXT_NODE && sibling.getNodeValue().match( /^\s*$/ ) !== null )
			node.parentNode.removeChild( sibling );

		node.parentNode.removeChild( node );
	}

	function processXmlFile( sourceLocation, targetLocation )
	{
		var fileContent = CKRELEASER.io.readFile( sourceLocation );
		CKRELEASER.io.saveFile( targetLocation, fileContent.replace( /\\/g, '\\\\' ) );

		var newDocument = templateDocument.cloneNode( true );
		var document = CKRELEASER.xml.loadDocument( targetLocation );
		var result = template;
		var node = {
			code :null,
			html :null,
			headscript :null,
			styles :null
		};
		var replacement = {
			code :"",
			html :"",
			headscript :"",
			styles :"",
			head :"",
			body :""
		};

		node.html = document.getElementById( 'html' );
		node.code = document.getElementById( 'code' );

		if ( !node.html || !node.code )
		{
			//Not a xml template, probably index.html or documentation.
			if ( CKRELEASER.verbose )
				print( "    WARNING: File with .html extension does not contain all necessary elements (html, code): "
						+ sourceLocation.getName() );

			if ( sourceLocation.getAbsolutePath() != templateLocation.getAbsolutePath() )
				CKRELEASER.io.copyFile( sourceLocation, targetLocation );
			return;
		}

		node.html = newDocument.importNode( node.html, true );
		node.code = newDocument.importNode( node.code, true );

		if ( newDocument.getElementById( 'html' ) )
			CKRELEASER.xml.replaceNodeWithNodes( newDocument, newDocument.getElementById( 'html' ), node.html.getChildNodes() );
		if ( newDocument.getElementById( 'code' ) )
			CKRELEASER.xml.replaceNodeWithNodes( newDocument, newDocument.getElementById( 'code' ), node.code.getChildNodes() );

		node.styles = document.getElementById( 'styles' );
		node.headscript = document.getElementById( 'headscript' );

		if ( node.styles )
		{
			node.styles = newDocument.importNode( node.styles, true );
			CKRELEASER.xml.replaceNode( newDocument, newDocument.getElementById( 'styles' ), node.styles );
		}
		else
		{
			removeNode( newDocument.getElementById( 'styles' ) );
			if ( CKRELEASER.verbose )
				print( "    XML file does not contain element with id 'styles': " + sourceLocation.getName() );
		}

		if ( node.headscript )
		{
			node.headscript = newDocument.importNode( node.headscript, true );
			CKRELEASER.xml.replaceNode( newDocument, newDocument.getElementById( 'headscript' ), node.headscript );
		}
		else
		{
			removeNode( newDocument.getElementById( 'headscript' ) );
			if ( CKRELEASER.verbose )
				print( "    XML file does not contain element with id 'headscript': " + sourceLocation.getName() );
		}

		/**
		 * FIXME: #3220
		 * xml:space="preserve" is somehow being added to the script tag.
		 */
		var scripts = newDocument.getElementsByTagName( 'script' );
		for ( var i = 0 ; i < scripts.getLength() ; i++ )
		{
			scripts.item( i ).removeAttribute( "xml:space" );
		}

		/**
		 * FIXME: No matter how do we set the OutputKeys.METHOD in
		 * CKRELEASER.xml.saveXml there is always something wrong. Setting
		 * "text" removes all tags. Setting "html" adds uppercased Meta tag,
		 * even if meta tag already exists. Setting "xml" moves first comment
		 * above doctype declaration. So instead of simply saving the xml file,
		 * we have to take the template file and replace only head and body tags
		 * in it.
		 */
		replacement.head = CKRELEASER.xml.asXml( newDocument, newDocument.getElementsByTagName( 'head' ).item( 0 ) );
		replacement.body = CKRELEASER.xml.asXml( newDocument, newDocument.getElementsByTagName( 'body' ).item( 0 ) );

		result = String( regexLib.head.matcher( result ).replaceAll( replacement.head ) );
		result = String( regexLib.body.matcher( result ).replaceAll( replacement.body ) );
		result = String( regexLib.script.matcher( result ).replaceAll( "<script $1></script>" ) );

		print( "    Created sample " + targetLocation.getName() );
		CKRELEASER.io.saveFile( targetLocation, result );
	}

	function processDirectory( sourceLocation, targetLocation )
	{
		if ( CKRELEASER.release.isIgnoredPath( sourceLocation.getAbsolutePath() ) )
			return;

		if ( sourceLocation.isDirectory() )
		{
			if ( !targetLocation.exists() )
			{
				targetLocation.mkdir();
			}

			var children = sourceLocation.list();
			for ( var i = 0 ; i < children.length ; i++ )
			{
				processDirectory( new File( sourceLocation, children[i] ), new File( targetLocation, children[i] ) );
			}
		}
		else
		{
			if ( sourceLocation.equals( templateLocation ) )
				return;

			if ( sourceLocation.getAbsolutePath().toLowerCase().endsWith( ".html" ) )
				processXmlFile( sourceLocation, targetLocation );
			else
				CKRELEASER.io.copy( sourceLocation, targetLocation );

			copiedFiles[sourceLocation] = targetLocation;
		}
	}

	CKRELEASER.samplesProcessor.prototype = {
		createSamples : function( sourceDir, targetDir )
		{
			var sourceLocation = new File( sourceDir, CKRELEASER.release.samples.source );
			if ( !sourceLocation.exists() )
				throw "Invalid source (" + sourceLocation.getAbsolutePath() + ")";

			var targetLocation = new File( targetDir, CKRELEASER.release.samples.target );
			if ( !targetLocation.exists() )
			{
				if ( !targetLocation.mkdir() )
					throw "Creating samples failed. Can't create target directory (" + targetLocation.getCanonicalPath() + ")";
			}

			templateLocation = new File( sourceDir, CKRELEASER.release.samples.template );
			if ( !templateLocation.exists() )
				throw "Missing template file (" + templateLocation.getAbsolutePath() + ")";

			templateDocument = CKRELEASER.xml.loadDocument( templateLocation );
			template = CKRELEASER.io.readFile( templateLocation );

			CKRELEASER.release.removeIgnoredPath( CKRELEASER.release.samples.source );
			processDirectory( sourceLocation, targetLocation );
			CKRELEASER.release.addIgnoredPath( CKRELEASER.release.samples.source );
		}
	};
})();
