// Copyright 2008 ProjectWizards GmbH. All rights reserved.

//console.log("TableColumns.js");
// ************************* TableColumn ***********************
var inputHeight = "14px";
var fontSize = "11px";

var TableColumn = Base.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
		this.className = "TableColumn";
        this.title = aTitle;
        this.shortTitle = aShortTitle;
        this.key = aKey;
        this.width = aWidth;
        this.prototypeSortDescriptors = [ {
            key: aKey,
            ascending: true
        }];
        this.editable = editable;
        this.align = align.startsWith("l") ? "left": (align.startsWith("c") ? "center": "right");
        this.headerAlign = headerAlign.startsWith("l") ? "left": (headerAlign.startsWith("c") ? "center": "right");
		this.isEditableWithKeyboard = true;
		this.disableReversedSortDescriptors = false;
		this._formatter = null;
//		this.URLPattern = /https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w/_\.]*(\?\S+)?)?)?/ig;	
//		this.URLPattern = /[\w]+:\/\/([-\w\.]+)+(:\d+)?(\/([\w/_\.]*(\?\S+)?)?)?/ig;	
		this.URLPattern = /(^|[\s\n]|<br\/?>)((?:https?|ftp):\/\/[\-A-Z0-9+\u0026\u2019@#\/%?=()~_|!:,.;]*[\-A-Z0-9+\u0026@#\/%=~()_|])/gi;	
    },
    
	removeEventHandlersFromElement: function(element) {
		
	},
	
	formatter: function() {
		return this._formatter;
	},
	
	isEditable: function() {
		return this.editable;
	},
	
	clone: function(){
		
		return new TableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},
	
    keyForEditing: function() {
        return this.editingKey ? this.editingKey: this.key;
    },
    
    setTableView: function(tableView) {
        this.tableView = tableView;
    },
	
	isOutlineColumn: function() {
		return this.tableView && this.tableView.outlineColumn == this;
	},
    
    // doSortDescriptorsEqualPrototype: 
    //  1 -> Descriptors sind gleich den prototypeSortDescriptors
    // -1 -> Descriptors sind gleich den umgekehrten prototypeSortDescriptors
    //  0 -> Descriptors sind weder gleich prototypeSortDescriptors noch gleich den umgekehrten prototypeSortDescriptors
    doSortDescriptorsEqualPrototype: function(descriptors) {
        var result = 0;
        if (descriptors && descriptors.length == this.prototypeSortDescriptors.length) {
            var direction = 0;
            for (var i = 0; i < descriptors.length; i ++ ) {
                if (descriptors[i].key != this.prototypeSortDescriptors[i].key)
                    break;
                if (descriptors[i].ascending == this.prototypeSortDescriptors[i].ascending) {
                    if (direction == 0)
                        direction = 1;
                    else if (direction ==- 1)
                        break;
                } else {
                    if (direction == 0)
                        direction = -1;
                    else if (direction == 1)
                        break;
                }
            }
            result = direction;
        }
        return result;
    },
    
    reversedPrototypeSortDescriptors: function() {
		if(this.disableReversedSortDescriptors)
			return this.prototypeSortDescriptors;
        var result = [];
        for (var i = 0; i < this.prototypeSortDescriptors.length; i ++ ) {
            var desc = this.prototypeSortDescriptors[i];
            result.push( {
                key: desc.key,
                ascending :! desc.ascending
            });
        }
        return result;
    },
    
    wrapperWithContent: function(content, cellHeight, doc) {
        return content;

        // Ist das folgende noch nötig für den IE?
        var wrapper = $(doc.createElement("span"));
        wrapper.style.overflow = "hidden";
	    if (cellHeight)
            wrapper.style.lineHeight = cellHeight + "px";
        wrapper.appendChild(content);
        return wrapper;
    },

	markupByReplacingURLsWithLinks: function(text, doc){
		var span = SPAN({document:doc});
		var start = 0;
		var regexpResult;
		while((regexpResult = this.URLPattern.exec(text)) != null){
			span.appendChild(doc.createTextNode(text.slice(start, regexpResult.index)));
			span.appendChild(A({document:doc, href:regexpResult[0], target:"_blank"}, regexpResult[0]));
			start = this.URLPattern.lastIndex;
		}
		var replaced = start != 0;
		if(replaced){
			if(start < text.length)
				span.appendChild(doc.createTextNode(text.slice(start, text.length)));			
		}
		return {markup:span, replaced:replaced};		
	},
    
    contentWidthFromCell: function(cell) {
        var width = this.width - 7;
        if (cell.style.paddingLeft)
            width -= parseInt(cell.style.paddingLeft) + 2;
        if (cell.style.marginLeft)
            width -= parseInt(cell.style.marginLeft);
        if (cell.childNodes[0] && cell.childNodes[0].width)
            width -= cell.childNodes[0].width;
        return width;
    },

	cellContentForValue: function(value, cell, doc, edit, cellHeight) {
        if (typeof value == "undefined" || value == null)
            value = "";
		value = value.toString();
        if (edit) {
            var textField = $(doc.createElement("input"));
            textField.type = "text";
            textField.style.width = (this.contentWidthFromCell(cell)-(Prototype.Browser.IE ? 18 : 0)) + "px";
            textField.style.height = inputHeight;
            textField.style.fontSize = fontSize;
            textField.value = value;
            textField.style.textAlign = this.align;
            textField.name = this.key;
            if (Prototype.Browser.IE && cellHeight) {
                textField.style.position = "absolute";
                textField.style.top = (cellHeight - parseInt(inputHeight) - 3) / 2 + "px";
            }
			return textField;            
        }else{
			if(value != "" && value.include("\n")) {
				value = value.gsub("\n"," ");
			}
			var result = this.markupByReplacingURLsWithLinks(value, doc);
			var node = result.replaced ? result.markup : doc.createTextNode(value);
			return this.wrapperWithContent(node, cellHeight, doc);
		}        	
	},
    
    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
        var value = object.valueForKey(this.key);
		return this.cellContentForValue(value, cell, doc, edit, cellHeight);
    }
	

}, {
	dontShowEditHints: false
});


