//=========================================================================================================
//
// Copyright 2002, 2003, 2004 Macromedia, Inc. All rights reserved.
//
// Feature: Paste Fix
// Author:  JDH
// Module:  PasteManager.js
// Purpose:	Main Paste Manager class (and entry points).
// Updates:
//	5/17/02 - Started file control
//	5/31/02 - Added more comments
//
//=========================================================================================================

//  The paste manager which handles the entire clipboard conversion process

function PasteManager()
{
	// Initialize the phases array

	this.phases = new Array();

	// Put together the initial list of content handlers

	var handlers = new Array();
	handlers.push( new ParseMetaTags );
	handlers.push( new IdentifyMSApplications );
	handlers.push( new FixupMSGarbage );
	handlers.push( new RetainStructure );
	handlers.push( new DecomposeClasses );
	handlers.push( new RemoveUnsupportedAttributes );
	handlers.push( new RemoveParsingRequiredStructuralTags );
	handlers.push( new RemoveCSSClasses );
	handlers.push( new DemoteToParagraphs );
	handlers.push( new SingleSpaceParagraphs );
	handlers.push( new MergeRedundantFontTags );
	handlers.push( new ChangeToStrongAndEm );

	// Iterate through the content handlers and put organize them by
	// priority number into the phases member.

	for( index in handlers )
	{
		// Get the phase descriptor from the handler

		var phase_desc = handlers[ index ].getPhase();
	
		// Get the phase priority

		var phase = phase_desc.priority;

		// If the phase is currently empty then create the array to put the
		// handlers into

		if ( this.phases[ phase ] == null )
		{
			this.phases[ phase ] = new Array();
			this.phases[ phase ].name = phase_desc.name;
			this.phases[ phase ].elements = new Array();
		}

		// Push the handler into the handlers list for this phase number

		this.phases[ phase ].elements.push( handlers[ index ] );
	}
}

PasteManager.prototype.run = PasteManager_run;
PasteManager.prototype.getClipHTML = PasteManager_getClipHTML;
PasteManager.prototype.getDebugText = PasteManager_getDebugText;
PasteManager.prototype.getDebugHTML = PasteManager_getDebugHTML;

function PasteManager_run( clipDOM, clipCSS, targetDOM, targetCSS, settings )
{
	// Put together the new context

	this.pasteContext = new PasteContext( clipDOM, clipCSS, targetDOM, targetCSS, settings );

	// Start the debug trace

	for( var setting in settings )
		this.pasteContext.debugInformation( "PasteManager", "Setting : " + setting );
	this.pasteContext.debugInformation( "PasteManager", "Start run" );

	// Iterate through the phases

	for ( var phase_index = 0; phase_index < PHASE_MAX; phase_index++ )
	{
		// If we have elements in this phase then iterate through them

		if ( this.phases[ phase_index ] )
		{
			// Put out the debugging information

			this.pasteContext.debugInformation( "PasteManager", "Phase: " + this.phases[ phase_index ].name );

			// Get the phase elements and interate through them and run each one

			var phase = this.phases[ phase_index ].elements;
			for( handler_index in phase )
			{
				var handler = phase[ handler_index ];
				handler.run( this.pasteContext );

//				alert(  "Phase " + handler + ": " + this.phases[ phase_index ].name + "\n" + this.pasteContext.getClipText() );
			}
		}
	}

	// Finish the debug trace

	this.pasteContext.debugInformation( "PasteManager", "End run" );
	this.pasteContext.updateClipDOM();

	if ( this.pasteContext.settingDefined( SETTINGS_NO_FILTER ) )
		return false;
	return true;
}

function PasteManager_getDebugText( ) { return this.pasteContext.getDebugText(); }

function PasteManager_getDebugHTML( ) { return this.pasteContext.getDebugHTML(); }

function PasteManager_getClipHTML( )
{
	// JDH: This is pretty brute force.  First we turn the whole document into text, then we 
	// find the start and end of the fragment, suck it out, and then remove the markers from the
	// finished piece.

	var full_html = this.pasteContext.getClipText();
//	DWfile.write("file:///C|/html.txt", full_html);

	full_html = full_html.replace( /[\r\n]/g, " " );

	
	var out_html = full_html.match( /\<body\>(.*?)\<\/body\>/g );
	out_html = out_html.toString();

	out_html = out_html.replace( /\<body\>/, "" );
	out_html = out_html.replace( /\<\/body\>/, "" );
	out_html = out_html.replace( /\<\!\-\-(\s*)StartFragment(\s*)\-\-\>/, "" );
	out_html = out_html.replace( /\<\!\-\-(\s*)EndFragment(\s*)\-\-\>/, "" );

	return out_html;
}



