// Thought Junction Javascript Startup Engine.
// TJ specific startup code

if (!window.console || !console.firebug)
{
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

    window.console = {};
    for (var i = 0; i < names.length; ++i)
        window.console[names[i]] = function() {};
}
	Ext.namespace('TJ');

	Ext.BLANK_IMAGE_URL = '/lib/external/s.gif';  // 2.2

	Ext.Ajax.timeout = 15000;

	Ext.Ajax.on('requestexception',function(conn,res,opt){ console.log('ajax requestexception',conn,res,opt);});

	Ext.Ajax.extraParams={'__source__':'Ext'};

	Ext.onReady(function(){
		Ext.QuickTips.init();
	});

	TJ.HumanFileSize =  function(size){
		var units = ['B','KB','MB','GB','TB'];
		for(var i = 0; size > 1024; i++)
			size = size / 1024;
		return Math.round(size*10)/10 + ' ' + units[i];
	};

// TJ Components
// included in tj_comp_standard.js


if(! Ext.StatusBar)
	Ext.StatusBar = Ext.ux.StatusBar;


Ext.namespace('TJ.comp');

TJ.comp.OneLangRequired=function() {
		var sibling;
		if(this.langRequired) {
			for(var i=0; i<this.langRequired.langs.length; i++)
				{
					sibling = this.ownerCt.getForm().findField(this.langRequired.basename + '_' + this.langRequired.langs[i]);
					if(sibling){
						if(sibling.getValue().length > 0)
							return true;
					}
				}
			this.markInvalid('At least one language is required');
			return false;
		}
		return true;
	
};


TJ.comp.Select = Ext.extend(Ext.form.ComboBox,{
        typeAhead: true,
        mode: 'local',
        triggerAction: 'all',
        selectOnFocus:true,
		width: 300,
		minListWidth: 400,
	forceSelection: true,
		initComponent: function() {
	    	this.hiddenName = this.name;
			TJ.comp.Select.superclass.initComponent.call(this);
	}
});

Ext.reg('tjselect',TJ.comp.Select);

TJ.comp.CachedStores=[];

TJ.comp.Language = Ext.extend(Ext.form.ComboBox, {
	langdata: [
				['en', 'English'],
				['fr', 'French']
				],
	valueField: 'code',
	displayField:'lang',
	typeAhead: true,
	mode: 'local',
	triggerAction: 'all',
	emptyText:'Select a language...',
	forceSelection: true,
	selectOnFocus:true,
	initComponent:function() {
		 this.hiddenName = this.name;
		 delete this.maxLength;
		 this.store = new Ext.data.SimpleStore({
			fields: ['code','lang'],
			data: this.langdata
		 });
		 // call parent initComponent
		TJ.comp.Language.superclass.initComponent.call(this);
	this.on('specialkey',
		function(field,e){ if (e.getKey() == e.ENTER) {  
			field.fireEvent('dosubmit', field);
		}});
	 } // end of function initComponent
});
// register xtype
Ext.reg('tjlanguage',TJ.comp.Language);


// tjcombo xtype
	TJ.comp.ComboBoxCached = Ext.extend(Ext.form.ComboBox, {
//	TJ.comp.ComboBoxCached = Ext.extend(TJ.comp.ComboBoxTwin, {
		valueField: 'id',
    	displayField:'title',
		editable: true,
		mode: 'local',		// to start with
		triggerAction: 'all',
		forceSelection: true,
        selectOnFocus:true,

	 initComponent:function() {
    	this.hiddenName = this.name;
		
		if( ! TJ.comp.CachedStores[this.url]) {
			TJ.comp.CachedStores[this.url] = new Ext.data.JsonStore({
			url: this.url,
			root: 'rows',
			fields: [ { name: this.valueField
					},{ name: this.displayField
					}],
			remoteLoaded:false
		    });
		}

		this.store = TJ.comp.CachedStores[this.url];
		if((this.value) && (! this.store.remoteLoaded))
			this.store.loadData({"rows" :  [{"id": this.value,"title":this.displayValue||this.value}]},true);

//			this.store.on('load',function(store,rec){console.log('asdf'); this.setValue(this.value);},this);
//			this.store.load();

        TJ.comp.ComboBoxCached.superclass.initComponent.call(this);
    }, // end of function initComponent
	render: function(ct,pos){
		TJ.comp.ComboBoxCached.superclass.render.call(this,ct,pos);



	},
	doQuery: function(q,forceAll){
		if(!this.store.remoteLoaded){
			this.store.remoteLoaded=true;
			this.store.load({});
		}

		TJ.comp.ComboBoxCached.superclass.doQuery.call(this,q,forceAll);
	}
});