// ************************* NumberTableColumn *********************** 
var NumberTableColumn = TableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "NumberTableColumn";
   		this.isEditableWithKeyboard = true;
	},

	clone: function(){
		return new NumberTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},
    
    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
        var value = object.valueForKey(this.key);
		if(!parseInt(value))
			value = null;
		return this.cellContentForValue(value, cell, doc, edit, cellHeight);
    }
    
});


// ************************* FlagStatusTableColumn *********************** 

var flagStatusImages = null;
var flagStatusTitles = null;
var flagStatusMenuOrder = null;

var FlagStatusTableColumn = TableColumn.extend( {
    constructor: function(aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base("flagStatus", aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "FlagStatusTableColumn";
        this.editingKey = "givenFlagStatus";
		this.isEditableWithKeyboard = false;
		this.editOnSingleClick = true;
    },

	clone: function(){
		return new FlagStatusTableColumn(this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},

    FlagStatus: {
        NoFlag: 0,
        GreenFlag: 1,
        YellowFlag: 2,
        RedFlag: 3,
        AutomaticFlag: 4
    },
    
    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
		var images = this.tableView.environment.images;
		if(!flagStatusImages) {
			flagStatusImages = {};
			flagStatusImages[0] = images["FlagSpacerSmall"];
			flagStatusImages[1] = images["FlagGreenSmall"];
			flagStatusImages[2] = images["FlagYellowSmall"];
			flagStatusImages[3] = images["FlagRedSmall"];
			flagStatusImages[4] = images["FlagSpacerSmall"];
		}
		if(!flagStatusTitles) {
			flagStatusTitles = {};
			flagStatusTitles[0] = environment.localizedString("None");
			flagStatusTitles[1] = ""; //environment.localizedString("Green");
			flagStatusTitles[2] = ""; //environment.localizedString("Yellow");
			flagStatusTitles[3] = ""; //environment.localizedString("Red");
			flagStatusTitles[4] = environment.localizedString("Auto");
		}
		if(!flagStatusMenuOrder) {
			flagStatusMenuOrder = [4, 0, 1, 2 , 3];
		}
		var flagStatus = object.valueForKey(this.editingKey);
		if(flagStatus == undefined)
			flagStatus = object.valueForKey(this.key);
		if(flagStatus == this.FlagStatus.AutomaticFlag) {
			flagStatusImages[4] = flagStatusImages[object.valueForKey(this.key)];
		}
		var image = flagStatusImages[flagStatus];
		if(!image)
			image = images["FlagSpacerSmall"];

		if(object.className() == "MEMasterResource") {
			return IMG({document:doc, style:"position:absolute; left:2px; top:"+((cellHeight-16)/2-1)+"px;", src:image});
		}else{
			this.element = DIV({document:doc, style:"overflow:hidden; height:"+cellHeight+"px;"});
			this.element.className = "customInputField";
			this.element.name = this.editingKey;
			this.element.value = flagStatus;
			this.element.appendChild(IMG({document:doc, style:"position:absolute; left:2px; top:"+((cellHeight-16)/2)+"px;", src:image}));
			if(!TableColumn.dontShowEditHints)
				this.element.appendChild(IMG({document:doc, 'class':"popUpButtonImage", style:"position:absolute; right:2px; top:"+((cellHeight-8)/2)+"px;", src:this.tableView.environment.images.WhiteArrowDown}));
			makePopUpMenuForElement(this.element, flagStatus, {enums:flagStatusTitles, images:flagStatusImages, imageClass:"flagMenuImage", order:flagStatusMenuOrder, showOnlyImages:false}, this.valueChanged, this.shouldOpenMenu, null, null, this);
		}
		return this.element;
    },
	
	valueChanged: function(element, value){
		this.element.value = value;
		this.tableView.endEditing();
	},
	
	shouldOpenMenu: function(event) {
		var row = null;
		var event = event || window.event;
		var target = event.srcElement ? event.srcElement : event.target;
		while(target && (!target.object || target.tagName != "DIV"))
			target = target.parentNode;
		row = target;
		return this.tableView.startEditingInRowAtColumn(row, this);
	},
	
	removeEventHandlersFromElement: function(element) {

	}
			
});


// ************************* InfoIconsTableColumn *********************** 
var InfoIconsTableColumn = TableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, false, align, headerAlign);
		this.className = "InfoIconsTableColumn";
		this.isEditableWithKeyboard = false;
    },
    
	clone: function(){
		return new InfoIconsTableColumn(this.key, this.title, this.shortTitle, this.width, this.align, this.headerAlign);
	},
	
    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
        var indexList = object.valueForKey(this.key);
        if (!indexList)
            return doc.createTextNode("");
			
		indexList = indexList.indices;
        var count = indexList.length;
        if (!count)
            return doc.createTextNode("");
        
        var container = doc.createElement("div");
        for (var i = 0; i < count; i ++ ) {
            var icon = doc.createElement("img");
            icon.style.paddingRight = "2px";
            icon.width = 11;
            icon.height = 11;
            icon.src = this.tableView.environment.infoIconURLs[indexList[i]];
            container.appendChild(icon);
            if (cellHeight) {
                icon.vspace = (cellHeight - 11) / 2;
                container.style.lineHeight = cellHeight + "px";
            }
            
        }
        return container;
    }
});


