// Copyright 2008 ProjectWizards GmbH. All rights reserved.

//console.log("ActivitiesViewController");

var	didRunQuicklookFix = false;

var ActivitiesViewController  = ViewController.extend({

	constructor: function(container, moc, controls, environment, styleList, viewOptions, columns, initialSortDescriptors, actionMethods, ruler, printPageURL, showPrintView, splitViewState, isBeingExportedForQuicklook){

		this.base(moc);
		this.initialSortDescriptors = initialSortDescriptors;
		this.splitViewState = parseFloat(eval('('+splitViewState+')'));
		this.showPrintView = showPrintView;
		this.className = "ActivitiesViewController";
		this.container = container;
		this.moc = moc;
		this.controls = controls;
		this.environment = environment;
		this.styleList = styleList;
		this.viewOptions = viewOptions;
		this.columns = columns;
		this.ruler = ruler;
		this.printPageURL = printPageURL;
		this.actionMethods = actionMethods;
		this.isBeingExportedForQuicklook = isBeingExportedForQuicklook;
		if(this.isVisible())	
			this.createSubviews();
		PWUtils.notificationCenter.addObserverForMessage(this, "rulerChanged", "handleRulerChangedNotification");
		if(this.isBeingExportedForQuicklook) {
			this.windowResizedActionEventListener = this.quicklookSplitterFix.bindAsEventListener(this);
			PWUtils.observe(window, "resize", this.windowResizedActionEventListener, true);
		}
	},

	createSubviews: function(){
		if(!this.outlineController){
			this.outlineController = new OutlineController(this.environment);
			this.outlineController.setChildrenKey("linkedSubActivities");
			this.outlineController.setSortDescriptors(this.initialSortDescriptors);				
			this.activitiesView = new ActivitiesView(this.outlineController, this.container, this.columns, this.styleList, this.ruler, this.viewOptions, this.environment, this.controls, this.moc, this.showPrintView, this, this.isBeingExportedForQuicklook);			
			this.setSplitViewState(this.splitViewState);
			if(this.splitterPosition)
				this.activitiesView.splitView.setSplitterPosition(this.splitterPosition);
			this.outlineController.setDelegate(this.activitiesView);
			//if(Prototype.Browser.IE)
				this.activitiesView.refresh();
			NotificationCenter.defaultNotificationCenter().addObserverForMessage(this, WRLAjaxContextChangedByServerNotification, "managedObjectContextChangedByServer");	
		}
	},

	managedObjectContextChangedByServer: function(msg, userInfo){
//                    console.log("Context changed");
		if(userInfo.context == this.moc){
			if(userInfo.result && (userInfo.result.deleted.length || userInfo.result.updated.length)) {
                this.activitiesView.refreshRuler();	
				this.activitiesView.refresh();
			}
		}
	},

	freezeSortOrder: function() {
		this.actionMethods.freezeSortOrder({sortDescriptors:Object.toJSON(this.outlineController.sortDescriptors)});
		this.moc.synchronize();			
		this.outlineController.setSortDescriptors([{key:'flatOrder', ascending: true}]);					
		this.refresh();
	},

	_addObject: function(method, position, targetActivities) {
		if(targetActivities.length) {
			if(this.isEditing())
				this.activitiesView.endEditing();
			var selectedActivitiesIDs = [];
			for (var i = 0; i < targetActivities.length; i ++ )
				selectedActivitiesIDs.push(targetActivities[i].objectID.uri);
			var opt = {selectedActivitiesIDs:selectedActivitiesIDs};
			if(position)
				opt.position=position;
			var objectID = method(opt);
			this.moc.synchronize();	
			var object = this.moc.registeredObjectWithURIString(objectID);
			if(object){
				this.outlineController.setSelectedObjectIDs([objectID]);
				this.activitiesView.refresh();
				var me = this;
				(function() { 
					me.activitiesView.outlineView.editSelectedRow(); 
				}).delay(0);
			}
		}
	},

	addObject: function(method, position){
		var selectedObjects = this.outlineController.selectedObjects;
		if(!selectedObjects || selectedObjects.length == 0) {
			var flatObjects = this.outlineController.getFlatObjects();
			selectedObjects = flatObjects.length ? [flatObjects[flatObjects.length-1]] : [];
		}
		this._addObject(method, position, selectedObjects);
	},

	addActivity: function(position){
		this.addObject(this.actionMethods.addActivity, position);
	},

	addMilestone: function(){
		this.addObject(this.actionMethods.addMilestone);
	},

	addAssignment: function(){
		this.addObject(this.actionMethods.addAssignment);
	},

	canAddActivity: function(){
		return this.activitiesView.canAddActivity();
	},
	
	canAddAssignment: function(){
		return this.activitiesView.canAddAssignment();	
	},

	canAddSubActivity: function(){
		return true;
	},
	
	canAddSuccessorActivity: function(){
		return true;
	},

	canAddPredecessorActivity: function(){
		return true;
	},

	canAddAuntActivity: function(){
		return true;
	},
		
	canChainActivities: function(){
		selectedObjects = this.selectedObjects();
		return selectedObjects && selectedObjects.length;
	},
	
	canDisconnectActivities: function(){
		selectedObjects = this.selectedObjects();
		return selectedObjects && selectedObjects.length;
	},
			
	deleteSelectedObjects: function(){
		var selectedActivitiesIDs = this.outlineController.selectedObjectIDs();
		if(selectedActivitiesIDs.length){
			this.actionMethods.deleteActivities({selectedActivitiesIDs:selectedActivitiesIDs});
			this.moc.synchronize();	
			this.outlineController.setSelectedObjects([]);
			this.activitiesView.refresh(true);
		}
	},

	canDeleteSelection: function() {
		return this.outlineController.selectedObjectIDs().length ? true : false;
	},
	
	selectAll: function() {
		var flatObjects = this.outlineController.getFlatObjects();
		if(flatObjects.length) {
			this.outlineController.setSelectedObjects(flatObjects);	
			this.refresh();
		}
	},

	indentOutdent: function(method){
		var parentIDs = this.activitiesView.parentIDs;
		var selectedActivitiesIDs = this.outlineController.selectedObjectIDs();
		if(selectedActivitiesIDs.length){
			this.activitiesView.endEditing();
			method({selectedActivitiesIDs:selectedActivitiesIDs, parentIDs:parentIDs});
			this.moc.synchronize();	
			this.activitiesView.refresh(true);
		}	
	},

	indentSelection: function(){
		this.indentOutdent(this.actionMethods.indentSelection);
	},

	outdentSelection: function(){
		this.indentOutdent(this.actionMethods.outdentSelection);
	},
	
	synchronizeManagedObjectContext: function(){
		this.moc.synchronize();
		this.activitiesView.refresh(true);		
	},
	
	refresh: function(){	
		this.activitiesView.refresh();		
	},
	
	zoomIn: function(){
		this.isInZoomAction = true;
		this.activitiesView.zoomIn();
		this.isInZoomAction = false;
	},
	
	zoomOut: function(){
		this.isInZoomAction = true;
		this.activitiesView.zoomOut();
		this.isInZoomAction = false;
	},

	selectedObjects: function(){
		return this.outlineController.selectedObjects;
	},
	
	shouldEditObjectProperty: function(object, key){
		if(object.className()=="MEAssignment" && key == "assignedResourcesString")
			return false;
		var result = this.actionMethods.shouldEditObjectProperty({objectID:object.objectID.uri, key:key});
		return eval(result);
	},
	
	validatePropertyOfObject: function(outline, property, object, validationDidEndHandler){
		this.validationDidEndHandler = validationDidEndHandler;	
		var propertyName;
		var value;
		for(propertyName in property){
			value = property[propertyName];
			break;
		}
		var result = this.actionMethods.validatePropertyOfObject({propertyName:propertyName, value:value, objectID:object.objectID.uri});
		validationDidEndHandler.call(outline, result);
	},
	
	closeDatePicker: function() {
		if(window["datePickerIsVisible"] && datePickerIsVisible()){
			closeCalendar();
			return true;
		}	
	},

	insertNewline: function(sender, evt){
		if(!this.closeDatePicker())
			this.activitiesView.outlineView.editSelectedRow();
		return true;
	},
	
	insertTab: function(sender, evt){
		if(!this.closeDatePicker())
			this.activitiesView.outlineView.editNextProperty();		
		return true;
	},
			
	moveLeft: function(sender, evt) {
		this.activitiesView.outlineView.setSelectedRowsCollapsed(true);
		return true;
	},

	moveRight: function(sender, evt) {
		this.activitiesView.outlineView.setSelectedRowsCollapsed(false);
		return true;
	},

	moveUp: function(sender, evt) {
		this.activitiesView.outlineView.selectPreviousRow(false);
		return true;
	},

	moveDown: function(sender, evt) {
		this.activitiesView.outlineView.selectNextRow(false);
		return true;
	},
	
	moveUpAndModifySelection: function(sender, evt){
		this.activitiesView.outlineView.selectPreviousRow(true);
		return true;
	},
  
	moveDownAndModifySelection: function(sender, evt){
		this.activitiesView.outlineView.selectNextRow(true);	
		return true;
	},
	
	clonedColumns: function(){
		var result = [];
		for(var i=0; i<this.columns.length; i++){
			result.push(this.columns[i].clone());
		}
		return result;
	},

	print: function(){
		var info = {};
		info.environment = this.environment;
		info.outlineSize = {	 width:this.activitiesView.outlineView.tableWidth(), 
								height:this.activitiesView.outlineView.fullHeight()};
		info.ganttSize	 = {	 width:this.activitiesView.ganttScrollView.width(), 
								height:this.activitiesView.ganttScrollView.fullHeight()};	
		info.ruler = this.activitiesView.ganttRuler.clone();
		info.columns = this.clonedColumns();
		info.styleList = this.styleList;
		info.viewOptions = this.viewOptions;
		info.moc = this.moc;		
		info.actionMethods = this.actionMethods;
		window.info = info;
		this.printWindow = window.open(Prototype.Browser.WebKit ? this.printPageURL : '', '','height=600, width=800, resizable=1, scrollbars=1');
		if(window.focus) 
			this.printWindow.focus();				
		if(!Prototype.Browser.WebKit){	
			this.printWindow.location = this.printPageURL;
		}

		/*	This variables are used in the utilization view

			info.moc	
			info.environment
			info.styleList
			info.viewOptions
			info.columns
			info.ruler
		*/
	},
	
	isVisible: function(){
		var style = PWUtils.effectiveStyle(this.container);
		return style.display != "none";
	},
	
	setIsVisible: function(flag){
		var wasVisible = this.isVisible();
		this.container.style.display = flag ? "block" : "none";
		if(flag && !wasVisible){	//disableContent
			this.createSubviews();
			this.activitiesView.splitView.windowResizedAction();
			if(this.refreshRuler){
				this.refreshRuler = false;
				this.activitiesView.refreshRuler();
			}
			if(!this.lastModificationDate || this.moc.modificationDate.getTime() != this.lastModificationDate.getTime())
				this.refresh();
		}else if(!flag && wasVisible)
			this.lastModificationDate = new Date(this.moc.modificationDate.getTime());
		if(this.activitiesView)
			this.activitiesView.setIsVisible(flag);
	},
	
	visibleGanttChanged: function(startDate, endDate) {
	
	},
	
	handleRulerChangedNotification: function(msg, ruler){
		if(ruler != this.ruler){
			if(this.ruler.pixelsPerDay != ruler.pixelsPerDay){
				this.ruler.setPixelsPerDay(ruler.pixelsPerDay);
				if(!this.isVisible())
					this.refreshRuler = true;
			}
		}
	},
	
	chainActivities: function(kind) {
		var activities = this.selectedObjects();
		if(activities.length) {
			var activityIDs = activities.collect(function(activity){
				return activity.uri();
			});
			this.actionMethods.chainActivities({activityIDs:activityIDs, kind:kind});
			this.moc.synchronize();
			this.refresh();
		}
	},
	
	chainFinishStart: function() {
		this.chainActivities(MEActivityRelationship.MEFinishToStartRelationship);
	},
	
	chainFinishFinish: function() {
		this.chainActivities(MEActivityRelationship.MEFinishToFinishRelationship);
	},
	
	chainStartFinish: function() {
		this.chainActivities(MEActivityRelationship.MEStartToFinishRelationship);
	},
	
	chainStartStart: function() {
		this.chainActivities(MEActivityRelationship.MEStartToStartRelationship);
	},
	
	disconnectActivities: function() {
		var activities = this.selectedObjects();
		if(activities.length) {
			var activityIDs = activities.collect(function(activity){
				return activity.uri();
			});
			this.actionMethods.disconnectActivities({activityIDs:activityIDs});
			this.moc.synchronize();
			this.refresh();
		}
	},
	
	// ************************************************************************************************************
	// *****
	// *****										Drag and Drop
	// *****

	canDragBetweenItems: function(pasteboard) {
		var result = false;
		if(this.outlineController.sortDescriptors && this.outlineController.sortDescriptors.length){
			var sortDescriptor = this.outlineController.sortDescriptors[0];
			if(sortDescriptor.key == 'flatOrder' || sortDescriptor.key == 'wbs') {
				result = true;
				var onlyAssignments = true;
				var rows = pasteboard[0].data;
				for(var i=0; i<rows.length; i++){
					var row = rows[i];
					if(row.object.className() != "MEAssignment"){
						onlyAssignments = false;
						break;
					}
				};
				if(onlyAssignments)
					result = false;				
			}
		}
		return result;
	},

	canDropOnTarget: function(target, pasteboard, area){
		var result = false;
		var rows = pasteboard[0].data;
		if(!(rows.length == 1 && target == rows[0].object)) {
			for(var i=0; i<rows.length; i++){
				var row = rows[i];
				if(!row.object.isAncestorOf(target)){
					result = true;
					break;
				}
			};
			if(target.isGroup() && area == "bottom"){
				result = this.canDropOnTarget(target.valueForKey("linkedSubActivities")[0], pasteboard, "middle");
			}
		}
		return result;
	},

	dropAreaFromLocation: function(location, pasteboard) {
		return this.canDragBetweenItems(pasteboard) ? (location.row == OutlineView.MOUSE_IS_NOT_IN_ROW ? 'middle' : location.area) : 'middle';
	},
	
	outlineShouldDragRows: function(outline, rows){
		return true;
	},
		
	outlineValidateDrop: function(outline, location, pasteboard){		
		if(location.row && location.row.object && location.row != OutlineView.MOUSE_IS_NOT_IN_OUTLINE){
			if(this.canDropOnTarget(location.row.object, pasteboard, location.area))
				return {accept:true, area:this.dropAreaFromLocation(location, pasteboard)};
		}
		return {accept:false};
	},

	outlineAcceptDrop: function(outline, location, pasteboard){
		if(location.row && location.row != OutlineView.MOUSE_IS_NOT_IN_OUTLINE && pasteboard.length){
			var objectIDs = [];
			var rows = pasteboard[0].data;
			rows.each(function(row){
				if(row.object)
					objectIDs.push(row.object.uri());
			});
			if(objectIDs.length){				
				var targetActivityID = location.row.object && location.row.object.uri ? location.row.object.uri() : "no_activity";
				this.actionMethods.acceptDrop({objectIDs:objectIDs, targetActivityID:targetActivityID, area:this.dropAreaFromLocation(location, pasteboard)});
				this.moc.synchronize();	
				this.activitiesView.refresh(true);
			}
		}
	},

	outlineDoubleClickInEmptyArea: function(outline, event) {
		var flatObjects = this.outlineController.getFlatObjects();
		var targetActivities = flatObjects.length ? [flatObjects[flatObjects.length-1]] : [];		
		this._addObject(this.actionMethods.addActivity, null, targetActivities);
		Event.stop(event);
	},

	canIndentActivity: function(){
		return this.activitiesView.canIndentActivity();
	},

	canOutdentActivity: function(){
		return this.activitiesView.canOutdentActivity();	
	},

	collapseAll: function() {
		this.activitiesView.collapseAll();
	},

	expandAll: function() {
		this.activitiesView.expandAll();
	},
	
	hideAllAssignments: function() {
		this.activitiesView.hideAllAssignments();
	},

	showAllAssignments: function() {
		this.activitiesView.showAllAssignments();
	},
	
	showOutlineLevel: function(level) {
		this.activitiesView.showOutlineLevel(level);
	},

	selectedObjectsThatCanBeTransformedIntoMilestones: function() {
		return this.selectedObjects().reject(function(object){
				return object.className() == "MEAssignment" || (!object.hasAssignments() && object.isGroup()) || object.valueForKey('isMilestone');
		}, this);
	},
	
	canTransformSelectedActivitiesIntoMilestones: function() {
		return this.selectedObjectsThatCanBeTransformedIntoMilestones().length;
	},
	
	transformSelectedActivitiesIntoMilestones: function() {
		var activities = this.selectedObjectsThatCanBeTransformedIntoMilestones();
		if(activities.length) {
			var activityIDs = activities.collect(function(activity){
				return activity.uri();
			});
			this.actionMethods.transformActivitiesIntoMilestones({activityIDs:activityIDs});
			this.moc.synchronize();
			this.refresh();
		}
	},
	
	selectedObjectsThatHaveActualValues: function() {
		return this.selectedObjects();	// TODO
	},

	canClearActualValues: function() {
		var selectedObjects = this.selectedObjectsThatHaveActualValues();
		return selectedObjects && selectedObjects.length;
	},
	
	clearActualValues: function() {
		var selectedObjects = this.selectedObjectsThatHaveActualValues();
		if(selectedObjects && selectedObjects.length) {
			var activityIDs = selectedObjects.collect(function(activity){
				return activity.uri();
			});
			this.actionMethods.clearActualValues({activityIDs:activityIDs});
			this.moc.synchronize();
			this.refresh();	
		}
	},

	isEditing: function() {
		return this.activitiesView.outlineView.isEditing();
	},
	
	testAddActivity: function() {	// Test
		var flatObjects = this.outlineController.getFlatObjects();
		var opt = flatObjects.length ? {selectedActivitiesIDs:[flatObjects[flatObjects.length-1].objectID.uri]} : null;
		var objectID = this.actionMethods.addActivity(opt);
		this.moc.synchronize();			
		return this.moc.registeredObjectWithURIString(objectID);
	},

	mainViewWidth: function() {
		if(this.isVisible())
			return this.container.offsetWidth;
		else {	
			var mainViews = $$(".mainView");
			for(var i=0; i<mainViews.length; i++) {
				var mainView = mainViews[i];
				if(mainView.offsetWidth)
					return mainView.offsetWidth;
			}
		}
	},

	splitterPositionFromRatio: function(ratio) {
		if(ratio == 0.0)
			return -4;
		if(ratio>1.0)
			ratio=1.0;
		var pos = (this.mainViewWidth() - 7) * ratio;
		pos = pos >= 0 ? pos : 0;	
		return pos;
	},
	
	columnsFromWorkspaceData: function(workspaceData) {
		return eval(workspaceData.columns);
	},
	
	_applyWorkspace: function(workspaceData) {
		this.styleList = eval('('+workspaceData.styleList+')');
		this.columns = this.columnsFromWorkspaceData(workspaceData);
		this.viewOptions = eval('('+workspaceData.viewOptions+')');
		if(workspaceData.splitViewState)
			this.setSplitViewState(workspaceData.splitViewState);

		if(this.activitiesView) {
			this.activitiesView.setRootActivities(this.activitiesView.rootObjectsInManagedObjectContext(this.moc), false);
			this.activitiesView.setStyleList(new StyleList(this.styleList, this.environment));
			this.activitiesView.setColumns(this.columns);
			this.activitiesView.setViewOptions(this.viewOptions);
			this.activitiesView.splitView.setSplitterPosition(this.splitterPosition);
			this.refresh();
			this.activitiesView.containerSizeChanged();
		}	
	},
	
	fetchWorkspace: function() {
		var wd = this.actionMethods.getWorkspaceData({});
		var workspaceData = eval('('+wd+')');
		this._applyWorkspace(workspaceData);
	},
	
	_setSplitViewState: function(splitViewState) {
		this.splitViewState = splitViewState;
		this.splitterPosition = this.splitterPositionFromRatio(splitViewState);
		if(this.activitiesView)
			this.activitiesView.splitView.setSplitterPosition(this.splitterPosition);	
	},
	
	setSplitViewState: function(splitViewState) {
		this._setSplitViewState(splitViewState);
		this.quicklookSplitViewState = splitViewState;
	},

	quicklookSplitterFix: function(event) {
		if(!didRunQuicklookFix) {
			didRunQuicklookFix = true;
			this._setSplitViewState(this.quicklookSplitViewState);
		}
	},
	
	workspaceViewName: function() {
		return "activitiesViewController";
	},	

	loadProjectLink: function(projectLink) {
		var result = this.actionMethods.loadProjectLink({objectID:projectLink.objectID.uri});		
		result = eval("("+result+")");
		if(!result.loaded) {
			if(result.error == MEProjectLink.CouldNotAccessProject) {
				var me  = this;
				var onValidate = function(username, password, context) {
					result = me.actionMethods.loadProjectLink({objectID:projectLink.objectID.uri, username:username, password:password});		
					result = eval("("+result+")");
					return result.loaded;
				} 
				var title = stringWithFormat(this.environment.localizedString("Login to project '%@'"), projectLink.valueForKey('title'));
				runLoginDialog(title, onValidate, null, this.environment);		
			}else if(result.error == MEProjectLink.ProjectLinkCouldNotFindTargetProject) {
				runAlert(this.environment.localizedString("ProjectLinkCouldNotFindTargetProject"), null, this.environment.images.MerlinWarning);
			}
		}
		return result.loaded;
	},

	// ************************************************************************************************************
	// *****
	// *****										Test methods
	// *****
	
	selectActivities: function(activities) {
		this.outlineController.setSelectedObjects(activities);
		this.activitiesView.outlineDidChangeSelection();
		this.refresh();
		var rows = this.activitiesView.outlineView.selectedRows();
		this.activitiesView.outlineView.scrollToRow(rows[activities.length-1]);
	}
	
});