Ext.reg('tjcombo',TJ.comp.ComboBoxCached);

// tjapplication xtype
TJ.comp.Application = Ext.extend(TJ.comp.ComboBoxCached, {
		url : '/en/form:fieldapplication',
        emptyText:'Select an application...'
});
Ext.reg('tjapplication',TJ.comp.Application);

// tjtype xtype
TJ.comp.Type = Ext.extend(TJ.comp.ComboBoxCached, {
		url : '/en/form:fieldtype',
        emptyText:'Select a table type...'
});
Ext.reg('tjtype',TJ.comp.Type);


TJ.comp.ComboBoxTwin = Ext.extend(Ext.form.ComboBox, {
	   initComponent : function(){
	        TJ.comp.ComboBoxTwin.superclass.initComponent.call(this);

        this.triggerConfig = {
            tag:'span', cls:'x-form-twin-triggers', style:'padding-right:2px',  // padding needed to prevent IE from clipping 2nd trigger button
            cn:[
                {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger"},
                {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger x-form-search-trigger"}
               ]
           };
    },
    getTrigger : function(index){
        return this.triggers[index];
    },
	 initTrigger : function(){
        var ts = this.trigger.select('.x-form-trigger', true);
        this.wrap.setStyle('overflow', 'hidden');
        var triggerField = this;
        ts.each(function(t, all, index){
            t.hide = function(){
                var w = triggerField.wrap.getWidth();
                this.dom.style.display = 'none';
                triggerField.el.setWidth(w-triggerField.trigger.getWidth());
            };
            t.show = function(){
                var w = triggerField.wrap.getWidth();
                this.dom.style.display = '';
                triggerField.el.setWidth(w-triggerField.trigger.getWidth());
            };
            var triggerIndex = 'Trigger'+(index+1);

            if(this['hide'+triggerIndex]){
                t.dom.style.display = 'none';
            }
            t.on("click", this['on'+triggerIndex+'Click'], this, {preventDefault:true});
            t.addClassOnOver('x-form-trigger-over');
            t.addClassOnClick('x-form-trigger-click');
        }, this);
        this.triggers = ts.elements;
    },

    onTrigger1Click : function() {this.onTriggerClick();},   // pass to original combobox trigger handler
    onTrigger2Click : Ext.emptyFn             // clear contents of combobox

	});

// tjobject xtype
	TJ.comp.Object = Ext.extend(TJ.comp.ComboBoxTwin, {
		valueField: '_id',
		displayField: '_summary',
		editable: true,
		mode: 'remote',
		triggerAction: 'all',
		forceSelection: true,
		selectOnFocus: true,
		minChars: 1,
		width: 400,
		emptyText: '[Select a record]',
		zeroText: '[Record not selected]',
		tableField:null,

        tpl : '<tpl for="."><div class="x-combo-list-item">{_summary} [{_id}]</div></tpl>',

		setTableClass: function(table){
			this.setDisabled(true);
			this.store.proxy.conn.url='/en/form:fieldobject';
			TJ.CallbackManager.GetInfo({url: TJ.LANGUAGESS + 'admin/apps/content-' + table + ':gettableinfo2', 
										callback: this.tableInfoCallback,
										scope: this});

		},
		tableInfoCallback: function(val){
			this.tableinfo=val;

			if(val) {


				this.zeroText = this.initialConfig.zeroText ||  String.format('[{0} not selected]',val.lang.label);
//				this.zeroText = this.initialConfig.zeroText ||  String.format('[{0} not selected]',val.lang.label);

				this.initStore(this.tableinfo['class']);
				if(this.popupwindow) {
					this.popupwindow.destroy();
					this.popupwindow=null;
				}
				this.setDisabled(false);
			}

		},
   		initComponent: function() {
	
	    	this.hiddenName = this.name;
			this.popupwindow=null;

			this.store = new Ext.data.JsonStore({
				root: 'rows',
				fields: [  {name: '_id'
						},{name: '_summary'
						}],
				url:  '/en/form:fieldobject'
				});
			this.store.on('load',this.storeLoad,this);
			TJ.comp.Object.superclass.initComponent.call(this);		
		},
		initStore: function(table){
	            this.store.proxy.conn.url='/en/form-' + (table) +':fieldobject';

				delete this.lastQuery;
				if(this.value===0) {
					this.store.loadData({"rows" :  [{"_id": this.value,"_summary":this.zeroText}]});
				}
				else if (this.value>0) {
					this.store.loadData({"rows" :  [{"_id": this.value,"_summary":this.displayValue|| String.format("Record [{0}]",this.value)}]});
					this.getDisplayValue(this.value);
				}

		},
		render: function(pos,ct){
			this.disabled=true;
			if(this.table) {
				this.setTableClass(this.table);
			}
			else {
				if(this.tableField && this.fieldArray[this.tableField])
					this.tableFieldCmp=Ext.getCmp(this.fieldArray[this.tableField]);
				if(this.tableFieldCmp){
					this.tableFieldCmp.on('select',function(f){
						this.setValue(null);
						this.setTableClass(f.getValue());
					},this);
					this.setTableClass(this.tableFieldCmp.getValue());
				}
			}

			TJ.comp.Object.superclass.render.call(this,pos,ct);
		},
		storeLoad: function(store,records){
			if(this.allowZero)
				store.insert(0, new Ext.data.Record({_id: 0, _summary: this.zeroText}));
		},
	getDisplayValue: function(id){
//			console.log('getdisp',id);
		if(this.displayValue)
			return;
		this.displayValue=null;
//		if(this.displayValue!==null)			return;
		var options = {
						url: '/en/form-' + this.tableinfo['class'] +':fieldobject',
						scope: this,
						params: {id: id},
						callback:  this.callbackDisplayValue
		};
		Ext.Ajax.request(options);
	},
	callbackDisplayValue:function(options, success, response) {
		if(response.responseText) {
			var data = Ext.util.JSON.decode(response.responseText);
			if(data.rows[0]) {

				if (this.value == data.rows[0]._id)
					this.store.loadData({"rows" :  [{"_id": this.value,"_summary":data.rows[0]._summary}]});
					this.setValue(this.value);


			}
		}

	},

    validateValue : function(value){
        if(!TJ.comp.Object.superclass.validateValue.call(this, value)){
            return false;
        }
		if(this.value===0 && !this.allowZero) {
			this.markInvalid('You must select a ' + this.label);
			return false;
		}
        return true;
    },

		doQuery : function(q, forceAll){
			if(q.length <=1)
				this.mode='remote';
			TJ.comp.Object.superclass.doQuery.call(this,q,forceAll);
			if(q.length >= 1) {
				this.mode='local';
				this.queryDelay=10;
			}
			else
			{
				this.mode='remote';
				this.queryDelay=500;
			}
		},
		onRender: function(ct, position) {
			TJ.comp.Object.superclass.onRender.call(this,ct,position);				
		},
		setRecord: function(record){
		// extra handling to support setting value within property grid.
		if(this.propertyGrid && this.propertyGrid.selModel.selection)
			this.propertyGrid.selModel.selection.record.set('value',record._id);

			this.store.loadData({"rows" :  [{"_id": record._id,"_summary":record._summary}]});
			this.setValue(record._id);
			this.popupwindow.hide();
		},
		onTrigger2Click: function() {
			if(! this.tableinfo)
				return;
			console.log(this.tableinfo);
			if (! this.popupwindow) {
				this.popupwindow = new TJ.Admin.TableSelectWindow({tableinfo: this.tableinfo});
				this.popupwindow.on('recordselected',this.setRecord,this);
			}
			this.popupwindow.setSelectedId(this.value);
			this.popupwindow.show(this);
		}
});
Ext.reg('tjobject',TJ.comp.Object);

TJ.comp.ParentFilter = Ext.extend(TJ.comp.Object, {
		allowZero:true,
		value:0,
		zeroText: 'No Parent Selected',
		width: 250
});
Ext.reg('tjparentfilter',TJ.comp.ParentFilter);

TJ.comp.User = Ext.extend(TJ.comp.Object, {
	table: 'CL_User_Account_Table'
});

Ext.reg('tjuser',TJ.comp.User);




// Dates

TJ.comp.DateField = Ext.extend(Ext.form.DateField, {
	width: 100,
	format: 'Y-m-d',
	altFormats: 'Y-m-d'
});
Ext.reg('tjdate',TJ.comp.DateField);

TJ.comp.TimeField = Ext.extend(Ext.form.TimeField, {
	width: 100,
	format: 'G:i:s',
	altFormats: 'G:i:s'
});
Ext.reg('tjtime',TJ.comp.TimeField);


TJ.comp.DateTimeField = Ext.extend(Ext.ux.form.DateTime, {
	dateFormat: 'Y-m-d',
	dateConfig: {msgTarget: 'qtip'},
	timeFormat: 'G:i:s',
	timeConfig: {msgTarget: 'qtip'},
	format: 'Y-m-d H:i:s',
	validate: function(){
		this.updateHidden();
		return TJ.comp.DateTimeField.superclass.validate.call(this);
	},
	 initComponent:function() {
		 this.hiddenName = this.name;
         // call parent initComponent
        TJ.comp.DateTimeField.superclass.initComponent.call(this);
	}
});
Ext.reg('tjdatetime',TJ.comp.DateTimeField);

//TJ.comp.FloatField = Ext.extend(Ext.form.NumberField,{
//	allowDecimals: true
//});

TJ.comp.HumanUser = Ext.extend(Ext.form.TextField, {
	allowBlank: false,
	width: 200,
	maskRe:  /[a-zA-Z]/,
	minLength: 5,
	maxLength: 5,
    onRender : function(ct, position){
        Ext.form.TextField.superclass.onRender.call(this, ct, position);
        this.wrap = this.el.wrap({});
			this.wrap.createChild({tag:'br'});
            this.wrap.createChild( {
								tag: 'img',
								src: '/en/form:captcha'
			});
	}
});

Ext.reg('tjhumanuser',TJ.comp.HumanUser);









TJ.comp.HtmlPublic = Ext.extend(Ext.form.HtmlEditor, {
//		width: 600,
//		height: 200,
//		markInvalid:  Ext.form.HtmlEditor.superclass.markInvalid,
//		clearInvalid: Ext.form.HtmlEditor.superclass.clearInvalid,
		focus: function(){},
    validateValue : function(value){
		if(! TJ.comp.OneLangRequired.call(this)){
			return false;
		}
		return TJ.comp.HtmlPublic.superclass.validateValue.call(this, value);
		
    }

});

Ext.reg('tjhtmlpublic',TJ.comp.HtmlPublic);

TJ.comp.SelectFile= function () {
	var browser;

	return  {
		TinyMCE: function(field_name, url, type, win){		// Callback for TinyMCE File Manager
			this.Display(url,function(file) {
				win.document.getElementById(field_name).value='/'+file;
				if(win.ImageDialog){
			        if (win.ImageDialog.getImageData) win.ImageDialog.getImageData();
			        if (win.ImageDialog.showPreviewImage) win.ImageDialog.showPreviewImage('/'+file);
				}
			
				});

		},
		Display: function(initialValue,callback){
			if(!browser) {
				browser=new TJ.Admin.FileSelectWindow({initialValue: initialValue});
			}
			browser.show(callback);
		}
	};


}(); // the parens here cause the anonymous function to execute and return




TJ.comp.HtmlTinyMCE = Ext.extend(Ext.ux.TinyMCE,{
	initComponent: function(){
	this.tinymceSettings={	theme:"advanced",
						plugins:"safari,pagebreak,style,layer,table,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,noneditable,visualchars,nonbreaking,xhtmlxtras,template",
//						theme_advanced_styles:"Heading=heading;Sub Heading=subheading;Title=title;Text=text;Description=description;Small=small;Error=error",
						content_css: TJ.EDITORCSS,
						body_class: 'yui-cssbase',
						theme_advanced_buttons1:"bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",
						theme_advanced_buttons2:"cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
						theme_advanced_buttons3:"tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|",
						theme_advanced_buttons4:"insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak",
						theme_advanced_toolbar_location:"top",
						forced_root_block : false,
						theme_advanced_toolbar_align:"left","theme_advanced_statusbar_location":"bottom",
						theme_advanced_resizing:false,
					    theme_advanced_source_editor_width : 500,
					    theme_advanced_source_editor_height : 400,
						relative_urls:false,
//						convert_urls : false,
						extended_valid_elements:"a[class|name|href|target|title|onclick],img[style|class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],div[id|class|align|style],span[class|align|style]",
						file_browser_callback : 'TJ.comp.SelectFile.TinyMCE'
						};

		TJ.comp.HtmlTinyMCE.superclass.initComponent.call(this);
	},
	width:  720,
	height: 240
		,
    validateValue : function(value){
		if(! TJ.comp.OneLangRequired.call(this)){
			return false;
		}
		return TJ.comp.HtmlTinyMCE.superclass.validateValue.call(this, value);
		
    }
});
//"width":720,"height":300,"tinymceSettings":{"theme":"advanced","plugins":"safari,pagebreak,style,layer,table,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,noneditable,visualchars,nonbreaking,xhtmlxtras,template","theme_advanced_styles":"Heading=heading;Sub Heading=subheading;Title=title;Text=text;Description=description;Small=small;Error=error","theme_advanced_buttons1":"bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect","theme_advanced_buttons2":"cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor","theme_advanced_buttons3":"tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|","theme_advanced_buttons4":"insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak","theme_advanced_toolbar_location":"top","theme_advanced_toolbar_align":"left","theme_advanced_statusbar_location":"bottom","theme_advanced_resizing":false,"relative_urls":false,"extended_valid_elements":"a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]"}   


Ext.reg('tjtinymce',TJ.comp.HtmlTinyMCE);

TJ.comp.HtmlTinyMCESimple = Ext.extend(Ext.ux.TinyMCE,{
	initComponent: function(){
	this.tinymceSettings={	theme:"advanced",
						plugins:"style,advimage,advlink,iespell,preview,searchreplace,paste,nonbreaking",
						theme_advanced_styles:"Heading=heading;Sub Heading=subheading;Title=title;Text=text;Description=description;Small=small;Error=error",
						theme_advanced_buttons1:"bold,italic,underline,strikethrough,|,styleselect,formatselect,fontselect,fontsizeselect,sub,sup,|,charmap,|,nonbreaking",
						theme_advanced_buttons2:"cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,forecolor,backcolor",
						theme_advanced_buttons3:"",
						theme_advanced_buttons4:"",
						theme_advanced_toolbar_location:"top",
						theme_advanced_toolbar_align:"left",
						theme_advanced_resizing:false,
						relative_urls:false,
						convert_urls : false,
						extended_valid_elements:"a[name|href|target|title|onclick],img[style|class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]",
						file_browser_callback : 'TJ.comp.SelectFile.TinyMCE'
					};

		TJ.comp.HtmlTinyMCE.superclass.initComponent.call(this);
	},
	width:  580,
	height: 200
});

Ext.reg('tjtinymcesimple',TJ.comp.HtmlTinyMCESimple);






// Color field

TJ.comp.Color = Ext.extend(Ext.form.TriggerField, {
	invalidText : 'This is not a valid color - it must be in a the hex format "#1A2B3C"',
    defaultAutoCreate : {tag: "input", type: "text", size: "10", maxlength: "7", autocomplete: "off"},
    // Limit input to hex values
	maskRe: /[#a-f0-9]/i,
	regex: /^#([a-f0-9]{3}|[a-f0-9]{6})$/i,
    // private

	markInvalid: function(){
		this.el.setStyle({
			'background-color': '#FFF',
			'background-image': 'none',
			'color'			  : '000'
		});
		TJ.comp.Color.superclass.markInvalid.apply(this,arguments);
	},
    validateValue : function(value){
        if(!TJ.comp.Color.superclass.validateValue.call(this, value)){
            return false;
        }
        if(value.length < 1){ // if it's blank and textfield didn't flag it then it's valid
             return true;
        }

        var parseOK = this.parseColor(value);

        if(!value || (parseOK === false)){
            this.markInvalid(String.format(this.invalidText, value, '#AABBCC'));
            return false;
        }
        var    bgColorBr = this.hex2rgb(value);
        fgColor = ((bgColorBr.R * 299) + (bgColorBr.G * 587) + (bgColorBr.B * 114)) / 1000 - 125 < 0 ? "#FFF" : "#000"; 
        
        this.el.setStyle({
            'background-color': value,
            'background-image': 'none',
            'color' : fgColor
        });

        return true;
    },
    // private
    // Provides logic to override the default TriggerField.validateBlur which just returns true
    validateBlur : function(){
        return !this.menu || !this.menu.isVisible();
    },

    /**
     * Returns the current value of the color field
     * @return {String} value The color value
     */
    getValue : function(){
        return TJ.comp.Color.superclass.getValue.call(this) || "";
    },

    /**
     * Sets the value of the color field.  You can pass a string that can be parsed into a valid HTML color
     * <br />Usage:
     * <pre><code>
		colorField.setValue('#FFFFFF');
       </code></pre>
     * @param {String} color The color string
     */
    setValue : function(color){
        TJ.comp.Color.superclass.setValue.call(this, this.formatColor(color));


    },
// private
    hex2dec: function(hexchar) {
        return "0123456789ABCDEF".indexOf(hexchar.toUpperCase());
    },
    // private
    hex2rgb: function(color) { 
        color = color.replace("#", "");
        return {
            R : (this.hex2dec(color.substr(0, 1)) * 16) + this.hex2dec(color.substr(1, 1)),
            G : (this.hex2dec(color.substr(2, 1)) * 16) + this.hex2dec(color.substr(3, 1)),
            B : (this.hex2dec(color.substr(4, 1)) * 16) + this.hex2dec(color.substr(5, 1))
        };
    },

    // private
    parseColor : function(value){
	return (!value || (value.substring(0,1) != '#')) ?
		false : true;
    },

    // private
    formatColor : function(value){
	if (value && (value.substring(0,1) != '#')) {
		value = '#' + value;
	}
//	console.log('format' + value);
        return value;
    },

    // private
    menuListeners : {
        select: function(e, c){
//			console.log(c);
            this.setValue(c);
        },
        show : function(){ // retain focus styling
            this.onFocus();
        },
        hide : function(){
            this.focus();
            var ml = this.menuListeners;
            this.menu.un("select", ml.select,  this);
            this.menu.un("show", ml.show,  this);
            this.menu.un("hide", ml.hide,  this);
        }
    },

    // private
    // Implements the default empty TriggerField.onTriggerClick function to display the ColorPalette
    onTriggerClick : function(){
        if(this.disabled){
            return;
        }
        if(this.menu === null){
            this.menu = new Ext.menu.ColorMenu();
			this.menu.palette.on('render',function(){ this.el.setWidth(325);});
			this.menu.palette.colors= 
			[
			"000000","000033","000066","000099","0000CC","0000FF","330000","330033",
			"330066","330099","3300CC","3300FF","660000","660033","660066","660099",
			"6600CC","6600FF","990000","990033","990066","990099","9900CC","9900FF",
			"CC0000","CC0033","CC0066","CC0099","CC00CC","CC00FF","FF0000","FF0033",
			"FF0066","FF0099","FF00CC","FF00FF","003300","003333","003366","003399",
			"0033CC","0033FF","333300","333333","333366","333399","3333CC","3333FF",
			"663300","663333","663366","663399","6633CC","6633FF","993300","993333",
			"993366","993399","9933CC","9933FF","CC3300","CC3333","CC3366","CC3399",
			"CC33CC","CC33FF","FF3300","FF3333","FF3366","FF3399","FF33CC","FF33FF",
			"006600","006633","006666","006699","0066CC","0066FF","336600","336633",
			"336666","336699","3366CC","3366FF","666600","666633","666666","666699",
			"6666CC","6666FF","996600","996633","996666","996699","9966CC","9966FF",
			"CC6600","CC6633","CC6666","CC6699","CC66CC","CC66FF","FF6600","FF6633",
			"FF6666","FF6699","FF66CC","FF66FF","009900","009933","009966","009999",
			"0099CC","0099FF","339900","339933","339966","339999","3399CC","3399FF",
			"669900","669933","669966","669999","6699CC","6699FF","999900","999933",
			"999966","999999","9999CC","9999FF","CC9900","CC9933","CC9966","CC9999",
			"CC99CC","CC99FF","FF9900","FF9933","FF9966","FF9999","FF99CC","FF99FF",
			"00CC00","00CC33","00CC66","00CC99","00CCCC","00CCFF","33CC00","33CC33",
			"33CC66","33CC99","33CCCC","33CCFF","66CC00","66CC33","66CC66","66CC99",
			"66CCCC","66CCFF","99CC00","99CC33","99CC66","99CC99","99CCCC","99CCFF",
			"CCCC00","CCCC33","CCCC66","CCCC99","CCCCCC","CCCCFF","FFCC00","FFCC33",
			"FFCC66","FFCC99","FFCCCC","FFCCFF","00FF00","00FF33","00FF66","00FF99",
			"00FFCC","00FFFF","33FF00","33FF33","33FF66","33FF99","33FFCC","33FFFF",
			"66FF00","66FF33","66FF66","66FF99","66FFCC","66FFFF","99FF00","99FF33",
			"99FF66","99FF99","99FFCC","99FFFF","CCFF00","CCFF33","CCFF66","CCFF99",
			"CCFFCC","CCFFFF","FFFF00","FFFF33","FFFF66","FFFF99","FFFFCC","FFFFFF"
			];
        }

        this.menu.on(Ext.apply({}, this.menuListeners, {
            scope:this
        }));

        this.menu.show(this.el, "tl-bl?");
    }



});

Ext.reg('tjcolor',TJ.comp.Color);

TJ.comp.File = Ext.extend(Ext.form.TriggerField, {
	width: 400,
    triggerClass : 'x-form-search-trigger',
	browse: null,
	selectMode: 'single',
    onTriggerClick : function() {
		if (!this.browse) {
			//	win2.on('select',function(f){console.log('File selected: ',f); this.hide();},win2);
			//	this.browse = new TJ.comp.DirFileBrowserWindow({initialValue: this.value, selectMode: this.selectMode, title: 'Select File'});
			this.browse = new TJ.Admin.FileSelectWindow({initialValue: this.getValue(),title: 'Select File'});
			this.browse.on('select',function(file){
				if(this.propertyGrid && this.propertyGrid.selModel.selection)
					this.propertyGrid.selModel.selection.record.set('value','/'+file);

					this.setValue('/'+file);
					this.browse.hide();
				},this);
			}
		this.browse.show();
	}  ,
	onDestroy : function() {
		if(this.browse) {
			this.browse.destroy();
			this.browse=null;
		}
	}

});

Ext.reg('tjfile',TJ.comp.File);


TJ.comp.Directory = Ext.extend(Ext.form.TriggerField,{
	width: 300,
    triggerClass : 'x-form-search-trigger',
	browse: null,
    onTriggerClick : function() {
		if(!this.browse) {
//			console.log('value',this.getValue());
			this.browse = new TJ.Admin.DirectorySelectWindow({initialDir: this.getValue(), title: 'Select Directory'});
//			this.browse = new TJ.comp.DirBrowserWindow({initialDir: this.value, selectMode: this.selectMode, title: 'Select Directory'});
			this.browse.on('select',function(dir){
					this.setValue(dir);
					this.browse.hide();
				},this);
		}
		this.browse.show();
	},
	onDestroy : function() {
		if(this.browse) {
			this.browse.destroy();
			this.browse=null;
		}
	}

});
Ext.reg('tjdirectory',TJ.comp.Directory);


//TJ.comp.

// override for Ext.Editor.
// Fixes error in destroying EditGridPanel within closeable tab.
Ext.override(Ext.Editor, {
    beforeDestroy : function(){
        Ext.destroy(this.field);
        this.field = null;
    }
});

// override for Ext.grid.GridPanel  Ext 2.2.1
// Fixes state restore within border layouts.



Ext.grid.GridPanel.prototype.applyState = Ext.grid.GridPanel.prototype.applyState.createSequence(
	function(state) {
		delete state.columns;
		delete state.sort;
		Ext.grid.GridPanel.superclass.applyState.call(this,state);
	}
);




TJ.clone = function (obj){    
	if(obj === null || typeof(obj) != 'object')        
		return obj;    
	var temp = obj.constructor(); // changed    
	for(var key in obj)        
		temp[key] = TJ.clone(obj[key]);    
	return temp;
};




TJ.removeHTMLTags = function(text) {
	var strInputCode = new String(text);
	/*
	This line is optional, it replaces escaped brackets with real ones,
	i.e. < is replaced with < and > is replaced with >
	*/
	strInputCode = strInputCode.replace(/&(lt|gt);/g, function (strMatch, p1) {
		return (p1 == "lt")? "<" : ">";
	});
 
	var strTagStrippedText = strInputCode.replace(/<\/?[^>]+(>|$)/g, "");
	//alert(”Output text:\n” + strTagStrippedText);
	// Use the alert below if you want to show the input and the output text
	// alert(”Input code:\n” + strInputCode + “\n\nOutput text:\n” + strTagStrippedText);
	return strTagStrippedText;
};

TJ.nl2br =function(str, is_xhtml) {
    // Converts newlines to HTML line breaks  
    // 
    // version: 903.3016
    // discuss at: http://phpjs.org/functions/nl2br
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Philip Peterson
    // +   improved by: Onno Marsman
    // +   improved by: Atli Þór
    // +   bugfixed by: Onno Marsman
    // +      input by: Brett Zamir (http://brettz9.blogspot.com)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: nl2br('Kevin\nvan\nZonneveld');
    // *     returns 1: 'Kevin<br />\nvan<br />\nZonneveld'
    // *     example 2: nl2br("\nOne\nTwo\n\nThree\n", false);
    // *     returns 2: '<br>\nOne<br>\nTwo<br>\n<br>\nThree<br>\n'
    // *     example 3: nl2br("\nOne\nTwo\n\nThree\n", true);
    // *     returns 3: '<br />\nOne<br />\nTwo<br />\n<br />\nThree<br />\n'
    var breakTag = '';

    breakTag = '<br />';
    if (typeof is_xhtml != 'undefined' && !is_xhtml) {
        breakTag = '<br>';
    }

    return (str + '').replace(/([^>]?)\n/g, '$1'+ breakTag +'\n');
};

TJ.GetIDList=function(selectionModel) {
	recs = selectionModel.getSelections();
	params=new Array();
	for(var i=0; i < recs.length;i++)
		params[i]=recs[i].data._id;
	return params.join(',');
};

/// ExtJS Session State provider
/// 

Ext.state.SessionProvider = Ext.extend(Ext.state.CookieProvider, {
    readCookies : function(){
        if(this.state){
            for(var k in this.state){
                if(typeof this.state[k] == 'string'){
                    this.state[k] = this.decodeValue(escape(this.state[k]));
                }
            }
        }
        return Ext.apply(this.state || {}, Ext.state.SessionProvider.superclass.readCookies.call(this));
    }
});

// override for tree editor
// see bug report:  http://extjs.com/forum/showthread.php?t=54609

Ext.override(Ext.tree.TreeEditor, {
	triggerEdit: function(node, defer){
		this.completeEdit();
		if (node.attributes.editable !== false) {
			this.editNode = node;
			if (this.tree.autoScroll) {
				Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body);
			}
			this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, node.text]);
			return false;
		}
	}
});