// ************************* FlatOrderTableColumn *********************** 
var FlatOrderTableColumn = TableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "FlatOrderTableColumn";
   		this.isEditableWithKeyboard = false;
	},

	clone: function(){
		return new FlatOrderTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},
    
    reversedPrototypeSortDescriptors: function() {
        return this.prototypeSortDescriptors;
    }
    
});


// ************************* ComboBoxTableColumn *********************** 
var ComboBoxTableColumn = TableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "ComboBoxTableColumn";
		this.isEditableWithKeyboard = true;		
    },

	clone: function(){
		return new ComboBoxTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},
    
	stringValueForObject: function(object, cell, doc, edit, cellHeight) {
		return "";
	},
	
	menuContent: function(object) {
		return [];
	},

    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
        var value = this.stringValueForObject(object, cell, doc, edit, cellHeight);
        var imageURL = this.tableView.environment.images.WhiteArrowDown;
        if (!edit) {
			var span = SPAN({document:doc, 'class':"customInputField", style:"height:"+cellHeight+"px; margin-right:17px; overflow:hidden;"}, 
				value, 
				element = DIV({document:doc, 'class':"popUpButtonImageBackground", style:"background-color:#3d80df; position:absolute; width:17px; height:"+cellHeight+"px; top:0px; right:0px;"})
			);
			if(!TableColumn.dontShowEditHints) {
				var image = IMG({document:doc, 'class':"popUpButtonImage", style:"position:absolute; right:3px; top:"+((cellHeight-8)/2)+"px;", src:imageURL});			
				var me = this;
				image.onclick=function(event){
					var row = null;
					var event = event || window.event;
					var target = event.srcElement ? event.srcElement : event.target;
					while(target && (!target.object || target.tagName != "DIV"))
						target = target.parentNode;
					row = target;
					me.openMenu = true;
					me.tableView.startEditingInRowAtColumn(row, me);
				}
				element.appendChild(image);
			}
			return span;
        }
        else 
        {
            var comboBox = new ComboBox(Prototype.Browser.WebKit ? 17: 14, parseInt(fontSize), imageURL, 9, 8, value, this.menuContent(object), this.contentWidthFromCell(cell), this.key, true, this, this.openMenu);
            var html = comboBox.HTMLElement;
            if (cellHeight) {
                var diff = Prototype.Browser.IE ? 3: 6;
                html.style.top = (cellHeight - parseInt(inputHeight) - diff) / 2 + "px";
            }
			this.openMenu = false;
            return html;
        }
    },
	
	comboBoxMenuClosed: function(comboBox){
		this.tableView.endEditing();
	}
});


