<?php
/**
 * @version		$Id: fckeditor.php 1154 18-1-2008 andrew
 * @package		JoomlaFCK
 * @copyright	Copyright (C) 2006 - 2008 WebXSolution Ltd. All rights reserved.
 * @license		Creative Commons Licence <http://www.joomlafckeditor.com/index.php?option=com_content&view=article&id=5&Itemid=2>
 * Ths application has been written by WebxSolution Ltd.  You may not copy or distribute JoomlaFCK without written consent
 * from WebxSolution Ltd.
 */

// Do not allow direct access
defined( '_JEXEC' ) or die( 'Restricted access' );

jimport('joomla.event.plugin');

/**
 * fckeditor Lite for Joomla! WYSIWYG Editor Plugin
 *
 * @author WebxSolution Ltd <andrew@webxsolution.com>
 * @package Editors
 * @since 1.5
 */
class plgEditorFckeditor extends JPlugin {

	/**
	 * Constructor
	 *
	 * For php4 compatability we must not use the __constructor as a constructor for plugins
	 * because func_get_args ( void ) returns a copy of all passed arguments NOT references.
	 * This causes problems with cross-referencing necessary for the observer design pattern.
	 *
	 * @param 	object $subject The object to observe
	 * @param 	array  $config  An array that holds the plugin configuration
	 * @since 1.5
	 */
	function plgEditorFckeditor(& $subject, $config) {
		parent::__construct($subject, $config);
	}

	/**
	 * Method to handle the onInitEditor event.
	 *  - Initializes the fckeditor Lite WYSIWYG Editor
	 *
	 * @access public
	 * @return string JavaScript Initialization string
	 * @since 1.5
	 */
	function onInit()
	{
  		return '<script type="text/javascript" src="'.JURI::root().'plugins/editors/fckeditor/fckeditor.js"></script>';
	}

	/**
	 * fckeditor Lite WYSIWYG Editor - get the editor content
	 *
	 * @param string 	The name of the editor
	 */
	function onGetContent( $editor ) {
			return " FCKeditorAPI.GetInstance('$editor').GetHTML(); ";
	}

	/**
	 * fckeditor Lite WYSIWYG Editor - set the editor content
	 *
	 * @param string 	The name of the editor
	 */
	function onSetContent( $editor, $html ) {
		return "oFCKeditor.InsertHtml = '". htmlentities($html) ."';";
	}

	/**
	 * fckeditor Lite WYSIWYG Editor - copy editor content to form field
	 *
	 * @param string 	The name of the editor
	 */
	function onSave( $editor ) { /* We do not need to test for anything */	}