TJ.IE6BoxFix=function(){
return;
//	alert(Ext.isIE6);
//	if(Ext.isIE6) {
		headers = Ext.select('div.hd > div.c');


		headers.each(function(e){
			console.log(e.getStyle('background-image'));
			parent = e.parent();
			parent.setWidth(parent.getWidth());
			console.log(parent);

			e.createChild({tag:'img',style:'border: 1px solid red; float: right;', src:e.getStyle('background-image').substring(4,e.getStyle('background-image').length-1)});
//			e.setWidth(e.getWidth()+20);
			e.setStyle('background','none');
		});

//		headers.each(function(e){e.createChild({tag:'img', style:'float: right; border: 1px solid red; display: block;', src:'/lib/activecircle.ca/css/cells/orangebox-tr-bg.png'});});

//		http://local.activecircle.ca/lib/activecircle.ca/css/cells/orangebox-tr-bg.png
		headers.each(function(e){console.log(e);});
//		headers.each(function(e){e.innerHTML='a';});
		//console.log(headers);
//		if (supersleight && supersleight.init) {
//			supersleight.init();
//			document.write(supersleight);

//		}
//	}
		return;

		temp.total=temp.topnav.getWidth();

		temp.items = Ext.select('ul.AC_TopNav li');

		temp.items.each(function(e) { temp.total = temp.total - e.getWidth();});

		temp.filler = Ext.select('ul.AC_TopNav li.filler',true).first();
		temp.filler.setWidth(temp.filler.getWidth()+temp.total);


};