// ************************* PercentTableColumn *********************** 
var PercentTableColumn = ComboBoxTableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "PercentTableColumn";	
    },

	clone: function(){
		return new PercentTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},

    setTableView: function(tableView) {
        this.base(tableView);
        this._formatter = new PercentFormatter(tableView.environment);
    },

	stringValueForObject: function(object, cell, doc, edit, cellHeight) {
		var value = object.valueForKey(this.key);
		if(typeof value == 'undefined')
			value = "";
		else
			value = Math.round(value * 100) + "%";
		return value;
	},
	
	menuContent: function(object) {
		return ['0%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%'];
	}
  
});

// ************************* UtilisationTableColumn *********************** 
var UtilisationTableColumn = ComboBoxTableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "UtilisationTableColumn";
    },

	clone: function(){
		return new UtilisationTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},

    setTableView: function(tableView) {
        this.base(tableView);
        this._formatter = new UtilisationFormatter(tableView.environment);
    },
    
	stringValueForObject: function(object, cell, doc, edit, cellHeight) {
        var value = object.valueForKey(this.key);
		value = this._formatter.stringForObjectValue(value);
		return value;
	},
	
	menuContent: function(object) {
		return ['0%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%'];
	}
});



// ************************* CurrencyTableColumn *********************** 
var CurrencyTableColumn = TableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "CurrencyTableColumn";
		this.isEditableWithKeyboard = true;	
    },

	clone: function(){
		return new CurrencyTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},

    setTableView: function(tableView) {
        this.base(tableView);
        this._formatter = new CurrencyFormatter(tableView.environment);
    },
    
    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
        var value = object.valueForKey(this.key);
		var isNegative = value < 0;
        if (!value)
            value = "";
		else{
			value = this._formatter.stringForObjectValue(value);
		}
			
        if (edit) {
            var textField = $(doc.createElement("input"));
            textField.type = "text";
            textField.style.width = this.contentWidthFromCell(cell) + "px";
            textField.style.height = inputHeight;
            textField.style.textAlign = this.align;
            textField.style.fontSize = fontSize;
            textField.value = value;
            textField.name = this.key;
            if (Prototype.Browser.IE && cellHeight) {
                textField.style.position = "absolute";
                textField.style.top = (cellHeight - parseInt(inputHeight) - 3) / 2 + "px";
            }
            return textField;
        }
		cell.style.textAlign = this.align;
		var options = {document:doc};
		if(isNegative)
			options.style = "color:#ff0000;";
		return SPAN(options, doc.createTextNode(value));
    }
});