function smartPaste( bSilent, inputDOM, returnValue )
{
	// Check to make sure we aren't trying to paste in something huge

//	alert( inputDOM.documentElement.outerHTML );
//	alert( "vesion: jdh_021203" );
//	var deb = new DebugScanner();
//	deb.scan( inputDOM.documentElement.outerHTML );
//	return;
	
	if ( bSilent == false )
	{
		var text = inputDOM.documentElement.outerHTML;
	/*	if ( text.length > MM.od_MaxThreshold)
		{
			alert ( MM.MSG_odStop );
			returnValue[ 0 ] = true;
			return;
		}
	*/
		if ( text.length > MM.od_WarnThreshold )
		{
			if ( ! confirm( MM.MSG_odWarn ) )
			{
				returnValue[ 0 ] = true;
				returnValue[ 1 ] = false;  // this represents that user has pressed cancelled button.
				return;
			}
		}
	}

	try {


		// Put together a new paste manager

		var mgr = new PasteManager();

		// Define the settings for the paste

		var settings = {};
		settings[ SETTINGS_CONTRIBUTE ] = 1;
		
		// Look for Contribute specific settings
		
		if ( dreamweaver.appName == "Contribute" )
		{
			if (dreamweaver.getDocumentDOM().getCCSharedSetting_PasteWordTextOnly())
			{
				dw.getDocumentDOM().clipPasteText();
				returnValue[ 0 ] = true
				return;
			}

				
			if ( dreamweaver.getDocumentDOM().getCCSharedSetting_TextOnlyInNonTemplates())
				settings[ SETTINGS_ETO ] = 1;
			
			if ( dreamweaver.getDocumentDOM().getCCSharedSetting_FontsEmitFontOrSpan() == "font" )
				settings[ SETTINGS_CHANGE_SPAN_TO_FONT ] = 1;

			if ( ! dreamweaver.getDocumentDOM().getCCSharedSetting_FontsLetUserChange())
				
				settings[ SETTINGS_NO_CSS ] = 1; 
	
			if ( ! dreamweaver.getDocumentDOM().getCCSharedSetting_StyleHTMLHeadings() )
				settings[ SETTINGS_DEMOTE_TO_PARAGRAPHS ] = 1;

			if ( ! dreamweaver.getDocumentDOM().getCCSharedSetting_StyleCSS())
				settings[ SETTINGS_NO_CSS ] = 1;

			if ( dreamweaver.getDocumentDOM().getCCSharedSetting_SingleSpaceParagraphsCSS() )
				settings[ SETTINGS_SINGLE_SPACE_P ] = 1;
				
			// check to see what units we want our word stuff emited in. -- jcheng
			var unit = dreamweaver.getDocumentDOM().getCCSharedSetting_FontsEmitFontUnits();
			
			if (!dreamweaver.getDocumentDOM().getCCSharedSetting_SingleSpaceParagraphsCSS())
				settings[SETTINGS_NO_INLINE_STYLES] = 1;
	
			if ( unit == "pixels")
			{
				settings[ SETTINGS_USE_PIXELS ] = 1;
			}
			if ( unit == "ems")
			{
				settings[ SETTINGS_USE_EMS ] = 1;
			}
			if ( unit == "%")
			{
				settings[ SETTINGS_USE_PERCENT ] = 1;
			}
			
			if (!dreamweaver.getDocumentDOM().getCCSharedSetting_FontsLetUserChange() )
			{
				settings [SETTINGS_NO_FONT] = 1;
			}
			if (!dreamweaver.getDocumentDOM().getCCSharedSetting_DecorationLetUserChange())
			{
				settings [SETTINGS_NO_DECORATION] = 1;
			}
			if (!dreamweaver.getDocumentDOM().getCCSharedSetting_ColorLetUserChange())
			{
				settings [SETTINGS_NO_COLOR] = 1;
			}
			
		}
		

		if ( dreamweaver.appName.match( /dreamweaver/i ) )
		{
			if ( dw.getPasteSettings().match( /high/ ) )
			{
				settings[ SETTINGS_CREATE_CLASSES ] = 1;
				settings[ SETTINGS_NO_FONT_MAP ] = 1;
			}
			else
			{
				settings[ SETTINGS_NO_CSS ] = 1;
				settings[ SETTINGS_LOW ] = 1;
			}
		}

		if ( dw.getPreferenceString("General Preferences", "Avoid Bold and Italic", 'TRUE') == 'TRUE')
		{
			settings[ SETTINGS_USE_EMPHASIS ] = 1;
		}

		if ( dw.getPreferenceString("General", "Use <strong> and <em> in place of <b> and <i>", "") )
		{
			settings[ SETTINGS_USE_EMPHASIS ] = 1;
		}
		
		//check the admin settings to see we want <em> and <string> instead of <b> and <i>
		if (dreamweaver.appName == "Contribute" )
		{
			if (dw.getDocumentDOM().getCCSharedSetting_FontsUseEmphasisStrong())
			{
				settings[ SETTINGS_USE_EMPHASIS ] = 1;
			}
		}

		// Get the names of the classes in the target

		var targetCSS = new CSSReferenceClassCollection();

		// Here we add referenced classes to the target CSS representative.  All that we
		// use is the class name.
		var styles = dreamweaver.cssStylePalette.getStyles();
		for ( var index in styles )
			targetCSS.add( styles[ index ] );

		// Get the CSS definitions from the clipboard

		var clipCSS = new CSSClassCollection( targetCSS );

		Utils_LoadCSSFromDOM( inputDOM, clipCSS );

		var filtered = mgr.run( inputDOM, clipCSS, null, targetCSS, settings );

		if ( filtered )
		{
			used_styles = clipCSS.create_used();
	
			out = mgr.getClipHTML();

			var htmlOut = "";
			htmlOut += "<html>\n";
			
			if ( used_styles.length > 0 )
			{
				htmlOut += "<!--StartFragment-->\n";
				htmlOut += "<head>\n";
				htmlOut += "<style type=\"text/css\"><!--\n" + used_styles + "--></style>\n";
				htmlOut += "</head>\n";
				htmlOut += "<body>\n";				
			}
			else
			{
				htmlOut += "<body>\n";
				htmlOut += "<!--StartFragment-->\n";
			}
			
			htmlOut += out;
			
			if ( used_styles.length > 0 )
			{
				htmlOut += "</body>\n";
				htmlOut += "<!--EndFragment-->\n";
			}
			else
			{
				htmlOut += "<!--EndFragment-->\n";
				htmlOut += "</body>\n";
			}
			htmlOut += "</html>\n";

			// throw out &nbsp; 's if the admin said so -- jcheng
			if (dreamweaver.appName == "Contribute" )
			{
				if (!dw.getDocumentDOM().getCCSharedSetting_allowMultipleSpaces())
				{
					htmlOut = htmlOut.replace(/(&nbsp;)+/gi, "");
				}
				
				// take out all the smart quotes too
				var regExpLdquo = new RegExp(String.fromCharCode(8220), "g");
				var regExpRdquo = new RegExp(String.fromCharCode(8221), "g");
				var regExpLsquo = new RegExp(String.fromCharCode(8216), "g");
				var regExpRsquo = new RegExp(String.fromCharCode(8217), "g");
				
				htmlOut = htmlOut.replace (regExpLdquo, "&ldquo;");
				htmlOut = htmlOut.replace (regExpRdquo, "&rdquo;");
				htmlOut = htmlOut.replace (regExpLsquo, "&lsquo;");
				htmlOut = htmlOut.replace (regExpRsquo, "&rsquo;");
				
				if (!dreamweaver.getDocumentDOM().getCCSharedSetting_DecorationLetUserChange())
				{
					var regExpDecoration = 
						new RegExp ("<i>|</i>|<b>|</b>|<s>|</s>|<u>|</u>|<em>|</em>|<strong>|</strong>", "gi");
					htmlOut = htmlOut.replace (regExpDecoration, "");
				}
			}
			inputDOM.documentElement.outerHTML = htmlOut;

		//	alert( inputDOM.documentElement.outerHTML );
		}

		dw.forceGarbageCollection();

		formatSource( inputDOM );

	}
	catch( e )
	{
		alert( MM.MSG_odProblem );
		dw.getDocumentDOM().clipPasteText();
		returnValue[ 0 ] = true;
	}

	return true;
}
