/*
 * CodePress - Real Time Syntax Highlighting Editor written in JavaScript - http://codepress.fermads.net/
 * 
 * Copyright (C) 2006 Fernando M.A.d.S. <fermads@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the 
 * GNU Lesser General Public License as published by the Free Software Foundation.
 * 
 * Read the full licence: http://www.opensource.org/licenses/lgpl-license.php
 */
var CodePress = Class.create();
CodePress.cpPath = $('cp-script').src.replace('codepress.js','');
document.write('<link type="text/css" href="'+CodePress.cpPath+'themes/default/codepress-editor.css" rel="stylesheet" />');
CodePress.cpEngine = "older";
CodePress.detect = function(){
  CodePress.cpEngine = 'older';
	var ua = navigator.userAgent;
	if(ua.match('MSIE')) CodePress.cpEngine = 'msie';
	else if(ua.match('KHTML')) CodePress.cpEngine = 'khtml'; 
	else if(ua.match('Opera')) CodePress.cpEngine = 'opera'; 
	else if(ua.match('Gecko')) CodePress.cpEngine = 'gecko';
}
CodePress.loadScript = function(target, src, callback) {
	var node = target.createElement("script");
	if (node.addEventListener) node.addEventListener("load", callback, false);
	else node.onreadystatechange = function() { if (this.readyState == "loaded") { callback.call(this);} }
	node.src = src;
	target.getElementsByTagName("head").item(0).appendChild(node);
	node = null;
}
CodePress.attach = function(element){
  Object.extend(element, new CodePress());
  if(!element.className.match(/\wcp\w/)) element.className += " cp";
  return element;
}