// ************************* BudgetTableColumn *********************** 

var BudgetTableColumn = CurrencyTableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "BudgetTableColumn";
    },
	
	clone: function(){
		return new BudgetTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},

    setTableView: function(tableView) {
        this.base(tableView);
        this._formatter = new BudgetFormatter(tableView.environment);
    }
});

// ************************* RateTableColumn *********************** 
var RateTableColumn = TableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "RateTableColumn";
		this.isEditableWithKeyboard = true;		
    },
 
 	clone: function(){
		return new RateTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},

    setTableView: function(tableView) {
        this.tableView  = tableView;
	    this._formatter = new RateFormatter(this.tableView.environment);
    },
   
    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
		var value = "";
        var rate = object.valueForKey(this.key);
        if (rate){
		    value = this._formatter.stringForObjectValue(rate);
//			var unit = rate.denominatorUnit == MEDuration.DurationUnit.MEMaterialUnit ? object.valueForKey("materialUnit") : this._formatter.descriptionForUnitPluralFloating(rate.denominatorUnit, false, rate.denominatorUnitIsFloating);
//			if (this.tableView.environment.currencySymbolBeforeAmount)
//				value = this.tableView.environment.currencySymbol+" "+rate.amount+"/"+unit;
//			else 
//				value = rate.amount + " " + this.tableView.environment.currencySymbol+"/"+unit;
			if (edit) {
				var textField = $(doc.createElement("input"));
				textField.type = "text";
				textField.style.width = this.contentWidthFromCell(cell) + "px";
				textField.style.height = inputHeight;
				textField.style.textAlign = this.align;
				textField.style.fontSize = fontSize;
				textField.value = value;
				textField.name = this.key;
				if (Prototype.Browser.IE && cellHeight) {
					textField.style.position = "absolute";
					textField.style.top = (cellHeight - parseInt(inputHeight) - 3) / 2 + "px";
				}
				return textField;
			}
		}
		cell.style.textAlign = this.align;
        return this.wrapperWithContent(doc.createTextNode(value), cellHeight, doc);
    }
});

// ************************* BooleanTableColumn *********************** 
var BooleanTableColumn = TableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "BooleanTableColumn";
		this.isEditableWithKeyboard = false;
		this.editOnSingleClick = true;
    },

 	clone: function(){
		return new BooleanTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},
    
    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
        var checked = this.useClickValue ? this.clickValue : object.valueForKey(this.key);
		if(!TableColumn.dontShowEditHints || checked) {
	        var value = object.valueForKey(this.key) ? this.tableView.environment.localizedTrueString: this.tableView.environment.localizedFalseString;
	        var checkbox = $(doc.createElement("input"));
	        checkbox.type = "checkbox";
	        checkbox.value = value;
	        checkbox.name = this.key;
			if(TableColumn.dontShowEditHints)
	        	checkbox.disabled = !edit;
	        if (checked) {
	            checkbox.checked = "checked";
	            checkbox.defaultChecked = true;
	            // IE7
            
	        }
	        if (Prototype.Browser.IE && cellHeight) {
	            checkbox.style.position = "absolute";
	            checkbox.style.top = (cellHeight - parseInt(inputHeight) - 3) / 2 + "px";
	        }
			if(!this.clickEventListener)
				this.clickEventListener = this.click.bindAsEventListener(this);
			PWUtils.observe(checkbox, 'click', this.clickEventListener, true);
	        return checkbox;
		}else
			return  doc.createTextNode("");
    },
	
	click: function(event) {
		var row = null;
		var event = event || window.event;
		var target = event.srcElement ? event.srcElement : event.target;
		var checkbox = target;
		while(target && (!target.object || target.tagName != "DIV"))
			target = target.parentNode;
		row = target;
		this.useClickValue = true;
		this.clickValue = checkbox.checked;
		if(!this.tableView.startEditingInRowAtColumn(row, this)) {
            checkbox.checked = this.clickValue ? null : "checked";
            checkbox.defaultChecked = this.clickValue ? false : null;
		}			
		this.useClickValue = false;
		this.tableView.endEditing();
//		PWUtils.stopObserving(checkbox, 'click', this.clickEventListener);
	}
	
});