// Callback Manager

TJ.CallbackManager = function (){
	var cache={};
	var callbacks={};
	var requests={};
	var storeTo={};


	var getCallback =  function(options,success,response){
		if(true===success){
			var res = Ext.util.JSON.decode(response.responseText);
			TJ.Admin.ProcessStandardResponse(res);
			cache[options.opt.url]=res.data;
		} else {
			cache[options.opt.url]=null;
		}
			
		if(callbacks[options.opt.url]) {
			while(callbacks[options.opt.url].length){
				cb=callbacks[options.opt.url].pop();
				cb.callback.call(cb.scope||this,cache[options.opt.url]);
			}
		}
	};

	var executeCallback = function(options,success,response){
		if(true===success){
			var res = Ext.util.JSON.decode(response.responseText);
			TJ.Admin.ProcessStandardResponse(res);

			if(options.opt.callback)
				options.opt.callback.call(options.opt.scope||this,res.data,res);


		}

	};




	return {
		// always send this.  
		// url:  
		// callback
		// scope
		Execute: function(opt) {
//			console.log('options',opt);

			Ext.Ajax.request( {
				 url: opt.url,
				 opt: opt,
				 callback: executeCallback
						});






		},
		// options:
		// url:			used for cacheing
		// callback:	when complete
		// scope:		
		// refresh:     default false
		// standard process: default true
		GetInfo: function(opt){
			opt = Ext.apply({refresh: false, standard: true},opt);

			// check if value in cache
			if(! opt.refresh) {
				if(cache[opt.url]) {
					if(opt.callback) {
						opt.callback.call(opt.scope||this,cache[opt.url]);
					}
					return;
				}
			}

			// store callback
			if(opt.callback){
				if(! callbacks[opt.url]){ // create callback array
					callbacks[opt.url]=[];
				}
				// store callback.
				callbacks[opt.url].push( {	callback: opt.callback,	scope: opt.scope});	
			}

			// check if in progress
			if(requests[opt.url] && requests[opt.url]['conn']){
				return;
			}


			//request
			requests[opt.url] = 
					Ext.Ajax.request( {
						 url: opt.url,
						 opt: opt,
 						 callback: getCallback
						});
		}







	};



}();