CodePress.prototype = {
	initialize : function(){},//Constructor
  observers: new Array(),
  load : function() {
    this.cpBody = this.cpEditor.contentWindow;
		this.cpBody.CodePress.syntaxHighlight('init');
		if(this.onLoadEdit) { this.onLoadEdit = false; this.edit(this.fileName, this.pgCode); }
	},
	setFileName : function() {
		this.cpFilename.innerHTML = this.fileName = (arguments[0]) ? arguments[0] : Content.menu.untitledFile;
	},
  getFileName : function(){
    return this.cpFilename.innerHTML;
  },
	getLanguage : function() {
		var extension = this.fileName.replace(/.*\.([^\.]+)$/,'$1');
		for(lang in Content.languages) {
			extensions = ','+Content.languages[lang].extensions+',';
			if(extensions.match(','+extension+',')) return lang;
		}
		return 'generic';
	},

	loadScript : function(target, src, callback) {
		var node = target.createElement("script");
		if (node.addEventListener) node.addEventListener("load", callback, false);
		else node.onreadystatechange = function() { if (this.readyState == "loaded") { callback.call(this);} }
		node.src = src;
		target.getElementsByTagName("head").item(0).appendChild(node);
		node = null;
	},
	
	setLanguage : function(reload) {
    //alert(this.cpEditor.tagName);
    //this.cpBody = this.getElementsByTagName("iframe")[0].contentWindow;
    this.language = (typeof(Content.languages[arguments[0]])!='undefined') ? arguments[0] : this.getLanguage();
		this.cpLanguageName.innerHTML = Content.languages[this.language].name;
		document.getElementsByClassName('language-'+this.language, this)[0].checked = true;
		this.hideAllMenu();
		if(reload) {
      var _this = this;
      if(this.cpBody.document.designMode=='on') this.cpBody.document.designMode = 'off';
			CodePress.loadScript(this.cpBody.document, CodePress.cpPath+'languages/'+this.language+'.js', function () { _this.cpBody.CodePress.syntaxHighlight('init'); })
      this.cpBody.document.getElementById('cp-lang-style').href = CodePress.cpPath+'languages/'+this.language+'.css';
		}
	},
	
	hideAllMenu : function() {
		this.cpMenus.each(
		  function(menu){
		    menu.removeClassName("show");
		    menu.addClassName("hide");
		    menu.arrow.src = CodePress.cpPath+'themes/default/menu-arrow-up.gif';
		  }
		);		
	},
	
	toogleMenu : function(menuIndex) {
		var menu = this.cpMenus[menuIndex];
		var arrowImage = menu.arrow;
    if(menu.hasClassName("show")){
      menu.className = menu.className.replace(/show/, "hide");
      arrowImage.src = CodePress.cpPath+'themes/default/menu-arrow-down.gif';
    }else{
      menu.className = menu.className.replace(/hide/, "show");
      arrowImage.src = CodePress.cpPath+'themes/default/menu-arrow-up.gif';
    }
	},
	
	toggleComplete : function(element) {
		this.complete = element.checked ? true : false ;
		this.hideAllMenu();
	},

	toggleLineNumbers : function(element) {
	  this.cpBody.document.getElementsByTagName('body')[0].className = (element.checked) ? 'show-line-numbers' : 'hide-line-numbers';
		this.hideAllMenu();
	},
	edit : function() {
		this.setFileName(arguments[0]);
		if(!arguments[1]||arguments[1]=='') { // file name of the source code (to open from server)
			this.setLanguage();
			this.cpEditor.src = cpPath+'modules/codepress.php?action=edit&file='+this.fileName+'&language='+this.language+'&engine='+CodePress.cpEngine
			return;
		}
		this.setLanguage('reload');
		if($(arguments[1])) this.setCode($(arguments[1]).firstChild.nodeValue); // id name of the source code
		else if(arguments[1].match(/\w/)) this.setCode(arguments[1]);  // text of the source code
		else if(typeof(arguments[1])=='Object') this.setCode(arguments[1].firstChild.nodeValue); // object of the source code
	},
  setDirty : function(isDirty){
    if(isDirty){
      this.setFileName("*"+this.getFileName().replace(/^\*/, ""));
    }else{
      this.setFileName(this.getFileName().replace(/^\*/, ""));
    }
  },
  isDirty : function(){
    return this.getFileName().match(/^\*/);
  },
	setContent : function() {
		var allLanguages = '';
    for(lang in Content.languages){
			allLanguages += '<input type=radio name=lang class="language-'+lang+'" onclick="$(\''+this.id+'\').setLanguage(\''+lang+'\')"><label for="language-'+lang+'">'+Content.languages[lang].name+'</label><br />';
		}
		
		this.pgCode = (this.firstChild) ? this.firstChild.nodeValue : '';
		this.fileName = this.title;
		this.language = this.getLanguage();
		this.complete = true;
		this.onLoadEdit = (this.pgCode.match(/\w/)) ? true : false ;
    
		this.cpWindowHeight = this.clientHeight;
		this.cpEditorHeight = (this.className.match('hideMenu')) ? this.cpWindowHeight : this.cpWindowHeight-20 ;
		if(this.cpWindowHeight==0) { setTimeout(function(){this.setContent();},10); return; } // if css is not loaded yet, try again
		var host = this.getAttribute('host');    
    var src = "FileManager/OpenCodePress.php?id="+this.id;
    if(host) src += "&host="+host;
    src += "&engine="+CodePress.cpEngine+"&filePath="+encodeURIComponent(this.fileName)+"&language="+this.language;
    
    this.innerHTML = '<div class="cp-window">'+
			'<iframe class="cp-editor" src="'+src+'" style="height:'+ this.cpEditorHeight +'px"></iframe>'+
      '<div class="cp-menu">'+
				  '<em class="cp-filename"></em>'+
          '<span class="cp-options" title="Editor Options" onclick="$(\''+this.id+'\').toogleMenu(0)"><img src="'+CodePress.cpPath+'themes/default/menu-icon-options.gif" align="top" /> '+Content.menu.options+' <img src="'+CodePress.cpPath+'themes/default/menu-arrow-up.gif" align="top" class="cp-arrow-options" /></span>'+
          '<span class="cp-language" title="Language Options" onclick="$(\''+this.id+'\').toogleMenu(1)"><img src="'+CodePress.cpPath+'themes/default/menu-icon-languages.gif" align="top" /> <span class="cp-language-name">'+Content.languages.generic.name+'</span> <img src="'+CodePress.cpPath+'themes/default/menu-arrow-up.gif" align=top class="cp-arrow-languages" /></span>'+
          '<span class="cp-saveButton" title="Save" onClick="$(\''+this.id+'\').save();">&nbsp;</span>'+
			'</div>'+
			'<div class="cp-options-menu hide">'+
    			'<input type=checkbox onclick="$(\''+this.id+'\').toggleLineNumbers(this)" checked="checked"><label>'+Content.menu.lineNumbers+'</label><br><input type=checkbox onclick="$(\''+this.id+'\').toggleComplete(this)" checked="checked"><label>'+Content.menu.autoComplete+'</label>'+
			'</div>'+
			'<div class="cp-languages-menu hide">'+allLanguages+'</div>'+
		'</div>';
		
    var _this = this;
		var $C = function(className){
      return document.getElementsByClassName(className, _this)[0];
		}
		this.cpWindow = $C('cp-window');
		this.cpEditor = $C('cp-editor');
		this.cpMenu = $C('cp-menu');
    this.cpFilename = $C('cp-filename');
		this.cpOptions = $C('cp-options');
		this.cpLanguage = $C('cp-language');
    this.cpMenus = new Array();
    this.cpMenus.push($C('cp-options-menu'));
    this.cpMenus[0].arrow = $C('cp-arrow-options');
    this.cpMenus.push($C('cp-languages-menu'));
    this.cpMenus[1].arrow = $C('cp-arrow-languages');
		this.cpLanguageName = $C('cp-language-name');
		
		this.setLanguage(); 
		this.setFileName(this.fileName.replace(new RegExp(".*\/", "g"), "")); 
	},

	// transform syntax highlighted code to original code
	getCode : function() {
		var code = this.cpBody.editor.innerHTML;
		code = code.replace(/<br>/g,'\n');
		code = code.replace(/<\/p>/gi,'\r');
		code = code.replace(/<p>/i,''); // IE first line fix
		code = code.replace(/<p>/gi,'\n');
		code = code.replace(/&nbsp;/gi,'');
		code = code.replace(/\u2009/g,'');
		code = code.replace(/<.*?>/g,'');
		code = code.replace(/&lt;/g,'<');
		code = code.replace(/&gt;/g,'>');
		code = code.replace(/&amp;/gi,'&');
		return code;
	},

	// put some code inside editor
	setCode : function() {
		var code = arguments[0];
		code = code.replace(/\u2009/gi,'');
		code = code.replace(/&/gi,'&amp;');		
    code = code.replace(/</g,'&lt;');
    code = code.replace(/>/g,'&gt;');
		this.cpBody.document.getElementById("code").innerHTML = "<pre>"+code+"</pre>";
	}, 
	
	updateSize : function(window){
	  if(!window) return false;
	  //$(windowId).style.overflow = "auto";
	  var size = window.getSize();
    var height = size.height - 2;
    var width = size.width - 2;
    this.cpWindow.style.height = height+"px";
    this.cpWindow.style.width = width+"px";
    this.cpEditor.style.height = (height - 28)+"px";
    this.cpEditor.style.width = (width)+"px";
	},
	
	save : function(){
    this.notify("onSave");
	},
	addObserver: function(o){
	 this.observers.push(o);
	},
	notify: function(event){
	 var _this = this;
   return this.observers.collect(
	   function(o){
	     if(o[event]) return o[event](_this);
	     return true;
	   }
	 );
	}
}

CodePress.detect();
Content={};
CodePress.loadScript(document, CodePress.cpPath+'content/'+$('cp-script').lang+'.js', function() { return;});