var dateTableColumnID = 0;

// ************************* DateTableColumn *********************** 
var DateTableColumn = TableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign, displayTime) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "DateTableColumn";
		this.isEditableWithKeyboard = true;		
		this.ID = dateTableColumnID;
		this.displayTime = displayTime;
		dateTableColumnID++;
    },

 	clone: function(){
		return new DateTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign, this.displayTime);
	},
    
    setTableView: function(tableView) {
        this.base(tableView);
        this._formatter = new DateFormatter(tableView.environment.format.dateAndTimeFormat.date, this.displayTime ? tableView.environment.format.dateAndTimeFormat.time : null, true, tableView.environment);
    },
    
    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
		var environment = this.tableView.environment;
        var value = object.valueForKey(this.key);
        if ( !value && !edit)
			return this.wrapperWithContent(doc.createTextNode(""), cellHeight, doc);
        if (edit) {
            var imageURL = this.tableView.environment.images.Calendar;
			var datePicker = new DatePicker(Prototype.Browser.WebKit ? 17: 14, parseInt(fontSize), imageURL, value, this.contentWidthFromCell(cell), this.key, this._formatter, this.displayTime);
            var html = datePicker.HTMLElement;
            if (cellHeight) {
                var diff = Prototype.Browser.IE ? 3: 6;
                html.style.top = (cellHeight - parseInt(inputHeight) - diff) / 2 + "px";
            }
            return html;
        }else{ 
            return SPAN({document:doc, style:"white-space:normal;"}, doc.createTextNode(this._formatter.stringForObjectValue(value))); //huhu
//            return SPAN({style:"white-space:normal;"}, doc.createTextNode("huhu")); //huhu
		}
    }
});


// ************************* DurationTableColumn *********************** 
var DurationTableColumn = TableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "DurationTableColumn";
		this.isEditableWithKeyboard = true;
    },

 	clone: function(){
		return new DurationTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},
    
    setTableView: function(tableView) {
        this.base(tableView);
        this._formatter = new DurationFormatter(tableView.environment);
    },
    
    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
		var cellWidth = this.contentWidthFromCell(cell);
		this._formatter.setPreferedWidth(cellWidth);
        var value = object.valueForKey(this.key);
        if ( ! value)
            value = "";
        if (edit) {
            var textField = $(doc.createElement("input"));
            textField.type = "text";
            textField.style.width = cellWidth + "px";
            textField.style.height = inputHeight;
            textField.style.fontSize = fontSize;            
            textField.value = this._formatter.stringForObjectValue(value);
            textField.name = this.key;
            if (Prototype.Browser.IE && cellHeight) {
                textField.style.position = "absolute";
                textField.style.top = (cellHeight - parseInt(inputHeight) - 3) / 2 + "px";
            }
            return textField;            
        } else 
			return this.wrapperWithContent(doc.createTextNode(this._formatter.stringForObjectValue(value)), cellHeight, doc);
    }
});

// ************************* ResourcesTableColumn *********************** 