	/**
	 * fckeditor Lite WYSIWYG Editor - display the editor
	 *
	 * @param string The name of the editor area
	 * @param string The content of the field
	 * @param string The name of the form field
	 * @param string The width of the editor area
	 * @param string The height of the editor area
	 * @param int The number of columns for the editor area
	 * @param int The number of rows for the editor area
	 * @param mixed Can be boolean or array.
	 */
	function onDisplay( $name, $content, $width, $height, $col, $row, $buttons = true )
	{
		// Load modal popup behavior
		JHTML::_('behavior.modal', 'a.modal-button');
		
		// Only add "px" to width and height if they are not given as a percentage
		if (is_numeric( $width )) {
			$width .= 'px';
		}
		if (is_numeric( $height )) {
			$height .= 'px';
		}

		jimport('joomla.environment.browser');
		$instance	=& JBrowser::getInstance();
		$language	=& JFactory::getLanguage();
		$db			=& JFactory::getDBO();
		
		

		if ($language->isRTL()) {
			$direction = 'rtl';
		} else {
			$direction = 'ltr';
		}
		
		/*
		 * Lets get the default template for the site application
		 */
		$query = 'SELECT template'
			. ' FROM #__templates_menu'
			. ' WHERE client_id = 0'
			. ' AND menuid = 0'
			;
		$db->setQuery( $query );
		$template = $db->loadResult();
		
		
		
		/* Load the FCK's Parameters */
		$toolbar 			=	$this->params->def( 'toolbar', 'Advanced' );
		$skin				= 	$this->params->def( 'skin', 'office2003' );
		$content_css		=	$this->params->def( 'content_css', 1 );
		$editor_css			=	$this->params->def( 'editor_css', 0 );
		$content_css_custom	=	$this->params->def( 'content_css_custom', '' );
		$imagePath			=	$this->params->def( 'imagePath', '/images/stories/' );
		$text_direction		=	$this->params->def( 'text_direction', 'ltr' );
		$wwidth				=   $this->params->def( 'wwidth', '100%' );
		$hheight			= 	$this->params->def( 'hheights', 480 );
		$lang_mode			= 	$this->params->def( 'lang_mode', 0 );
		$lang				= 	$this->params->def( 'lang_code', 'en' );
		$entermode = $this->params->def( 'entermode', 0 );
		$shiftentermode = $this->params->def( 'shiftentermode', 1 );
		$htmlentities = $this->params->def( 'htmlentities', 0 );
		$includelatinentities = $this->params->def( 'includelatinentities', 0 );
		$includegreekentities = $this->params->def( 'includegreekentities', 0 );
		$numericentities = $this->params->def( 'numericentities', 0 );

		/* Check on the users enteries to ensure that they are correct */
		$lastCharacter = substr( $imagePath, (strlen( $imagePath ) - 1), strlen($imagePath) );
		if( $lastCharacter != '/' && $lastCharacter != '\\' ){
			$imagePath .= '/';
		}//end if
		/* Check on the users enteries to ensure that they are correct */
		$firstCharacter = substr( $imagePath, 0, 1 );
		if( $firstCharacter != '/' && $firstCharacter != '\\' ){
			$imagePath = '/' . $imagePath;
		}//end if	
		/* Check to see if the path exists. */
		
		// initialise $error varable
		$errors = '';
	
		if( !is_dir( JPATH_SITE . $imagePath ) && $my->gid > $gid ){
			$errors .= '<span style="color: red;">Warning: ' . JPATH_SITE . $imagePath . ' does not appear to be a valid directory. Reverting to JoomlaFCK\'s default styles</span><br/>';
		}//end if
		
		
		
		/* Start setting up the XML files */
		$xml_path= JPATH_SITE."/plugins/editors/fckeditor/fckstyles_template.xml";
		$style_css="fckstyles_template.xml";

		if ( $content_css || $editor_css ) {
			if($editor_css !== 0 & $content_css == 0){
				if( is_file( JPATH_SITE . '/templates/'.$template.'/css/editor.css' ) ){
					$content_css = 'templates/'.$template.'/css/editor.css';
				} else {
					$errors .= '<span style="color: red;">Warning: ' . JPATH_SITE . '/templates/'.$template.'/css/editor.css' . ' does not appear to be a valid file. Reverting to JoomlaFCK\'s default styles</span><br/>';
				}//end if valid file
			} else {
				if( is_file( JPATH_SITE . '/templates/'.$template.'/css/template.css' ) ){
					$content_css = 'templates/'.$template.'/css/template.css';
				} else {
					$errors .= '<span style="color: red;">Warning: ' . JPATH_SITE . '/templates/'.$template.'/css/template.css' . ' does not appear to be a valid file. Reverting to JoomlaFCK\'s default styles</span><br/>';
				}//end if valid file
			}//end if  $editor_css !== 0 & $content_css == 0
	
			/* Is the content_css == 0 or 1 then use FCK's default */
			if( $errors !== "" ){
				$content_css = 'plugins/editors/fckeditor/editor/css/fck_editorarea.css';
			}//end if 
	
			/*write to xml file and read from css asnd store this file under editors*/
			$this->xml_writer( JPATH_SITE."/".$content_css, $xml_path );
	
		} else {
			if ( $content_css_custom ) {
	
				if( is_file( JPATH_SITE . '/' . $content_css_custom ) ){
					$content_css = $content_css_custom;
					$this->xml_writer(JPATH_SITE."/".$content_css,$xml_path);
					$style_css="fckstyles_template.xml";
				} else {
					$errors .= '<span style="color: red;">Warning: ' . JPATH_SITE . '/' .$content_css_custom . ' does not appear to be a valid file.</span><br/>';
					$content_css = 'plugins/editors/fckeditor/editor/css/fck_editorarea.css';
				}//end if valid file
					
			} else {
	
				$content_css = 'plugins/editors/fckeditor/editor/css/fck_editorarea.css';
	
			}//end if $content_css_custom
			/*write to xml file and read from css asnd store this file under editors*/
			$this->xml_writer( JPATH_SITE."/".$content_css, $xml_path );

		}//end if $content_css || $editor_css


        // If language mode set 
		

	    // set default Joomla language setting
		 switch ($lang_mode)
		 {
			 case 0:
				 $AutoDetectLanguage = 	0; // User selectiom
				 break;
			 case 1:
			 	$AutoDetectLanguage = 	0; // Joomla Default
				$lang = substr( $language->getTag(), 0, strpos( $language->getTag(), '-' ) ); //access joomlas global configuation and get the language setting from there
				break;
			 case 2:
			 	$AutoDetectLanguage = 	1; // Browser default
 				break; 
		 }
		 
		// Define Enter & Shift Enter Mode
		 $enterbehavior = array();
		 $enterbehavior[0] = 'br';
		 $enterbehavior[1] = 'p';
		 $enterbehavior[2] = 'div';

    // Define Entities
    $htmlentities	= $htmlentities ? 'true' : 'false';
    $includelatinentities	= $includelatinentities ? 'true' : 'false';
    $includegreekentities	= $includegreekentities ? 'true' : 'false';
    $numericentities	= $numericentities ? 'true' : 'false';

		/* Generate the Output */
		$html = '
		<textarea name="'.$name.'" id="'.$name.'" cols="75" rows="20" style="width:100%; height:350px;">'.$content.'</textarea>
		<script type="text/javascript">
			var oFCKeditor = new FCKeditor("'.$name.'");
			oFCKeditor.BasePath = "'.JURI::root() .'plugins/editors/fckeditor/" ;
			oFCKeditor.Config["CustomConfigurationsPath"] = "'.JURI::root() .'plugins/editors/fckconfigjoomla.js";
			oFCKeditor.ToolbarSet = "'.$toolbar.'" ;
      oFCKeditor.Config["EnterMode"] = "'.$enterbehavior[$entermode].'";
      oFCKeditor.Config["ShiftEnterMode"] = "'.$enterbehavior[$shiftentermode].'";
			oFCKeditor.Config["EditorAreaCSS"] = "'.JURI::root() .$content_css.'";
			oFCKeditor.Config["ContentLangDirection"] = "'.$direction.'" ;
			oFCKeditor.Config["AutoDetectLanguage"]  ="'. $AutoDetectLanguage .'";
			oFCKeditor.Config["DefaultLanguage"] = "'.$lang.'" ;
			oFCKeditor.Config["ProcessHTMLEntities"] = "'.$htmlentities.'" ;
			oFCKeditor.Config["IncludeLatinEntities"] = "'.$includelatinentities.'" ;
			oFCKeditor.Config["IncludeGreekEntities"] = "'.$includegreekentities.'" ;
			oFCKeditor.Config["ProcessNumericEntities"] = "'.$numericentities.'" ;
			oFCKeditor.Config["SkinPath"] = oFCKeditor.BasePath + "editor/skins/" + "'.$skin.'" + "/" ;
			oFCKeditor.Config["StylesXmlPath"]= "../'.$style_css.'";	
			oFCKeditor.Width = "'.$wwidth.'" ;
		/*	oFCKeditor.Style_css ="'.$style_css.'" ; */
			oFCKeditor.Height = "'.$hheight.'" ;
					
			function ReplaceTextHeader()
			{
				oFCKeditor.ReplaceTextarea();
			}
				
			function RenderEditor() 
			{
			 
			  if(navigator.userAgent.indexOf("MSIE 7") >= 0)
			  {
			    window.setTimeout(ReplaceTextHeader,5); // Force IE7 to render Editor last 
			  }
			  else
			  {
			  	 ReplaceTextHeader();
			  }	
			}
			
			/* oFCKeditor.ReplaceTextarea();*/
			RenderEditor(); 
		</script>
		';
		/* Add Joomla's Buttons */
		$html .= $this->_displayButtons($name, $buttons);

		if( $errors !== "" ){
			$html = $errors . $html;
		}//end if

		return $html;
	}
	
function xml_writer($txt_filename = "" ,$xml_filename = "")
 {
 	/* Due to the way the FCK editor works, we need to generate the XML file when the editor is loaded.
		TODO:
		To speed this up, it would be nice to check to see if the files have been changed since last time.
		If so run through this... */
	if( $txt_filename == 1 ){ return; }
	/* echo '<span style="color: green;">Writing: ' . $txt_filename . ' to: '. $xml_filename .'</span><br/>'; */
	/* When was the files last modified? */
	$xml_str="<?xml version=\"1.0\" encoding=\"utf-8\" ?>
				<Styles>";
	$f=file($txt_filename);
	$main=array();
	$elem=array();
	
	for($i=0;$i<count($f);$i++)
	{
		$mm=$f[$i];
		//for dot class
			if(preg_match("/^\./", $mm,$tt))
			{
			$x=explode("{",$mm);
			$xx=trim($x[0]);
			$pp=explode(",",$xx);
			foreach($pp as $val)
				{
				$ll=explode(" ",$val);
				$nn=substr($ll[0],1);
				if(!in_array($nn,$main) && $nn!="")
					{
					array_push($main,$nn);
					array_push($elem,"p");
					}
				}
			}//end dot
			//for div class
			elseif(preg_match("/^div\./", $mm))
			{
			$x=explode("{",$mm);
			$xx=trim($x[0]);
			$pp=explode(",",$xx);
			foreach($pp as $val)
				{
				$ll=explode(" ",$val);
				$nn=substr($ll[0],4);
				if(!in_array($nn,$main) && $nn!="")
					{
					array_push($main,$nn);
					array_push($elem,"div");
					}
				}
			}//end div
			//for img class
			elseif(preg_match("/^img\./", $mm))
			{
			$x=explode("{",$mm);
			$xx=trim($x[0]);
			$pp=explode(",",$xx);
			foreach($pp as $val)
				{
				$ll=explode(" ",$val);
				$nn=substr($ll[0],4);
				if(!in_array($nn,$main) && $nn!="")
					{
					array_push($main,$nn);
					array_push($elem,"img");
					}
				}
			}//end img
			//for span class
			elseif(preg_match("/^span\./", $mm))
			{
			$x=explode("{",$mm);
			$xx=trim($x[0]);
			$pp=explode(",",$xx);
			foreach($pp as $val)
				{
				$ll=explode(" ",$val);
				$nn=substr($ll[0],5);
				if(!in_array($nn,$main) && $nn!="")
					{
					array_push($main,$nn);
					array_push($elem,"span");
					}
				}
			}//end img
	
		}	
	
	
	if(count($main))
	{
		foreach($main as $k=>$val)
		{
			if($val !== "offline" ){
				$xml_str.='<Style name="'.$val.'" element="'.$elem[$k].'">
								<Attribute name="class" value="'.$val.'" />
							</Style>';	
				$xml_str.="\n";
			}//end if
		}//end for loop
	}//end count
		
	$xml_str.="\n"."</Styles>"; 
	$fp=fopen($xml_filename,"w");
	fwrite($fp,$xml_str);
	fclose($fp);
 }//end function
 
 	
	function onGetInsertMethod($name)
	{
		$doc = & JFactory::getDocument();
		$url = str_replace('administrator/', '', JURI::base() );
		$js= "function jInsertEditorText( text ) {
				var oEditor = FCKeditorAPI.GetInstance('$name') ;
				text = text.replace( /<img src=\"/, '<img src=\"".$url."' );
				oEditor.InsertHtml( text );
		}";
		$doc->addScriptDeclaration($js);

		return true;
	}