var ResourcesTableColumn = ComboBoxTableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "ResourcesTableColumn";
    },

 	clone: function(){
		return new ResourcesTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},

	stringValueForObject: function(object, cell, doc, edit, cellHeight) {
		if(this.className == "ResourcesTableColumn" && object.className() == "MEAssignment")
			return doc.createTextNode("");

        var value = object.valueForKey(this.key);
        if (typeof value == "undefined" || value == null)
            value = "";        
		else if(typeof value != "string")
			value = value.valueForKey("title");
		return value;
	},
	
	menuContent: function(object) {
		var value = this.stringValueForObject(object);
		var rootProjects = this.tableView.delegate.rootObjectsInManagedObjectContext(this.tableView.delegate.moc);
		var visibleResources = rootProjects.valueForKeyPath("resources.title")[0];
		if(visibleResources.length) {
			visibleResources = visibleResources.without(value);
			if(visibleResources.length)
				visibleResources = visibleResources.sort();
		}
		return visibleResources;
	}
});

// ************************* ActivityTitleTableColumn *********************** 
var ActivityTitleTableColumn = ResourcesTableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "ActivityTitleTableColumn";
   		this.isEditableWithKeyboard = true;
	},

	clone: function(){
		return new ActivityTitleTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},
    
    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
		if(object.className() == "MEAssignment")
			return this.base(object, cell, doc, edit, cellHeight);
		else {
	        var value = object.valueForKey(this.key);
			return this.cellContentForValue(value, cell, doc, edit, cellHeight);
		}
    }
});

// ************************* SingleSelectionTableColumn *********************** 

var SingleSelectionTableColumn = TableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign, enums) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "SingleSelectionTableColumn";
		this.isEditableWithKeyboard = true;
		this.enums = enums;
		this.editOnSingleClick = true;
    },
	
 	clone: function(){
		return new SingleSelectionTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign, this.enums);
	},
	
    cellContentForObject: function(object, cell, doc, edit, cellHeight) {
        var value = object.valueForKeyPath(this.key);
		var displayValue = this.enums[value];
		this.element = DIV({document:doc, style:"overflow:hidden;"});
		this.element.className = "customInputField";
		this.element.name = this.key;
		this.element.appendChild(doc.createTextNode(displayValue));
		if(!TableColumn.dontShowEditHints)
			this.element.appendChild(IMG({document:doc, 'class':"popUpButtonImage", style:"position:absolute; right:2px; top:"+((cellHeight-6)/2)+"px;", src:this.tableView.environment.images.WhiteArrowDown}));		
		var order = Object.keys(this.enums).sortBy(function(s) { return parseInt(s); });
		order.reverse();
		makePopUpMenuForElement(this.element, value, {enums:this.enums, order:order, removeAfterFirstClick:true}, this.valueChanged, this.shouldOpenMenu, null, null, this);
		return this.element;
    },

	valueChanged: function(element, value){
		this.element.value = value;
		this.tableView.endEditing();
	},
	
	shouldOpenMenu: function(event) {
		var row = null;
		var event = event || window.event;
		var target = event.srcElement ? event.srcElement : event.target;
		while(target && (!target.object || target.tagName != "DIV"))
			target = target.parentNode;
		row = target;
		return this.tableView.startEditingInRowAtColumn(row, this);
	}
});


// ************************* RoleTableColumn *********************** 

var RoleTableColumn = ComboBoxTableColumn.extend( {
    constructor: function(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign) {
        this.base(aKey, aTitle, aShortTitle, aWidth, editable, align, headerAlign);
		this.className = "RoleTableColumn";
    },

 	clone: function(){
		return new RoleTableColumn(this.key, this.title, this.shortTitle, this.width, this.editable, this.align, this.headerAlign);
	},

	stringValueForObject: function(object, cell, doc, edit, cellHeight) {
        var role = object.valueForKey(this.key);
		var value = "";
		if(role){
			value = role.valueForKey("title");
            if(value == undefined)
                value = "";
        }
		return value;
	},
	
	menuContent: function(object) {
		var project = object.valueForKey("project");
		this.project = project;
		var roles = project.sortedRoles();
		var roleNames = [];
		roles.each(function(role){
			roleNames.push(role.valueForKeyPath("title"));
		});
		return roleNames;
	},

	formatter: function() {
		if(!this._formatter)
			this._formatter = new RoleFormatter(this.project);
		return this._formatter;
	}
});