	function _getTemplateCss()
	{
		$db=& JFactory::getDBO();

		/*
		 * Lets get the default template for the site application
		 */
		$query = 'SELECT template'
		. ' FROM #__templates_menu'
		. ' WHERE client_id = 0'
		. ' AND menuid = 0'
		;
		$db->setQuery( $query );
		$template = $db->loadResult();

		$content_css = JURI::root() .'/templates/'. $template .'/css/';

		$file_path = JPATH_SITE .'/templates/'. $template .'/css/';
		if ( file_exists( $file_path .DS. 'editor.css' ) ) {
			$content_css = $content_css . 'editor.css' .'", ';
		} else {
			$content_css = $content_css . 'template_css.css", ';
		}

		return $content_css;
	}
	
	function _displayButtons($name, $buttons)
	{
		// Load modal popup behavior
		JHTML::_('behavior.modal', 'a.modal-button');

		$args['name'] = $name;
		$args['event'] = 'onGetInsertMethod';

		$return = '';
		$results[] = $this->update($args);
		foreach ($results as $result) {
			if (is_string($result) && trim($result)) {
				$return .= $result;
			}
		}

		if(!empty($buttons))
		{
			$results = $this->_subject->getButtons($name, $buttons);

			/*
			 * This will allow plugins to attach buttons or change the behavior on the fly using AJAX
			 */
			$return .= "\n<div id=\"editor-xtd-buttons\">\n";
			foreach ($results as $button)
			{
				/*
				 * Results should be an object
				 */
				if ( $button->get('name') ) 
				{
					$modal		= ($button->get('modal')) ? 'class="modal-button"' : null;
					$href		= ($button->get('link')) ? 'href="'.$button->get('link').'"' : null;
					$onclick	= ($button->get('onclick')) ? 'onclick="'.$button->get('onclick').'"' : null;
					$return .= "<div class=\"button2-left\"><div class=\"".$button->get('name')."\"><a ".$modal." title=\"".$button->get('text')."\" ".$href." ".$onclick." rel=\"".$button->get('options')."\">".$button->get('text')."</a></div></div>\n";
				}
			}
			$return .= "</div>\n";
		}
		
		return $return;
	}

}
?>