var prefs = {
	zoom: 100, 
	save: function(name, value) {
		this[name] = value;
		Popegg.Cookie.setCookie(name, value);
	},
	load: function() {
		this.zoom = Popegg.Cookie.getCookie('zoom') || 100;	
	}
};

Collage.completeOpenIDLogin = function() {
	$egg('#dialog_content').dialog('close');
	$egg('#auth_button .label').html('');
    canvas.reload();
};

var Temp = Class.create(Collage.Canvas, Popegg.RESTSource, {
	initialize: function() {},
	
	property_names: ['id', 'title'],
	
	// user properties
	loggedIn: false,   
	target_item_id: "none",
	mode: 'canvas',  //canshare에 이용된다.
	firstSnap: true,
	prefs: null,
			
	_successRefresh: function() {
		var v = $('canvas');
		
		$egg('body')
		.setClass('inbox', this.id=='inbox')
		.setClass('top', this.isTop)
		.setClass('guest', !this.loggedIn)
		.setClass('ring', this.ring)
		.setClass('editable', this.editable);
		
		$egg('#tb-inbox-button').setClass('sel', this.id=='inbox');
		$egg('#tb-home-button').setClass('sel', this.isHome===true);
        
		document.title = this.title + " - POPEGG";
		
		$egg(".dyn-canvas-title-label").text(this.title);
		
		$egg('#auth_button .label').text(this.member_name);
	
		$egg('#tb-unread-filter').setClass('disabled', !this.loggedIn);
		
		if (this.title == null || this.title.length == 0 || this.title=='Untitled') {
			$egg('#tb-canvas-info').click();
		}
		//$egg('#tb-create-canvas').setClass('disabled', !this.loggedIn);

		if (this.prefs==null)
		{
		    this.prefs = {
		        zoom: parseInt(this.zoom, 10),
		        center: this.center
		    };
		    if (!this.prefs.zoom || this.prefs.zoom==0) this.prefs.zoom = prefs.zoom; //cookie
		    if (!this.prefs.center || this.prefs.center.split(',').length != 2) this.prefs.center = "2500,1500";
		}
		
        $egg('#canvas-zoom-slider').slider('value', this.prefs.zoom);        
        Collage.mainController.toCenter(this.prefs.center.split(',')); 
  
		app._resumeHashChangeMonitor();
		this.prefs = null; // 다음번 로드시 이용하기 위해		
	},
	
	_errorRefresh: function(error) {
		app.showMessage('오류가 발생하였습니다.', error);
		//app.openCanvas('top');
	},
	member_url: function() { 
		return "%@/%@".fmt(this.collection_url(), this.url); 
	},
	reload: function() {
		this.savePrefs();
		this.firstSnap = true;
		app._openCanvas();
	},
	savePrefs: function() {	
	    var params = {
	        'canvas_uid': this.uid,
		    'zoom': Collage.mainController.getZoom()		    
		};
		if (Collage.mainController._oldCenter)
		    params.center = Collage.mainController._oldCenter.join(",");
	    	
	    if (this.loggedIn) {
	        new Ajax.Request('/canvas/pref', {
    			parameters: params
    		});
	    }
		this.zoom = null;
		this.center = null;
	}
});
var canvas = new Temp();


var InspectorViewController = Class.create({
	////////////////////////////////////////
	//	Managing View
	//
	view:null,
	initialize: function() {	
		return this;	
	},

	attachView: function(path) {
		this.view = $egg(path.view);
		return this;
	},
	////////////////////////////////////////
	// Item Management
	//
	item: null,
	setCurrentItem: function(item) {
		this.item = item;
		if (item==null) return;
		
		/*
		//var itemView = $egg('#canvasitem-'+this.item.id);		
		//itemView.addClass('sel');
		
		// 맨 마지막에 스크롤해야 정상 포지션으로 이동
		if (itemView.length > 0) {
			var pos = itemView[0].positionedOffset();
			if (pos[1] > $egg('#comment-bar .widget-content').scrollTop() && pos[1] < $egg('#comment-bar .widget-content').scrollTop() + $egg('#comment-bar .widget-content').height()) {

			} else {
				//$egg('#comment-bar .widget-content').scrollTop(pos[1]-5);
				//console.log(Math.abs($egg('#comment-bar .widget-content').scrollTop() - pos[1]));
				if (Math.abs($egg('#comment-bar .widget-content').scrollTop() - pos[1])<$egg('#comment-bar').width()*3)
					$egg('#comment-bar .widget-content').animate({scrollTop:pos[1]-5}, 800);
				else
					$egg('#comment-bar .widget-content').scrollTop(pos[1]-5);
			}
		}
		*/
	},
	
	selectPrevItem: function() {
		this.view.find(".canvasitem.sel").prev().find(".canvasitem-title").click();
	},
	selectNextItem: function() {
		this.view.find(".canvasitem.sel").next().find(".canvasitem-title").click();
	},
	eventHandler: function(evt) {
		console.log(evt);
		console.log(evt.target);
		
		var target = $egg(evt.target);
		var itemView = null;
		
		if (target.is('.canvasitem')) {
		    itemView = target;
		    console.log(itemView);
		} else {
		    itemView = target.parents(".canvasitem");
		}
		
		if (!itemView || itemView.length == 0) return;
		//var itemId = itemView.attr('id').replace('canvasitem-', '');
		var itemIndex = itemView.index();
		
		//itemView.addClass('sel').siblings().removeClass('sel');

		if (evt.type == "click" || evt.type=="dblclick") {
		    if (target.is('.canvasitem .label')) {
                app.openCanvas(app.inboxItems[itemIndex].canvas_url);
            } else if (target.is('.canvasitem-thumbnail')){
                if ($egg('body').hasClass('preview_mode')) 
    				Collage.previewController._preview(app.inboxItems[itemIndex]);
    			else
    			    app.openDocument(app.inboxItems[itemIndex]);
            }
		    
		}
		
	},

	unlinkItem: function() {
		var subItem = this.item;
		if (subItem.ref_item_id==null) {
			alert('준비 중입니다.');
		}

		//TODO Find로 바꾸자
		var refItem = Collage.mainController.currentItem;
		
		if (subItem && refItem) {
			refItem.attach_count--;// = refItem.attach_count-1; // 하나 감소
			//subItem.ref_item_id = null; 조심하자.. 버그수정하자...
			
			Collage.mainController.indexingCells();
			Collage.mainController.updateItem(refItem);
			Collage.mainController.addItems([subItem], false);

			subItem.rUpdate(['ref_item_id']);
		}
	},
	
	///////////////////////////////////////////
	// Actions
	//
	openWebsite: function() {
		window.open(this.item.url);
	},
	download: function() {
		app.openDialog("다운로드", '/collage/download/%@'.fmt(this.item.uid));
		

	},
	

	//////////////////////////////////////////////////////
	//
	//
	messageCanvasItem: function(evt, data) {
		//delete의 경우 item이 사라지고 없다.
		if (data.action == "delete") {
			//$egg('#comment-bar #canvasitem-%@'.fmt(data.canvas_item_id)).remove();
			app.isDirtySnap = true;
			return;
		}
	}
});
Collage.itemController = new InspectorViewController();


function debug_frame(msg, f) {
	console.log("%@: %@,%@,%@,%@".fmt(msg, f.x, f.y, f.width, f.height));
};

var debug = {
    prevTime: 0,
    laptime: function(msg) {
        var t = new Date().getTime();
        console.log("%@:%@".fmt(msg, t-this.prevTime));
        this.prevTime = t;
    }
};


Collage.CanvasViewController = Class.create({

});

CanvasMixin = {};
var Canvas_DragDrop = {
	makeCanvasSmart: function() {
		var canvasView = $egg('#canvas2d');
		canvasView.addClass("-webkit-user-drop: element");
		
		canvasView.bind("dragenter", function(evt) {
			evt.originalEvent.preventDefault();
			//return true;
		});
		canvasView.bind("dragleave", function(evt) {
			evt.originalEvent.preventDefault(); 
		});
		canvasView.bind("dragover", function(evt) {
			evt.originalEvent.preventDefault();	
		});
		canvasView.bind("paste", function(evt) {
			evt.originalEvent.preventDefault();	
			console.log("PASTE");
		});
		canvasView.bind("drop", Collage.mainController.onSmartDrop.bind(this));
		//canvasView.bind("paste", Collage.mainController.onSmartDrop.bind(this));
	},
	onSmartDrop: function(e) {
		var evt = e.originalEvent;
		//console.log(evt);
		
		/***
		var e = evt;
		if (!!e.dataTransfer.types) {
			var dataTypes = e.dataTransfer.types;
			//console.log("TYPES:"+dataTypes.length);
			//console.log(dataTypes);
			try {
				for (var i = 0; i < dataTypes.length; i++) {
					var dtype = dataTypes[i];
					if (e.dataTransfer.getData(dtype)!==undefined) {
						//console.log("%@. %@=====>%@, %@".fmt(i, dtype));
						//console.log(e.dataTransfer.getData(dtype));
						//console.log(e.dataTransfer.getData(dtype).length);
					}
					//console.log(e.dataTransfer.getData(type));
				}
			
				console.log("=====>"+e.dataTransfer.getData("image/x-java-image"));
			} catch(e) {console.log(e);}
		}
		*/
		/*****
		console.log("==========================");
		console.log(evt.dataTransfer.getData("text/html"));
		console.log(evt.dataTransfer.getData("text/uri-list"));
		console.log(evt.dataTransfer.getData("text/uri-name"));
		console.log(evt.dataTransfer.files.item(0));
		****/
		evt.preventDefault();
		//alert(evt);
		// url 조사
		if (!canvas.loggedIn) {
			app.showMessage('로그인하세요.', "새 아이템을 올리시려면 로그인하세요.");
			return true;
		}
		var files = evt.dataTransfer.files;
		/***
		console.log(evt);
		console.log(evt.dataTransfer.getData("text/plain"));
		console.log(evt.dataTransfer.getData("url"));
		console.log(evt.dataTransfer.getData("text/uri-list"));
		console.log("============");
		
		for (var i=0; i<evt.dataTransfer.types.length; i++)
			console.log(evt.dataTransfer.types.item(i)+"====>"+evt.dataTransfer.getData(evt.dataTransfer.types.item(i)));
		console.log("===============");
		**/
		/*
		console.log(evt.dataTransfer.types.length);
		console.log(evt.dataTransfer.types.item(0));
		*/
		
		//return;
		
		if (files && files.length>0 && files.item(0).fileSize>0) {
			
			this.addFiles(files, this.fromGlobalFrameToCanvas({x:evt.clientX, y:evt.clientY, width:100, height:100}));
			
		} else {
			var image_url = this._image_url_from_uri_list(evt.dataTransfer);
			
			if (!image_url) image_url = this._image_url_from_text_html(evt.dataTransfer);
			if (!image_url) image_url = this._image_url_from_text_plain(evt.dataTransfer);
			
			
			if (!image_url) {
				var data = this._url_from_data_transfer(evt.dataTransfer);
				if (data && data.indexOf("http://")>=0) {
					var f = this.fromGlobalFrameToCanvas({x:e.pageX, y:e.pageY, width:0, height:0});
					f.width=100;
					f.height=100;
					var canvasItem = this.createTempCanvasItem(f);
					canvasItem._by_drop = true;
					canvasItem.resource_type = "RemoteItem"; //WebItem
					canvasItem.content_body = data;
					
					this.commitTempCanvasItem();
				} else {
					/**
					console.log("check");
					console.log(evt.dataTransfer.getData("application/x-moz-file")==null);
					console.log(evt.dataTransfer.getData("application/x-moz-file")==undefined);
					console.log(evt.dataTransfer.Files);
					**/
					var x_moz_file=evt.dataTransfer.getData("application/x-moz-file");
					
					if (x_moz_file!=null && x_moz_file!=undefined && !evt.dataTransfer.Files) {
						app.showMessage('안내', "드래그해서 파일올리기는 파이어폭스 3.6 이상에서 지원됩니다.");
					} else 
						app.showMessage('오류가 발생하였습니다.', "드래그 된 아이템에서 필요한 정보를 찾을 수 없습니다.");
					//<br/>링크가 걸려있는 이미지는 현재 드래그 앤 드롭을 지원하지 않습니다.<br/>PC에 다운로드 후 업로드하시거나 게시판을 더블클릭하여 이미지 주소를 입력해 주세요.
				}

			} else {
				var f = this.fromGlobalFrameToCanvas({x:e.pageX, y:e.pageY, width:0, height:0});
				f.width=100;
				f.height=100;
				var canvasItem = this.createTempCanvasItem(f);
				canvasItem.resource_type = "RemoteItem";  //ImageItem
				canvasItem.content_body = image_url;
				canvasItem._by_drop = true;
				this.commitTempCanvasItem();
				//this.content.replace(0,0,[canvasItem]);
				//canvasItem.rCreate();
			}
			//

		}
		return true;
	},
	
	_image_url_from_uri_list: function(dataTransfer) {
		var str = dataTransfer.getData("text/uri-list");
		if (str) {
			if (str.toLowerCase().match(/.+\.(jpg|gif|png)/)!=null) return str;
		}
		return null;
	},
	_image_url_from_text_html: function(dataTransfer) {
		var str = dataTransfer.getData("text/html");

		if (str && str.match(/src=["|'](.+?)["|']/)) {
			return str.match(/src=["|'](.+?)["|']/)[1];
		}
		return null;
	},
	_image_url_from_text_plain: function(dataTransfer) {
		var str = dataTransfer.getData("text/plain");
		if (str) {
			if (str.toLowerCase().match(/.+\.(jpg|gif|png)/)!=null) return str;
		}
		return null;
	},
	_url_from_data_transfer: function(dataTransfer) {
		var str = dataTransfer.getData("text/uri-list");
		if (!str) str = dataTransfer.getData("text/plain"); 
		
		return str;
	}	
};

var Canvas_Rendering = {
	applyUnreadFilter: false,
	setUnreadFilter: function(flag) {
		if (this.applyUnreadFilter != flag)
		{
			this.applyUnreadFilter = flag;
			this.updateAll();
		}
		
	},
	
	/////////////////////////////////////////
	// Rendering Queue
	//
	//

	
	_renderingRect: null,
	_renderingQueue: [],
	_renderingPointer: 0,
	_readyCount: 0,
	//_readyCount: 0,
	_renderingTimer: null,
	_initialRenderComplete: false,
	
	_renderingQueue_clearAll: function() {
		this._renderingQueue = [];
		this._renderingPointer = 0;
	},
	_renderingQueue_addItem: function(item, invalidateRect) {
		this._renderingQueue.push({'item':item, 'invalidateRect': invalidateRect});
	},
	_renderingQueue_dump: function() {
		var count = 0;
		var len = this._renderingQueue.length;
		for(var i=0;i<len;i++) 
			if (this._renderingQueue[i]._thumbnailReady > 0) count++;
		console.log("%@ / %@".fmt(count, len));
	},
	_flushRendered: function(rect) {
	    
	    console.log("FLUSH");
		if (!app.staticMode)
		{
		    from = this._renderingRect || {x:0, y:0, width:5000, height:3000};
		    frac = $('canvas2d').width / 5000;
		    to = {x:from.x*frac, y:from.y*frac, width:from.width*frac, height:from.height*frac};
		    
		    //debug_frame("from", from);
		    //debug_frame("to", to);

    		$('canvas2d').getContext('2d').clearRect(to.x,to.y,to.width, to.height);
    		$('canvas2d').getContext('2d').drawImage($('canvas-back'), from.x, from.y, from.width, from.height, to.x, to.y, to.width, to.height);
		}
	},
	_renderingQueue_readyItem: function(item) {
		var len = this._renderingQueue.length;
		this._readyCount++;
		
		
		var progress = this._readyCount / len;
		
		//console.log("%@ / %@ = %@".fmt(this._readyCount, len, progress));
		
		if (len>0)
            $egg('#load-progress').progressbar('value', this._readyCount * 100 / len);
        else
            $egg('#load-progress').progressbar('value', 100);

		$egg('#canvas2d').css({'opacity':progress});
		
		if (this._readyCount == this._renderingQueue.length) {
			setTimeout(this._renderingQueue_commit.bind(this), 0);
		}
	},
	_renderingQueue_commit: function(term) {
	    try {
	        var ctx = $('canvas-back').getContext('2d');
			var len = this._renderingQueue.length;
  
			if (this._readyCount == len /* && len>0 */) {
				clearTimeout(this._renderingTimer);
				this._renderingTimer = null;
				
				//debug.laptime("before render2d loop");
				for(var i=0;i<len;i++) {
    				var itemInfo = this._renderingQueue[i];
    				var item = itemInfo.item;
    				item.render2d(ctx, itemInfo.invalidateRect, this.applyUnreadFilter);		
    			}
    			//debug.laptime("end render2d loop");
    			
				this._renderingPointer = 0;
				this._renderingQueue = [];
				this._readyCount = 0;
                
                //debug.laptime("before render2d loop");
				console.log("RENDER COMMIT");
                this._flushRendered();
                //debug.laptime("after render2d loop");
                
				this.updateAllMap();
				//console.log("update-complete");
				this._initialRenderComplete = true;
				this._renderingRect = null;
				$egg('#load-progress').hide().progressbar('value', 0);//fadeOut(1000);
				$egg('#canvas2d').css({'opacity':1});	
				if ($egg('#focused-item').hasClass('resizing dragging')) {
					$egg('#focused-item').removeClass('resizing dragging');	
					$egg('#focus-border').removeClass('resizing dragging');
				}		
					
			} else {
				/*
				if (!term)
					this._renderingTimer = setTimeout(this._renderingQueue_commit.bind(this), 500);
				else
					this._renderingTimer = setTimeout(this._renderingQueue_commit.bind(this), 500);
				*/
			}
			
			/*
			var ctx = $('canvas2d').getContext('2d');
			var len = this._renderingQueue.length;
			
			//if (len >0 && this._renderingQueue.first().item._thumbnailReady==0) return;
			for(;this._renderingPointer<len;this._renderingPointer++) {
				var itemInfo = this._renderingQueue[this._renderingPointer];
				var item = itemInfo.item;
				if (item._thumbnailReady==0) break;
				item.render2d(ctx, itemInfo.invalidateRect);		
			}
			
			console.log("%@ / %@".fmt(this._renderingPointer, len));
            
			// 전부다 그렸으면
			var remains = this._renderingQueue.slice(this._renderingPointer);
			this._renderingPointer = 0;
			this._renderingQueue = remains;
			
			var count = $egg('#load-progress').data('count');
			if (count>0)
                $egg('#load-progress').progressbar('value', (count-remains.length) * 100 /$egg('#load-progress').data('count'));
            else
                $egg('#load-progress').progressbar('value', 100);
                
			if (remains.length == 0) {
				clearTimeout(this._renderingTimer);
				this._renderingTimer = null;
                
                $('canvas-back').getContext('2d').clearRect(0,0,5000,3000);
				this.updateAllMap();
				//console.log("update-complete");
				this._initialRenderComplete = true;
				$egg('#load-progress').fadeOut(1000);
			} else {
				if (!term)
					this._renderingTimer = setTimeout(this._renderingQueue_commit.bind(this), 500);
				else
					this._renderingTimer = setTimeout(this._renderingQueue_commit.bind(this), 500);
				
			}
			**/
		} catch(e) { console.log(e); }
	}
};


var Canvas_Append = {
	////////////////////////////////////////////////////////
	// Handling Temporary Item
	//
	tempCanvasItem: null, 	
	tempid: function() {
		return "temp-%@".fmt(new Date().getTime());
	},
	createTempCanvasItem: function(metric) {
		var canvasItem = new Collage.CanvasItem().initWithObject({
			id: null,
			temp_id: this.tempid(),
			title: 'untitled',
			resource_type: 'Temporary',
			isTemporaryItem: true,
			resource_id: null,
			canvas_id: canvas.id,
			timestamp: Math.floor(new Date().getTime() / 1000),
			thumbnail: "/images/nocover.jpg",
			large_thumb: "/images/nocover.jpg",
			content_body: null,
			metric: {x:metric.x, y:metric.y, width:metric.width, height:metric.height},
			inner_bound: {x:0, y:0, width:metric.width*10, height:metric.height*10} 
		});			
		this.tempCanvasItem = canvasItem;	
		canvasItem._temporaryMetric = true;
		
		this.addItems([canvasItem]);
		return canvasItem;
		// temp item은 한번에 하나만 존재 main_controller의 member로 존재
	},
	removeTempCanvasItem: function() {
		var temp = this.tempCanvasItem;
		console.log("removeTempCanvasItem");
		console.log(temp);
		if (temp.resource_type=='Temporary' /*|| (!temp._file && !temp.id)*/) {
			this.removeItems([temp]);
			if (temp == this.currentItem) this.selectItem(null);
		}
		this.tempCanvasItem = null;
	},
	commitTempCanvasItem: function() {
		var canvasItem = this.tempCanvasItem;
		if (canvasItem) {
			canvasItem.isTemporaryItem = false;
			$egg("#inspector").addClass('uploading');
			canvasItem.metric_str = canvasItem.get_metric_str();
			canvasItem._successCreate = this.successCreateCanvasItem.bind(this);
			canvasItem._failCreate = this.failCreateCanvasItem.bind(this);
			canvasItem.uploadStatusMessage = "올리는 중";
			canvasItem.uploadStatus = "CONVERTING";
			canvasItem.uploadRatio = 100;
			app.sendMessage("canvasitem", {action:"update_upload_status", canvas_item_id:canvasItem.id});
			
			canvasItem.rCreate();
		}
	},
	failCreateCanvasItem: function(error) {
		$egg('#inspector .error').html(error);
		
		this.tempCanvasItem.resource_type = "Temporary";
		this.tempCanvasItem.isTemporaryItem = true;
		
		
		this.tempCanvasItem.uploadStatusMessage = "완료";
		this.tempCanvasItem.uploadStatus = "COMPLETE";
		app.sendMessage("canvasitem", {action:"update_upload_status", canvas_item_id:this.tempCanvasItem.id});
		$egg("#inspector").removeClass('uploading');
	},
	successCreateCanvasItem: function(canvasItem) {
		
		//$egg("#comment-bar #canvasitem-%@".fmt(canvasItem.temp_id)).attr('id', "canvasitem-%@".fmt(canvasItem.id));
		//canvasItem.temp_id = null;
		if (this.currentItem == canvasItem)
		{	
			$egg('#inspector')
			.removeClass(INSPECTOR_MODES)
			.addClass(canvasItem.resource_type)
			.setClass('buttonmode', canvasItem.resource_type!='LabelItem')
			.setClass('editable', canvasItem.editable);			
				
    		$egg("#inspector input.shadow").attr('checked', canvasItem.visual_style.vshadow);
        	$egg("#inspector input.border").attr('checked', canvasItem.visual_style.vborder);
        	$egg("#inspector input.title").attr('checked', canvasItem.visual_style.vshow_title);	
				
        	$egg("#inspector .upload_info .progress").progressbar('value', canvasItem.uploadRatio);
        	$egg("#inspector .upload_info .message").html(canvasItem.uploadStatusMessage);
        	$egg('#inspector').setClass("uploading", !(!canvasItem.uploadStatus || canvasItem.uploadStatus=="COMPLETE")); 
        		
    		$egg('#tb-delete-canvasitem').setClass('disabled', !canvasItem.deletable);
			$egg("#tb-download-canvasitem").setClass("disabled", !canvasItem.resource_type.oneOf("ImageItem DocItem"));
			$egg("#tb-share-canvasitem").setClass("disabled", !canvasItem.resource_type.oneOf("ImageItem DocItem BookItem WebItem MovieItem NoteItem") || !canvas.loggedIn);
		}
		$egg("#inspector").removeClass(INSPECTOR_MODES).addClass('buttonmode').find('.widget-form').empty();
		
		
		if (canvasItem.resource_type=='DocItem') {
			//TODO 이미 변환된 이미지는 listen하지 않도록하자
			//Popegg.DocItemListener.listen({id:parseInt(canvasItem.resource_id, 10), convert_progress:'complete'}, canvasItem.updateThumbnail.bind(canvasItem));
			//canvasItem.uploadStatusMessage = "완료";
			//canvasItem.uploadStatus = "COMPLETE";
			
		} else if (canvasItem.resource_type=='WebItem') {
			this.uploadStatusMessage = "변환 중";
			this.uploadStatus = "CONVERTING";
			
			Popegg.DocItemListener.listen({id:parseInt(canvasItem.resource_id, 10), convert_progress:'complete'}, canvasItem.uploadAndCreateComplete.bind(canvasItem));
			
		} else {
			canvasItem.uploadStatusMessage = "완료";
			canvasItem.uploadStatus = "COMPLETE";
		}
		app.sendMessage("canvasitem", {action:"update", canvas_item_id:canvasItem.id});
		app.sendMessage("canvasitem", {action:"update_upload_status", canvas_item_id:canvasItem.id});
		
		this.indexingCells();
		this.updateItem(canvasItem, true);
		this.selectItem(); // 변경사항 반영하기 위해
	},
	
	add_image_by_url: function(url) {
		var item = this.tempCanvasItem; 
		//var item = this.createTempCanvasItem();
		if (!item) return;
		item.isTemporaryItem = false;
		item.resource_type = "ImageItem";
		item.content_body = url;
		item._temporaryMetric = true;
		this.commitTempCanvasItem();
		//this.updateItem(item);
	},
	add_image_by_file: function() {
		
	},
	add_movie_by_url: function(url) {
		var item = this.tempCanvasItem; 
		if (!item) return;
		item.resource_type = "MovieItem";
		item.isTemporaryItem = false;
		item.content_body = url;
		this.commitTempCanvasItem();
		//this.updateItem(item);
	},
	add_web_by_url: function(url) {
		var item = this.tempCanvasItem; 
		if (!item) return;
		item.resource_type = "WebItem";
		item.isTemporaryItem = false;
		item.content_body = url;
		item._temporaryMetric = true;
		this.commitTempCanvasItem();
		
		//this.updateItem(item);
	},
	add_book_by_search: function(bookinfo) {
		var item = this.tempCanvasItem; 
		//var item = this.createTempCanvasItem();
		if (!item) return;
		console.log(bookinfo);
		
		//Object.extend(item, bookinfo);
		item.resource_type = "BookItem";
		item.isTemporaryItem = false;
		item.content_body = bookinfo;
		item._temporaryMetric = true;
		this.commitTempCanvasItem();
		//this.updateItem(item);
	},
	add_label: function(text, colorStr) {
		var item = this.tempCanvasItem; 
		if (!item) return;
		console.log(colorStr);
		item.resource_type="LabelItem";
		item.isTemporaryItem = false;
		item.metric.height = 48;
		item.metric.width = 300;				
		item.content_body = text;
		item.color = colorStr;// || 'white,black';
		item._temporaryMetric = false;
		this.commitTempCanvasItem();
		//this.updateItem(item);
	},
	addFiles: function(files, rect) {
		console.log("Drop FILE:");
		console.log(rect);
		if (files && files.length>0 && files.item(0).fileSize>0) {
			for (var i=0;i<1;i++) {
				var f = rect || {x:2000, y:1000, width:100, height:100};
				var file = files.item(i);
				
				var canvasItem = new Collage.CanvasItem().initWithObject({
					id: null,
					temp_id: this.tempid(),
					title: file.fileName.split('.')[0],
					resource_id: null,
					canvas_id: canvas.id,
					timestamp: Math.floor(new Date().getTime() / 1000),
					thumbnail: "/images/nocover.jpg",
					large_thumb: "/images/nocover.jpg",
					content_body: null,
					editable: true,
					//vshow_title: true,
					metric: {x:f.x+i*30, y:f.y+i*30, width:100, height:100 },
					inner_bound: {x:0, y:0, width:100*10, height:100*10},
					
					_temporaryMetric: true,
					_by_drop: true
				});
				canvasItem.metric_str = canvasItem.get_metric_str();
				$egg('#inspector').addClass('uploading');
				if (file.fileName.toLowerCase().match(/.+\.(jpg|jpeg|gif|png)/)!=null) {
					canvasItem.resource_type='ImageItem';
				} else if (file.fileName.toLowerCase().match(/.+\.(pdf|ppt|pptx|xls|xlsx|doc|docx|rtf)/)!=null) {
					canvasItem.resource_type='DocItem';
				} else {
					app.showMessage('지원하지 않는 형식입니다.', "현재는 이미지 파일들과 문서파일 중 pdf, ppt, xls, doc만을 지원하고 있습니다.");
					return;
				}
				this.addItems([canvasItem]);
				canvasItem._file = file;		
				canvasItem.startUpload();	
			}
		}
	}
};
Collage.MainController = Class.create(Canvas_DragDrop, Canvas_Rendering, Canvas_Append, {
	////////////////////////////////////////////////////////
	// Initialize
	//
	initialize: function() {
		//arguments.callee.base.apply(this,arguments) ;
	},

	
	////////////////////////////////////////////////////////
	//  ITEM POSITION & METRIC  (Low level)
	//
	itemForEvent: function(evt) {
		//var loc = this.fromGlobalFrameToCanvas({x:evt.x, y:evt.y});
		
		// 축소가 안되어 있는 이미지 이므로 변환없이 바로 
		var loc = this.fromGlobalFrameToCanvas({x:evt.clientX, y:evt.clientY}, 1);
		//var loc = {x:evt.clientX, y:evt.clientY};
		
		/******
		var ctx = $('canvas2d').getContext('2d');
		console.log("RAW_MOUSEDOWN:%@,%@".fmt(loc.x, loc.y));
		
		try {
		    var imageData = ctx.getImageData(loc.x-1, loc.y-1, 3, 3);
            console.log(imageData.data);
    	    var transparent = true;
    	    for(var i=3;i<4*9;i+=4) {
    	        if (imageData.data[i] != 0) {
    	            transparent = false;
    	            break;
    	        }
    	    }
    	    if (transparent) return null;
		} catch (e) { console.log(e); }
	    *****/
	    
        loc = this.fromGlobalFrameToCanvas({x:evt.clientX, y:evt.clientY}, null);
        
		var r=Math.floor(loc.y/this._snapY);
		var c=Math.floor(loc.x/this._snapX);

		//var itemIndices = this._drawingCells[r][c];
		var indices = this.getItemIndicesInCell(r, c);
		if (!indices) return null;

		indices = indices.sortBy( function(idx) {return -idx;});
		var idx = indices.length;

		while (--idx>=0) {
			var item = this.content[indices[idx]];
			if (item) {
			    //debug_frame("metric", item.metric);
			    //debug_frame("bounds", item.activeFrame());
				//var m = item.metric;
				var m = item.activeFrame();
				var f = {x:m.x, y:m.y, width:m.width, height:m.height};

				if ($egg.pointInRect(loc, f)) return item;
			} else {
				console.log("itemForEvent:null");
			}
		}
		return null;
	},
	getCellRectByItem: function(item, margin) {
		if (margin === undefined) margin = {top:5, bottom:27, left:10, right:15};
		
		var m = item.metric;
		var startCol = Math.floor((m.x-margin.left)/this._snapX);
		var endCol = Math.floor((m.x+m.width+(margin.left+margin.right))/this._snapX);
		var startRow = Math.floor((m.y-margin.top)/this._snapY);
		var endRow = Math.floor((m.y+m.height+(margin.top+margin.bottom))/this._snapY);
		
		return {startCol: startCol, startRow:startRow, endCol:endCol, endRow:endRow};
	},
	getItemIndicesInCell: function(aRow, aCol) {
		var row = this._drawingCells[aRow];
		if (!row) {
			console.log("check getItemIndicesInCell");
			return;
		}
		var indices = row[aCol];
		if (!indices) return [];
		else return indices;
	},
	getItemsInCell: function(row, col) {
		var indices = this.getItemIndicesInCell(row, col);
		return indices.map(function(idx) { return this.content[idx]; }.bind(this));
	},
	getGlobalFrameOfItemView: function(view) {
		var canvasItemView = view;
		var canvasView = canvasItemView.parentNode;
		var canvasScrollView = canvasView.parentNode;
		//anchor.recacheFrames();
		// anchor -> canvasItem
		//origin = canvasItemView.convertFrameFromView(anchor.get('frame'), anchor);
		origin = canvasItemView.get('frame');
		// canvasItem -> canvas
		origin = canvasItemView.convertFrameToView(origin, canvasView);
		// adjust for zoom
		var z = EGGCss.getZoom(canvasView);
		origin.x *= z; origin.y *= z; origin.width *= z; origin.height *= z;
		// canvas -> scroll
		origin = canvasView.convertFrameToView(origin, canvasScrollView);
		// scroll -> global
		
		origin.x = Math.floor(origin.x); origin.y = Math.floor(origin.y);
		origin.width = Math.floor(origin.width); origin.height = Math.floor(origin.height);
		
		return EGGMetrics.convertToGlobal(canvasScrollView, origin);
	},
	fromGlobalFrameToCanvas: function(f, zoom) {
		try {
			var canvasView = this;

			var offset = $egg('#main-view').offset();
			f.x-=offset.left; f.y-=offset.top;
			f.x+=$egg('#main-view').scrollLeft();
			f.y+=$egg('#main-view').scrollTop();
			
			var z = (zoom || this.getZoom()/100);

			// zoom 적용
			f.x = Math.floor(f.x/z); f.y = Math.floor(f.y/z); 
			f.width = Math.floor(f.width/z); f.height = Math.floor(f.height/z);
		}catch(e) {
			console.log(e);
		}
		return f;
	},
	getCanvasItemFrame: function(item) {
		var m = item.metric;
		if (!m) return m; // canvas일 경우가 많음.
		var f = {x:m.x, y:m.y, width:m.width, height:m.height};
		
		var z = Collage.mainController.getZoom();
		//var border = parseInt($egg('#focused-item').css('border-width'), 10);
		var border = 6;
		f.x=Math.floor(f.x*z/100)-border; 
		f.y=Math.floor(f.y*z/100)-border; 
		f.width=Math.round(f.width*z/100+0.5)+border*2;
		f.height=Math.round(f.height*z/100+0.5)+border*2;
		// canvas -> scroll
		return f;
	},
	getCanvasItemActiveFrame: function(item) {
		var m = item.activeFrame();
		if (!m) return m; // canvas일 경우가 많음.
		var f = {x:m.x, y:m.y, width:m.width, height:m.height};
		
		var z = Collage.mainController.getZoom();
		//var border = parseInt($egg('#focused-item').css('border-width'), 10);
		var border = 6;
		f.x=Math.floor(f.x*z/100)-border; 
		f.y=Math.floor(f.y*z/100)-border; 
		f.width=Math.round(f.width*z/100+0.5)+border*2;
		f.height=Math.round(f.height*z/100+0.5)+border*2;
		// canvas -> scroll
		return f;
	},
	getGlobalCanvasItemFrame: function(item) {
		if (!item) return null;
		var f=this.getCanvasItemFrame(item);
		f = this.parentNode.convertFrameFromView(f, this);
		f = this.parentNode.convertFrameToView(f, null);
		return f;
	},
	
	////////////////////////////////////////////////////////
	//  MAP
	//
	updateAllMap: function() {
		try {
		    this.updateMap(0,0,5000,3000);
    		app.snapCanvas(false);
		} catch(e) { console.log(e); }
		
	},
	updateMap: function(dx, dy, dw, dh) {
		var map = $("map-canvas");
		if (!app.staticMode)
		{
		    if (map) {
    			mapCtx = map.getContext("2d");
    			var rx = map.width/5000;
    			var ry = map.height/3000;
    			mapCtx.clearRect(dx*rx, dy*ry, dw*rx, dh*ry);
    			try {
    			if ($('canvas-back')) {
    				mapCtx.drawImage($('canvas-back'), dx, dy, dw, dh, dx*rx, dy*ry, dw*rx, dh*ry);
    			}
    			} catch(e) { console.log(e); }
    		} 
		}
		else
		{
		    //map.src = $('canvas2d').src;
		    map.src = canvas.thumbnail;
		}
		
	},
	clearAll: function() {
	    this._initialRenderComplete = false;
		
		if (!app.staticMode) 
		{
		    $('map-canvas').getContext('2d').clearRect(0,0,500,300);
		}
	},
	getData: function() {
		return $('canvas2d').toDataURL();
	},
	////////////////////////////////////////////////////////
	// View Updates
	//
	// 있던 것들 제거할 때
	updateItem: function(item, fReloadImage) {
		//this.indexingCells(); //TODO 여기 꼭 잡자
		if (fReloadImage==true) 
			item.removeImage();
		
		this.invalidateCellsByItem(item);
	
		this.selectedItem_reposition();
		app.isDirtySnap = true;
		//SC.page.focusedItemView.updateCover();	
	},
	hideItem: function(item) {
		if (!item) return;
		//if (item._visible) {
			item._visible = false;
			this.invalidateCellsByItem(item);
		//}
 	},
	showItem: function(item) {
		if (!item) {
			console.log("show item null");
			return;
		}
		//if (!item._visible) {
			item._visible = true;
			this.invalidateCellsByItem(item);
		//}
 	},
	
	updateAll: function(fullUpdate) {
		this._renderingQueue_clearAll();
		
		var map = $("map-canvas");
		if (map && map.getContext) map.getContext("2d").clearRect(0,0,180,108);;
			
		this.indexingCells();
		
		if (!app.staticMode)
		{
		    //var ctx = $('canvas2d').getContext('2d');  
    		var ctx = $('canvas-back').getContext('2d');  


    		ctx.clearRect(0,0,$('canvas-back').width, $('canvas-back').height);
    		//ctx.clearRect(0,0,5000,3000);

			this.indexingCells();
			
			var len = this.content.length;
    		for(var idx=0;idx<len;idx++) {
    			var item = this.content[idx];
    			var cellRect = this.getCellRectByItem(item, {top:5, bottom:27, left:10, right:15});
    			var f = {
    				x: this._snapX*cellRect.startCol,
    				y: this._snapY*cellRect.startRow,
    				width: (cellRect.endCol-cellRect.startCol+1)*this._snapX,
    				height: (cellRect.endRow-cellRect.startRow+1)*this._snapY
    			};
				this._renderingQueue_addItem(item, f);
    		}
			for(var idx=0;idx<len;idx++) {
				var item = this.content[idx];
				item.prepareRendering(ctx, f);
			}


			/****
            var len = this.content.length;
    		for(var idx=0;idx<len;idx++) {
    			//console.log(item);
    			var item = this.content[idx];
    			var cellRect = this.getCellRectByItem(item, {top:5, bottom:27, left:10, right:15});
    			var f = {
    				x: this._snapX*cellRect.startCol,
    				y: this._snapY*cellRect.startRow,
    				width: (cellRect.endCol-cellRect.startCol+1)*this._snapX,
    				height: (cellRect.endRow-cellRect.startRow+1)*this._snapY
    			};
    			item.prepareRendering(ctx, f);
    		}
    		// 초기 사이즈가 잘 안맞는 것들 다시 ... flag가 set되었을 때만 돌도록 다시처리하자
    		this.indexingCells();
    		for(var idx=0;idx<len;idx++) {
    			var item = this.content[idx];
    			var cellRect = this.getCellRectByItem(item, {top:5, bottom:27, left:10, right:15});
    			var f = {
    				x: this._snapX*cellRect.startCol,
    				y: this._snapY*cellRect.startRow,
    				width: (cellRect.endCol-cellRect.startCol+1)*this._snapX,
    				height: (cellRect.endRow-cellRect.startRow+1)*this._snapY
    			};
    			this._renderingQueue_addItem(item, f);
    		}
			****/
    		//console.log("COMMMMMMMITTTTTTT:" + this._renderingQueue.length);
    		app.startTime = new Date().getTime();
			console.log("UPDATE ALL");
    		//this._renderingQueue_commit(100);
		} else {
		    $egg('#load-progress').progressbar('value', 100);
		    $egg('#load-progress').fadeOut(1000);
			$egg('#canvas2d').css({opacity:1});
		    this.updateAllMap();
		}
		
		return;
	},
		
	invalidateCellsByItem: function(item) {
	    if (!!app.staticMode) return;
	
		// 아이템이 점유한 cell들을 구한다.
		var cellRect = this.getCellRectByItem(item, {top:5, bottom:27, left:10, right:15});
		// 해당 cell에 포함된 index들을 구한다.
		var indices = [];
		//debug.laptime("before scan cells");
		for (var r=cellRect.startRow; r<=cellRect.endRow; r++) {
			for (var c=cellRect.startCol;c<=cellRect.endCol;c++) {
				indices = indices.concat(this.getItemIndicesInCell(r, c));
			}
		}
		//debug.laptime("after scan cells");
		indices = indices.uniq().sortBy( function(idx) {return -idx;}); // 중복을 제거한다
        //debug.laptime("after sort items");
		// CellRect에 해당하는 Frame을 가져온다.
		var f = {
			x: this._snapX*cellRect.startCol,
			y: this._snapY*cellRect.startRow,
			width: (cellRect.endCol-cellRect.startCol+1)*this._snapX,
			height: (cellRect.endRow-cellRect.startRow+1)*this._snapY
		};
		// frame을 지운다.
		
		// -frame에 다라 clip한다.
		//var ctx = $('canvas2d').getContext('2d');
		var ctx = $('canvas-back').getContext('2d');
		if (f.x == NaN) {
		} else {
		    ctx.clearRect(f.x, f.y, f.width, f.height);
		}
        //debug.laptime("after clear rect");
		// -item들을 다시 그린다.
		var items = indices.map(function(idx) { return this.content[idx]; }.bind(this));
		var len = items.length;
		for(var i=0;i<len;i++) {
			var item = items[i];
			if (!!item) {
				this._renderingQueue_addItem(item, f);				
			}
		};	
		for(var i=0;i<len;i++) {
			var item = items[i];
			if (!!item) {
				item.prepareRendering(ctx, f);
			}
		};
		
		//debug.laptime("after queuing items");
		this._renderingRect = f;
		console.log("invalidateCellsByItem");
		//this._renderingQueue_commit(100);

	},
	/////////////////////////////////////////
	// Indexing Items & Cells
	//
	_snapX: 100, _snapY:100,
	_drawingCells: [],	
	indexingCells: function() {
		this._drawingCells = [];
		var rows = Math.floor(3000/this._snapY) + 1;
		for(var r=0;r<rows;r++) this._drawingCells[r] = [];		
		var len = this.content.length;
		for (var i=0;i<len;i++) {			
			var item = this.content[i];	
			var cellRect = this.getCellRectByItem(item);
			for (var r=cellRect.startRow; r<=cellRect.endRow; r++) {
				var drawingRow = this._drawingCells[r];
				if (drawingRow) {
					for (var c=cellRect.startCol;c<=cellRect.endCol;c++) {
						if (!drawingRow[c]) drawingRow[c] = [];
						drawingRow[c].push(i);
						//console.log("%@,%@:%@".fmt(r,c,i));
					}
				} else {
					//캔버스를 넘어서면.... 
					/*
					console.log("indexingCells");
					console.log(r);
					console.log(this._drawingCells.length);
					*/
				}
			}
		}
	},
	addItems: function(items, autoSelect) {
		var len = items.length;
		
		for(var i=0; i<len;i++) {
			this.content.push(items[i]);
		}
		// view 처리
		if (autoSelect!==false)
			this.selectItem(items.first());
		
		// _drawingCells에 포함되어 있지 않으면 포함해 준다.
		/**TT
		for (var i=0;i<len;i++) {
			var item = items[i];	
			var cellRect = this.getCellRectByItem(item);
			//TODO 중복제거 해야할까?
			for (var r=cellRect.startRow; r<=cellRect.endRow; r++) {
				var drawingRow = this._drawingCells[r];
				for (var c=cellRect.startCol;c<=cellRect.endCol;c++) {
					if (!drawingRow[c]) drawingRow[c] = [];
					drawingRow[c].push(i);					
				}
			}
		}
		// 여기버그 꼭 잡자
		**/
		this.indexingCells();
		for(var i=0; i<len;i++) {
			this.invalidateCellsByItem(items[i]);
		}
	},
	removeItems: function(items) {
		// drawing 되지 않도록 막고
		items.each(function(item) {item._visible=false;});
		var idx = items.length;
		while(--idx>=0) {
			this.invalidateCellsByItem(items[idx]); // 화면에서 제거
			$egg('#chat-balloon-view .chat-item-%@'.fmt(items[idx].uid)).remove();
		}
		var len = items.length;
		for(var i=0;i<len;i++) {
			this.content.removeObject(items[i]);
			console.log("removeItems:"+items[i].temp_id);
			if (items[i].temp_id) {
				$egg('#comment-bar .widget-content #canvasitem-%@'.fmt(items[i].temp_id)).remove();
			}
		}
		this.indexingCells();
	},
	
	////////////////////////////////////////////////////////
	// view controller
	//
	attachView: function(path) {
	    var slider_opts = {max:100, min:30, step:5};
	    
	    if (!!app.staticMode) {
	        slider_opts = {max:40, min:20, step:5};
	    }
		$egg('#canvas-zoom-slider').slider(slider_opts).bind( "slide", function(evt, ui) {
			Collage.mainController.setZoom(ui.value);
		}).bind('slidechange', function(evt, ui) {
			Collage.mainController.setZoom(ui.value);
		});;

		$egg('#map #viewport').mousedown(function(evt) {
		    evt.stopPropagation();
		})
		.draggable({ containment: 'parent', scroll:false }).bind('drag', function(evt, ui) {
			var cf = {x:0, y:0, width:5000, height:3000};
			var z = Collage.mainController.getZoom()/100;
			if (!z) z=1;
			var loc = {x:ui.position.left, y:ui.position.top};
			//debug_frame(loc, "mouse position");

			var t = cf.width / $egg('#map').width();
			var pt = {x:loc.x*t*z, y: loc.y*t*z};
			if (pt.x<0) pt.x = 0;
			if (pt.y<0) pt.y = 0;

			$egg("#main-view").scrollLeft(pt.x).scrollTop(pt.y);
		});

        $egg('#map').mousedown(function(evt) {
           var loc = [evt.pageX-$egg(this).offset().left, evt.pageY-$egg(this).offset().top];

           loc[0] *= 5000/$egg(this).width();
           loc[1] *= 3000/$egg(this).height();
           
           Collage.mainController.toCenter(loc, true);
        });
		var _canvasDragPos = {x:0, y:0};

        if (!app.staticMode)
        {
            $egg("#focused-item")
    			.draggable().bind({
    				dragstart: this.selectedItem_startDrag.bind(this),
    				dragstop: this.selectedItem_endDrag.bind(this),
    				drag: this.selectedItem_drag.bind(this),
    				dblclick: this.selectedItem_dblClick.bind(this)
    			})
    			.resizable({handles:"se"/*, alsoResize: "#focused-item .cover"*/}).bind({
    				/*resizestart : function(evt, ui) {  
    					ui.position.left += $egg(this).parent().scrollLeft();
    					ui.position.top += $egg(this).parent().scrollTop();
    					Collage.mainController.
    				},*/
    				resizestart: this.selectedItem_startResize.bind(this),
    				resizestop: this.selectedItem_endResize.bind(this),
    				resize: this.selectedItem_repaint.bind(this)
    				//resize: function(evt, ui) { 
    				//}
    			})
    			;
        }
		else
		{
		    $egg("#focused-item").bind({
    				dblclick: this.selectedItem_dblClick.bind(this)
    			});
		}
		
			
		
		$egg("#main-view")
			.bind({
				scroll: function() {
					var z = Collage.mainController.getZoom()/100;
					if (!z) z=1;

					var cf = {x:0, y:0, width:5000, height:3000};
					//var cvf = SC.page.mainView.get('innerFrame');
					var cvf = {width:$egg("#main-view").width(), height:$egg("#main-view").height()};
					cvf.x = $egg(this).scrollLeft()/z; cvf.y = $egg(this).scrollTop()/z;  //offset

					var fr = $egg('#map').width()/ cf.width;
					var mvf = {x:cvf.x*fr, y:cvf.y*fr, width:cvf.width*fr/z, height:cvf.height*fr/z};

					$egg('#map #viewport').width(mvf.width).height(mvf.height).css({left:"%@px".fmt(mvf.x), top:"%@px".fmt(mvf.y)});
					Collage.mainController.cache_center();
				},
				resize: this.canvas_resize.bind(this)				
			})
			.draggable({scroll:false, helper: function() { 
				var elem = document.createElement("DIV"); 
				elem.style.cssText = "position:absolute; width:10px; height:10px; background:transparent";
				return elem;
			}})
			.bind({
				drag: function(evt, ui) { 
					evt.stopPropagation();
					/*var elem = $egg("#main-view")[0];				
					elem.scrollTop = _canvasDragPos.y-ui.position.top;
					elem.scrollLeft = _canvasDragPos.x - ui.position.left;*/
					try {
					    $egg("#main-view").scrollLeft(_canvasDragPos.x - ui.position.left).scrollTop(_canvasDragPos.y-ui.position.top);
					} catch(e) {
					    console.log(e);
					}
					
				},
				dragstart: function(evt, ui) {
					evt.stopPropagation();
					_canvasDragPos.x = $egg("#main-view").scrollLeft();
					_canvasDragPos.y = $egg("#main-view").scrollTop();
				}
			});

		
		//Event.observe($('main-view'), "mousewheel", function(evt) { console.log(evt); }, false); 
		
		$egg('#canvas2d').bind({
			mousedown: this.canvas_mousedown.bind(this)
		});
		
	},
	///////////////////////////////////////////////////////////
	// CANVAS EVENT
	//
	cache_center: function() {
		var mainview = $egg('#main-view');
		var sf = {x: mainview.scrollLeft(), y: mainview.scrollTop() }; //SC.page.mainView.get('scrollFrame');
		var f = mainview.frame(); //SC.page.mainView.get('frame');
		var midX = sf.x+f.width/2;
		var midY = sf.y+f.height/2;
		var z =this.getZoom();
		midX = Math.ceil(midX * 100 / z);
		midY = Math.ceil(midY * 100 / z);	
		
		var center = [midX, midY];		
		this._oldCenter = center;
	},
	canvas_resize: function(evt) {
		var mainview = $egg('#main-view');
		//console.log("main-view width:%@".fmt(mainview.width()))
	    var z = this.getZoom()/100;
		var x = this._oldCenter[0]*z - mainview.width()/2;
		var y = this._oldCenter[1]*z - mainview.height()/2;
		//console.log("%@ - %@ = %@".fmt(mainview.width()/2, this._oldCenter[0]*z, x));
		mainview.scrollLeft(x).scrollTop(y);		
	},
	canvas_mousedown: function(evt) {
		var item = this.itemForEvent(evt);        
        var loc = this.fromGlobalFrameToCanvas({x:evt.clientX, y:evt.clientY});
               
		if (item) {
			this.selectItem(item);
			evt.preventDefault();
			evt.stopPropagation();
			
			var element = $egg('#focused-item')[0];
			var event;
			if (document.createEvent) {
				event = document.createEvent("MouseEvents");
				event.initMouseEvent("mousedown", true, true, window, 1, 0, 0, evt.originalEvent.clientX, evt.originalEvent.clientY, false, false, false, false, 0, null);
				element.dispatchEvent(event);
				
			}	
		} else {
			this.selectItem(null);
		}
	},
	
	canvas_widget_drop: function(evt, ui) {
	    
	    if (!!app.staticMode)
	    {
	        app.openDialog('브라우저 안내', '/help/browser_warning');
	        return true;
	    }
	    
	    if (!canvas.loggedIn) {
			app.showMessage('로그인하세요.', "새 아이템을 올리시려면 로그인하세요.");
			return true;
		}
		
	    var loc = {x:ui.offset.left, y:ui.offset.top};
	    var rect = $egg('#canvas_main').frame();
	    rect.x = $egg('#canvas_main').offset().left;
	    rect.y = $egg('#canvas_main').offset().top;
	    
	    if ( !$egg.pointInRect(loc, rect) ) return;
	    
	    var f = this.fromGlobalFrameToCanvas({x:ui.offset.left, y:ui.offset.top});
		// 해당 point에 임시 canvas item 만들고 resource panel 띄운다.
		f.width = 100; f.height = 100;
		
		var target = $egg(evt.target);

		var tempItem = this.createTempCanvasItem(f);
		
		var offset = $egg('#focused-item').offset();
		var z = parseInt(this.getZoom(), 10);
		offset.left += (z+10);
		offset.top = Math.max(0, offset.top-20);
		
		

		if (target.is('.note-widget .widget-icon'))
		{
		    var self = this;
    	    $egg.post('/canvas/create_note', {
    	        x: f.x,
    	        y: f.y,
    	        canvas_id: canvas.id
    	        
    	    }, function(data) {
    	        if (data && !!data.id)
    	        {
    	            var canvasItem = new Collage.CanvasItem().initWithObject(data);			
            		canvasItem._temporaryMetric = false;
            		self.addItems([canvasItem]);
    	        }
    	        else
    	        {
    	            console.log("FAIL");
    	        }
    	    });
    		return;
		}
		
		$egg('#inspector').removeClass(INSPECTOR_MODES).addClass('widgetmode');
		
    	if (target.is('.photo-widget .widget-icon'))
		{
		    $egg('#inspector .widget-form').load('/collage/widget_form/photo-widget');
		}
		else if (target.is('.movie-widget .widget-icon'))
		{
		    $egg('#inspector .widget-form').load('/collage/widget_form/movie-widget');
		}
		else if (target.is('.webclip-widget .widget-icon'))
		{
		    $egg('#inspector .widget-form').load('/collage/widget_form/webclip-widget');
		}
		else if (target.is('.book-widget .widget-icon'))
		{
			$egg('#inspector .widget-form').load('/collage/widget_form/book-widget');
		}
		else if (target.is('.doc-widget .widget-icon'))
		{
			$egg('#inspector .widget-form').load('/collage/widget_form/doc-widget');
		}
		else if (target.is('.label-widget .widget-icon'))
		{
			$egg('#inspector .widget-form').load('/collage/widget_form/label-widget', function() {
				$egg(this).find(".palette").each( function(item) {
					var len = EGGPalette.swatches.length;
					for(var i=0;i<len;i++) {
						$egg(this).append('<div class="swatch" style="background-color:%@;color:%@"></div>'.fmt(EGGPalette.swatches[i].split(",")[0], EGGPalette.swatches[i].split(",")[1]));
					}
				});
			});
		}
		else if (target.is('.canvas-widget .widget-icon'))
    	{
			$egg('#inspector .widget-form').removeClass('select-canvas-mode').load('/collage/widget_form/canvas-widget');
			
    	}
	},
	
	scrollToItem: function(current) {
		if (!current) current = this.currentItem;
		if (!current) return; // 아무것도 없는 게시판
		var f = current.metric;
		/**
		if (current.resource_type!='LabelItem') {
			f = v.coverView.get('frame');
			f = v.coverView.convertFrameToView(f, v);
		} else {
			f = v.get('frame');
		}
		***/
		var holder_f = $egg('#main-view').frame();//this.parentNode.get('innerFrame');
		var actual_f = this.getCanvasItemFrame(current);
		
		var left = (holder_f.width - actual_f.width)/2; //눈에 보이는 크기로 계산
		var top = (holder_f.height - actual_f.height)/2;
		var s_loc = { x: Math.floor(actual_f.x-left), y: Math.floor(actual_f.y-top) };
		if (s_loc.x<0) s_loc.x = 0;
		if (s_loc.y<0) s_loc.y = 0;
		
		//this.parentNode.scrollTo(s_loc.x, s_loc.y);
		$egg('#main-view').scrollLeft(s_loc.x).scrollTop(s_loc.y);
	},
	
	scrollToCenter: function() {
		var view = $egg('#main-view');
		var contentView = view.children().first();
		var z = (this.getZoom() || 100)/100;
		view.scrollLeft((contentView.width()*z-view.width())/2).scrollTop((contentView.height()*z-view.height()) /2);
	},
	
	centerizeCanvasItem: function(item) {
		var f = item.metric;

		var holder_f = $egg('#main-view').frame();
		var actual_f = this.getCanvasItemFrame(item);
		
		var left = (holder_f.width - actual_f.width)/2; //눈에 보이는 크기로 계산
		var top = (holder_f.height - actual_f.height)/2;
		var s_loc = { x: Math.floor(actual_f.x-left), y: Math.floor(actual_f.y-top) };
		if (s_loc.x<0) s_loc.x = 0;
		if (s_loc.y<0) s_loc.y = 0;
		
		//$egg('#main-view').scrollLeft(s_loc.x).scrollTop(s_loc.y);
		$egg('#main-view').animate({scrollLeft:s_loc.x, scrollTop:s_loc.y}, 800);
	},
	
	toCenter: function(center, animation) {	
			
		var mainview = $egg('#main-view');
		var z = Collage.mainController.getZoom();

		center[0] = center[0] * z / 100;
		center[1] = center[1] * z / 100;
		
		
		var x = (mainview.width()/2) - center[0];
		var y = (mainview.height()/2) - center[1];
		
		if (animation === true) 
		{
		    mainview.animate({scrollLeft:-x, scrollTop:-y}, 500);
		} else 
		{
		    mainview.scrollLeft(-x).scrollTop(-y);
		}
		
	},
	innerBound: function() {
	    var cp = {left:5000, top: 5000, right:0, bottom: 0};

        if (this.content.length > 0) 
        {
            Collage.mainController.content.each(function(item) {
                cp.top = Math.min(item.metric.y, cp.top);
                cp.bottom = Math.max(item.metric.y+item.metric.height, cp.bottom);
                cp.left = Math.min(item.metric.x, cp.left);
                cp.right = Math.max(item.metric.x+item.metric.width, cp.right);
            });
        }
        if (cp.left > cp.right)
        {
            cp.left = 0; cp.right = 5000; 
        }
        if (cp.top > cp.bottom)
        {
            cp.top = 0; cp.bottom = 3000;
        }
        return {
            x: Math.max(cp.left-100, 0), 
            y: Math.max(cp.top-100, 0), 
            width: Math.min(cp.right-cp.left+200, 5000), 
            height: Math.min(cp.bottom-cp.top+200, 3000)
        };
	},
	///////////////////////////////////////////////////////////
	// 
	///////////////////////////////////////////////////////////
	// SELECTED ITEM
	//
	currentItem: null,
	findItemById: function(id) {
		var idx = this.content.length;
		while(--idx>=0) if (this.content[idx].id==id) return this.content[idx];
		return null;
	},
	selectItemById: function(id) {
		var found = this.findItemById(id);
		if (found) this.selectItem(found);
	},
	selectItem: function(item) {
		if (item !== undefined) {			
			
			Collage.itemController.setCurrentItem(item); // item 변경사항 반영하기 위해서
			if (this.currentItem === item) return;
				
			if (this.currentItem && this.currentItem.isTemporaryItem) 
			{
				//Collage.mainController.removeTempCanvasItem();
				console.log("removeTempCanvasItem");
				console.log(this.currentItem );
				this.removeItems([this.currentItem]);
				$egg('#inspector').removeClass(INSPECTOR_MODES).addClass('buttonmode').find(".widget-form").empty();
			}
			this.currentItem = item;
			
			if (item)
			{	
				// config inspector
				$egg('#inspector')
				.removeClass(INSPECTOR_MODES)
				.addClass(item.resource_type)
				.setClass('buttonmode', /*item.resource_type!="Canvas" &&*/ item.resource_type!='LabelItem')
				.setClass('editable', item.editable)
				.setClass('topmode', canvas.isTop);
				
    			$egg("#inspector input.shadow").attr('checked', item.visual_style.vshadow);
        		$egg("#inspector input.border").attr('checked', item.visual_style.vborder);
        		$egg("#inspector input.title").attr('checked', item.visual_style.vshow_title);	
				
        		$egg("#inspector .upload_info .progress").progressbar('value', item.uploadRatio);
        		$egg("#inspector .upload_info .message").html(item.uploadStatusMessage);
        		$egg('#inspector').setClass("uploading", !(!item.uploadStatus || item.uploadStatus=="COMPLETE")); 
        		
        		$egg('#inspector #inplace-editor').blur();

				//app.sendMessage("canvasitem", {action:"update_upload_status", canvas_item_id:item.id});
				$egg('#focus-border').show();
			} else {
				$egg('#chat-balloon-view .chat-balloon').css({zIndex:0});
				$egg('#focus-border').hide();
			}
			this.selectedItem_reposition();
		} else {
			Collage.itemController.setCurrentItem(this.currentItem); // item 변경사항 반영하기 위해서
		}
		if (this.currentItem) {
    		$egg('#tb-delete-canvasitem').setClass('disabled', !item.deletable);
			$egg("#tb-download-canvasitem").setClass("disabled", !this.currentItem.resource_type.oneOf("ImageItem DocItem"));
			$egg("#tb-share-canvasitem").setClass("disabled", !this.currentItem.resource_type.oneOf("ImageItem DocItem BookItem WebItem MovieItem NoteItem") || !canvas.loggedIn);
			
		} else {
			$egg("#tb-delete-canvasitem").addClass("disabled");
			$egg("#tb-download-canvasitem").addClass("disabled");
			$egg("#tb-share-canvasitem").addClass("disabled");
		}
	},
	
	
	selectedItem_reposition: function() {
		this.repositionChatBalloon();
	    try {
		if (!this.currentItem) {
			$egg('#focused-item').hide();
			$egg('#inspector').hide();
			return;
		}
		else 
		{
		    $egg('#focused-item').show();
			$egg('#inspector').show();
		}
		
		var f = this.getCanvasItemActiveFrame(this.currentItem);
		var f2 = this.getCanvasItemFrame(this.currentItem);
		var border = 6;
		f.width-=border*2; f.height-=border*2;
		f2.width-=border*2; f2.height-=border*2;
		
		var src = "/images/app/blank.gif";
        if (this.currentItem.img /*&& this.currentItem.resource_type!="Canvas"*/) 
	        src = this.currentItem.img.src;
	        
        var z = this.getZoom() / 100;
		$egg('#focused-item .cover')
		.width(f2.width)
		.height(f2.height)
		.css({left: "-%@px".fmt(this.currentItem.offset().left*z), top: "-%@px".fmt(this.currentItem.offset().top*z)})
		.attr('src', src);
		
		if (!app.staticMode) {
		    $egg('#focused-item .cover').removeClass('static_mode');
		} else {
		    $egg('#focused-item .cover').addClass('static_mode');
		}
		//
		
		$egg('#focused-item').frame(f).show();
		
		this.selectedItem_repaint();
		var aspect = true;
		if (this.currentItem.resource_type=="LabelItem") {
			aspect = false;
		} else if (this.currentItem.img) {
			aspect = this.currentItem.img.width / this.currentItem.img.height;
		}
		
		$egg('#focused-item').resizable('destroy');
		
		if (this.currentItem.resource_type!="Canvas" && !canvas.isTop)
		{
		    if (!app.staticMode) $egg('#focused-item').resizable({handles:"se", alsoResize: "#focused-item .cover", aspectRatio: aspect});
		} 
		
		var offset = $egg('#focused-item').offset();
		$egg('#inspector').css({opacity:0}).show();
		$egg('#inspector').offset({left:offset.left - (200-$egg('#focused-item').width())/2, top:offset.top + $egg('#focused-item').height()+30});
		$egg('#inspector .body').text(this.currentItem.title);
		$egg('#inspector').css({opacity:1});
		
		var focusedItem = $egg("#focused-item");
		$egg('#focus-border').css({
			left:"%@px".fmt(parseInt(focusedItem.css('left'),10)-10),
			width:"%@px".fmt(parseInt(focusedItem.css('width'),10)+24),
			height:"%@px".fmt(parseInt(focusedItem.css('height'),10)+24),
			top:"%@px".fmt(parseInt(focusedItem.css('top'),10)-10),
		});
		
	    } catch(e) { console.log(e); }
	},
	selectedItem_repaint: function() {
		if (!this.currentItem) return;
		

		var f = {x:0, y:0, width:$egg('#focused-item .cover').width(), height:$egg('#focused-item .cover').height() };
		
		if (this.currentItem.resource_type=="LabelItem") {	
			var m = Object.clone(f);
			var z = this.getZoom();
			m.width = m.width * 100 / z;
			m.height = m.height * 100 / z;
			var ctx = $egg('#focused-item .item_canvas').width(f.width).height(f.height).attr('width', m.width).attr('height', m.height)[0].getContext("2d");
			
			var ch = EGGPalette.toColorHash( this.currentItem.color );
			
			ctx.save();
			//this._setShadow(ctx);
			ctx.fillStyle=ch['backgroundColor'];
			ctx.fillRect(0,0,m.width,m.height);
			ctx.restore();

			ctx.save();
			ctx.fillStyle = ch['color'];
			ctx.textAlign = 'center';
			ctx.textBaseline = 'middle';
			ctx.font = '26px Arial';
	
			ctx.fillText(this.currentItem.title, m.width/2, m.height/2);//, m.width);
			ctx.restore();
			$egg('#focused-item .item_canvas').show();
		} else {

            var z = this.getZoom() / 100;
    		$egg('#focused-item .cover')
    		.css({left: "-%@px".fmt(this.currentItem.offset().left*z), top: "-%@px".fmt(this.currentItem.offset().top*z)});    		

    		/*
    		$egg('#focused-item .cover')
    		.width($egg('#focused-item').width())
    		.height($egg('#focused-item').height());
    		
    	    
			var ctx = $egg('#focused-item .item_canvas').width(f.width).height(f.height).attr('width', f.width).attr('height', f.height)[0].getContext("2d");
			ctx.save();
			//ctx.fillStyle = "red";
			//ctx.fillRect(0,0,f.width, f.height);
			ctx.clearRect(0,0,f.width, f.height);
			//ctx.drawImage(this.currentItem.img, 0,0, f.width, f.height);
			ctx.restore();
            */
			$egg('#focused-item .item_canvas').hide();
		}
		
	},
	selectedItem_startResize: function(evt, ui) {
		this.hideItem(this.currentItem);
		ui.position.left += $egg('#main-view').scrollLeft();
		ui.position.top += $egg('#main-view').scrollTop();
		$egg('#focused-item').addClass('resizing');
		$egg('#focus-border').addClass('resizing');
		$egg('#inspector').hide();
	},
	selectedItem_endResize: function(evt, ui) {
		
		this.selectedItem_resizeComplete(this.currentItem);
		this.selectedItem_reposition();
	},
	selectedItem_startDrag: function(evt, ui) {
		$egg('#focused-item').addClass('dragging');
		$egg('#focus-border').addClass('dragging');
		
		evt.stopPropagation();
		//evt.preventDefault();
		
		var self = this;
		//setTimeout(function() { self.hideItem(self.currentItem) }, 100);
		this.hideItem(this.currentItem);
		
		$egg('#inspector').hide();
	},
	selectedItem_endDrag: function(evt, ui) {
		evt.stopPropagation();
		//evt.preventDefault();
		$egg('#focused-item').removeClass('dragging');
		$egg('#focus-border').removeClass('dragging');
		
		var item = this.currentItem;
		if (item) {
		    
			if (!item.editable) {
				this.showItem(item);
				this.selectedItem_reposition();
				//$egg('#focused-item').removeClass('dragging');
				return true;
			}
			
			// border 만큼 빼준다.
			var f = $egg("#focused-item").frame();
			var border = 6;
			f.x += border; f.y += border; f.width -= border*2; f.height -= border*2;

			var z = this.getZoom();
			f.x = f.x * 100 / z;
			f.y = f.y * 100 / z;
			var targetView = $egg('#target-item');
			
			var linkRtn = false;
			
			if (targetView.data() && targetView.data().item) {
				console.log(this.currentItem);
				console.log(targetView.data().item);
				linkRtn = true;
				targetView.hide();
				linkRtn = this.linkItem(this.currentItem, targetView.data().item);
			}
			if (linkRtn) {
				this.selectItem(targetView.data().item);
				targetView.data(null);
			} else {
				item.metric.x = f.x;
				item.metric.y = f.y;
				if (item.resource_type=="Canvas") {
				    item.metric.x -= item.offset().left;
				    item.metric.y -= item.offset().top;
				}

				this.indexingCells();
				this.showItem(item);
				item.metric_str = item.get_metric_str();
				if (item.isDraggable()) item.rUpdate(['metric_str']);
				app.isDirtySnap = true;
			}
		} else {
			console.log("this.content is NULLLLLL");
		}
		this.selectedItem_reposition();
	},
	selectedItem_drag: function(evt, ui) {
		evt.stopPropagation();
		
		var item = this.itemForEvent(evt);
		var targetView = $egg('#target-item');
		if (item && item != this.currentItem && item.isDropTarget() && this.currentItem.isStackable() && item.isStackable()) {
			var f = this.getCanvasItemFrame(item);
			//var border = 6;
			var border = 0;
			f.x-=border; f.y-=border; f.width-=6*2; f.height-=6*2;  //TODO 꼭 수정
			targetView.frame(f).attr('src', item.img.src).show();
			targetView.data({item:item});
		} else {
			targetView.hide();
			targetView.data(null);
		}
	},
	
	selectedItem_dblClick: function(evt, ui) {
		evt.preventDefault();
		app.openDocument(this.currentItem);
	},
	
	selectedItem_resizeComplete: function(item) {
		$egg('#focused-item').removeClass('resizing');
		$egg('#focus-border').removeClass('resizing');
		
		if (item) {
			if (!item.isDraggable()) {				
				this.showItem(item);
				this.selectedItem_reposition();
				return true;
			}
			// border 만큼 빼준다.
			var f = $egg("#focused-item").frame();
			
			var border = 6;
			f.x += border; f.y += border; f.width -= border*2; f.height -= border*2;
			
			var z = this.getZoom();
			f.x = f.x * 100 / z;
			f.y = f.y * 100 / z;
			f.width = Math.ceil(f.width * 100/z);
			f.height = Math.ceil(f.height * 100/z);
			
			/*
			item.metric.x = f.x;
			item.metric.y = f.y;
			*/
			item.metric.width = f.width;
			item.metric.height = f.height;
			item.inner_bound.width = f.width*10;
			item.inner_bound.height = f.height*10;
			
			this.indexingCells();
			this.showItem(item);
			item.metric_str = item.get_metric_str();
			item.rUpdate(['metric_str']);
			
		} else {
			console.log("this.content is NULLLLLL");
		}
	},
	messageCanvasItem: function(evt, data) {
		if (data.action == "update_upload_status") {
    		console.log("----MESSAGE:%@.%@".fmt(data.canvas_item_id, this.currentItem.id));
    		if (!this.currentItem || data.canvas_item_id != this.currentItem.id) return;
			
			var item = this.currentItem;
			$egg("#inspector .upload_info .message").html(item.uploadStatusMessage);			
			$egg("#inspector .upload_info .progress").progressbar('value', item.uploadRatio);
			
			if (!item.uploadStatus || item.uploadStatus == "COMPLETE") {
				$egg("#inspector").removeClass("uploading converting");
			} else {
				$egg("#inspector").addClass("uploading");
				if (item.uploadStatus.oneOf("CONVERTING")) {
					$egg("#inspector").addClass("converting");
				}
			}
		}
	},
	////////////////////////////////////////////////////////
	// zoom delegate
	//
	_zoom: null,
	getZoom: function() {
		return this._zoom;
	},
	zoomFactor: function(key, value) { 
    	if (value !== undefined) {
			this._zoom = value;
			Popegg.Cookie.setCookie('zoom', this._zoom, null, '/');
			var canvas2d = $('canvas2d');
			if (canvas2d) {
					canvas2d.setStyle({width:"%@px".fmt(5000*this._zoom/100), height:"%@px".fmt(3000*this._zoom/100)});
			}
    	}
		if (!this._zoom) {
			if (canvas.canZoom()) {
				var z = parseInt(Popegg.Cookie.getCookie('zoom'), 10);
				if (z > 0 && z < 1000) {
					this._zoom = z;
				} else 
					this._zoom = 80; //기본값
			} else {
				this._zoom = 100;
			}
		}
    	return this._zoom;
  	},

	_oldZoom: 100, 
	
	setZoom: function(value, silent) {
		this._zoom = value;
		prefs.save('zoom', value);
		
		var cvs = $('canvas2d');
		if (cvs) {
		    if (!app.staticMode)
		    {
		        // zoom 적용
    			/* original
    			cvs.setStyle({width:"%@px".fmt(Math.round(5000*value/100)), height:"%@px".fmt(Math.round(3000*value/100))});

    			$('canvas-back').setStyle({width:"%@px".fmt(Math.round(5000*value/100)), height:"%@px".fmt(Math.round(3000*value/100))});
                */

                /*
    			$egg('#canvas2d').hide();
    			$('canvas-back').width = Math.round(5000*value/100);
    			$('canvas-back').height = Math.round(3000*value/100);
    			$('canvas-back').setStyle({width:"auto", height:"auto"});
    			*/
    			$egg('#canvas-back').hide();
    			$('canvas2d').width = Math.round(5000*value/100);
    			$('canvas2d').height = Math.round(3000*value/100);
    			$('canvas2d').setStyle({width:"auto", height:"auto"});
				console.log("RESIZE");
    			this._flushRendered();
		    }
		    else 
		    {
		        $egg('#canvas2d').css({width:"%@px".fmt(Math.round(5000*value/100)), height:"%@px".fmt(Math.round(3000*value/100))});
    			$egg('#canvas-back').css({width:"%@px".fmt(Math.round(5000*value/100)), height:"%@px".fmt(Math.round(3000*value/100))});

				
		    }
			//$egg('#chat-balloon-view').css({width:"%@px".fmt(Math.round(5000*value/100)), height:"%@px".fmt(Math.round(3000*value/100))});
			$egg('#chat-balloon-view').css({
				width:"%@px".fmt(Math.round(5000*value/100)), height:"1px", top:"%@px".fmt(Math.round(3000*value/100))
			});
		}

		// 변경전 zoom에서의 중심좌표를 찾는다.
		// 중심좌표 x += width_of_viewport/2
		var z = this._oldZoom/100;

		var scrollview = $egg('#main-view');
		var viewport = {width: scrollview.width(), height: scrollview.height()};
		var vp = {width: viewport.width/z, height: viewport.height/z};
		

		var before_sf = {x:-scrollview.scrollLeft(), y:-scrollview.scrollTop()};
		before_sf.x /= z;
		before_sf.y /= z;
		
		// center 계산
		var before_center = {x:-Math.floor(before_sf.x-vp.width/2), y:-Math.floor(before_sf.y-vp.height/2)};
		
		z = value/100;
		//vp 복원
		vp = {width: viewport.width/z, height: viewport.height/z};
	
		var after_sf = {};
		after_sf.x = -(before_center.x-vp.width/2) * z;
		after_sf.y = -(before_center.y-vp.height/2) * z;
		
		scrollview.scrollLeft(-after_sf.x).scrollTop(-after_sf.y);
	
		this._oldZoom = value;
		
		this.selectedItem_reposition();
		//this.repositionChatBalloon();
		return;

	},
	
	
	////////////////////////////////////////////////////////
	// SELECTION  and current management
	//	
	
	////////////////////////////////////////////////////////
	// Data Delegate for Canvas
	//

	linkItem: function(src, dest) {
		
		if (canvas.loggedIn) {
			if (src.resource_type=='LabelItem') {
				// 여기로 올 가능성 없음
				//this.showFlashMessage("라벨은 다른 아이템에 결합할 수 없습니다.");
				return false;
			}
			if (src.editable) {
				dest.new_attach_item_id = src.id;
				dest._successUpdate = this.successLinkItem.bind(this);
				dest.rUpdate();

				this.removeItems([src]);
				this.selectItem(dest);
				return true;
			} else {
				app.showMessage('안내', "내가 올린 아이템만 다른 아이템에 결합할 수 있습니다.");
			}
		} else {
			app.showMessage('로그인하세요.', "새 아이템을 올리시려면 로그인하세요.");
		}
		console.log("WHY!!!!!!!!!!!!!!!!");
		return false;
	},
	successLinkItem: function(canvasItem) {
		this.indexingCells();
		this.updateItem(canvasItem);
	},
	////////////////////////////////////////////////////////
	// Link & Unlink Items
	//
	
	deleteCanvasItemByItemId: function(id) {
		console.log(id);
		return this.deleteCanvasItem(this.findItemById(id));
	},
	deleteCanvasItem: function(item) {
		var canvasItem = item || Collage.itemController.item;

		if (canvasItem && canvasItem.deletable==true) {
			if (canvasItem.type=='Feed' || confirm("삭제하시겠습니까? 관련된 모든 댓글도 함께 삭제됩니다.")) {
				try {
					if (!canvasItem.ref_item_id) {
						//console.log("베이스아이템");
						this.removeItems([canvasItem]);
						
						/*
						var list = Collage.previewController.content;
						if (list) {
							//
							var idx = list.indexOf(canvasItem);
							list.removeObject(canvasItem);
							
							var nextItem = (!list[idx] ? list.last() : list[idx]);
							if (!nextItem) {
								this.selectItem(null);
								
								//SC.page.stackDlg.closePanel();								
								Collage.previewController.close();
							} else {
								Collage.previewController.set('selection', [nextItem]);
							}
						}
						*/
						canvasItem.rDelete();
						this.selectItem(null);
					} else {
						//console.log("서브아이템");						
						//TOOD var refItem = Collage.stackCntr.get('currentItem');
						var refItem = this.currentItem;
						refItem.set('attach_count', refItem.attach_count-1);
						
						var subitems = Collage.previewController.content;
						if (subitems) {
							var idx = subitems.indexOf(canvasItem);
							subitems.removeObject(canvasItem);
							var nextItem = (!subitems[idx] ? subitems.last() : subitems[idx]);
							if (!nextItem) {
								Collage.stackCntr.set('selection', [refItem]);
							} else {
								Collage.previewController.set('selection', [nextItem]);
							}
						}
						canvasItem.rDelete();
					}
				} catch(e) {
					console.log(e);
				}
				app.sendMessage("canvasitem", {action:"delete", canvas_item_id:canvasItem.id});
				return true;
			}
		}
		return false;
	},
	
	repositionChatBalloon: function() {
		var self = this;
		$egg('#main-view .chat-balloon').each(function() {
			var chat = $egg(this);
			var index = parseInt(chat.idattr('chat-'), 10);
			var item = self.content[index];
			var z = self.getZoom();
			var screenHeight = $egg("#canvas2d").height();
			if (item) {
				var left = item.metric.x*z/100 - 35;
				var bottom = (screenHeight-item.metric.y*z/100) + 15;
				chat.css({
					bottom: "%@px".fmt(bottom),
					left: "%@px".fmt(left)
				});
			}
		});
	},
	listFor:function() {
		var self = this;
		
		if (this.content) this.content.clear();
		Collage.mainController.clearAll();
		$egg('#chat-balloon-view .chat-balloon').unbind('mousedown').remove();
		new Ajax.Request('/canvas/open/%@'.fmt(canvas.url), {
			requestHeaders: { Accept: 'application/json, text/javascript, text/html, application/xml, text/xml, */*' },
			onSuccess: function(transport) {
				try {
				    //console.log(transport.responseText);
					var data = eval('data='+transport.responseText);
					
					if (data.error) {
					    console.log(transport.responseText);
					    app.showMessage('오류', data.error);
					    app._resumeHashChangeMonitor();
					    return;
					}
					self.selectItem(null);
					self.content = [];
					Object.extend(canvas, data.canvas);
					var len = data.items.length;
					
					
					for(var i=0;i<len;i++) {
						self.content.push( new Collage.CanvasItem().initWithObject(data.items[i]) );
						var newitem = self.content.last();
						if (newitem.unread && !canvas.isTop) {
							var comment = newitem.latest_comment;
							if (!comment) newitem.latest_comment = {};
							if (comment && comment.body)
								$egg('#chat-balloon-view').append('<div id="chat-%@" class="chat-balloon chat-item-%@"><div class="label"><span class="member">%@</span>%@</div><img class="thumbnail" src="/images/app/blank.gif"/><img class="tail" src="/images/app/blank.gif"/></div>'.fmt(i, newitem.uid, comment.member_name, comment.body));
						}
					}
					canvas._successRefresh();
					$egg('#chat-balloon-view .chat-balloon').bind('mousedown', function() {
						var sel = Collage.mainController.content[parseInt($egg(this).idattr('chat-'), 10)];
						Collage.mainController.selectItem(sel);
						$egg(this).css({zIndex:2}).siblings().css({zIndex:0});
						$egg('#focus-border').show();
					});
					self.repositionChatBalloon();
					if (app._inTransition === true) 
					{
					    console.log("Transition Mode");
						$egg('#canvas2d').css({opacity:0});
					    app.showCanvas(canvas.large_thumb);
					    //self.updateAll();
						/*
					    $egg('#canvas2d').animate({opacity:1}, 800, function() {
            			    app._inTransition = false;
            			});
						*/
					}
					else 
					{
					    app.showCanvas(canvas.large_thumb);
					}
					return;
				} catch (e) {console.log(transport.responseText); console.log(e); app._resumeHashChangeMonitor();}
				
			},
			onFailure: function(transport) {
			    console.log(transport);
			    app._resumeHashChangeMonitor();
				app.showMessage('오류', transport.statusText);
			    return;
			}
		});
	},	
	_successListFor: function() {
		//TT SC.page.msgbox.hideMessage();
		var content = this.content;
		
		this.updateAll();
		return;
		
		if (this._oldLocation && !!this._oldLocation.canvasItem) {
			var idx = content.length;
			while(--idx>=0) {
				if (content[idx].id==this._oldLocation.canvasItem) {
					console.log("TARGET_ITEM_ID:"+canvas.target_item_id);
					this.selectItem(content[idx]);
					break;
				}
			}
		} else {
			if (content.length > 0) {
				if (canvas.isTop)
					this.selectItem(content.first());
				else
					this.selectItem(content.last());
			}
				
		}
		//if (this.selection.length>0) {
		if (!!this.currentItem) {
			if (!canvas.center || canvas.center.split(',').length != 2) { 
					this.scrollToItem();
					//console.log("SCROLL TO ITEM");
			}
			var item = this.currentItem;
			if (item && item.id==this._oldLocation.canvasItem) {
				console.log(this._oldLocation.hashString);
				var target = "%@/%@".fmt(this._oldLocation.canvas, this._oldLocation.canvasItem);
				this._oldLocation.canvasItem = undefined;
				window.location.hash = target;
				//this._oldLocation_silendChangeCanvasItem();
			}
		} 			
	},
	
	downloadHandler: function(evt) {
		console.log(evt);
		var target = $egg(evt.target);
		if (evt.type=="click") 
		{
			if (target.is("#inspector .canvas-list .list-item")) {
				if (!!app.staticMode) {
	                app.openDialog('브라우저 안내', '/help/browser_warning');
	                return false;
	            };
				
				//alert("Move %@ to %@".fmt(Collage.mainController.currentItem.title, target.idattr('target-canvas-')));
				$egg.getJSON('/collage/scrap_canvas_item', 
					{ 
						canvas_item_uid:this.currentItem.uid, 
						target_canvas_uid:target.idattr('target-canvas-')
					}, 
					function(data) {
						//console.log(data);
						if (!data || data.error) {
							alert(data.error);
						}
						else
						{
							$egg('#inspector').removeClass('canvaslistmode').addClass('buttonmode');
						}
					}
				);
			}
		}
	}
	
	
	

	
	
	
});
Collage.mainController = new Collage.MainController();


Collage.previewController = new PreviewController();

var bookSearchController = {
	collection: null,
	init: function() {
		
	},
	search: function(q) {
		this.collection = [];
		if (q && q.strip().length>0) {
			$egg.getJSON('/book/'+q, function(data) {
				this.collection = data;
				this.updateAll();
			}.bind(this));
		} else {
			this.updateAll();
		}
	},
	searchHtml: function(q) {
		this.collection = [];
		if (q && q.strip().length>0) {
			$egg("#inspector .book-widget-form .activity-indicator").show();
			$egg("#inspector .book-widget-form .search_button").hide();
			$egg("#inspector #book-search-list").load('/books/search_html/'+q, function() {
				$egg("#inspector .book-widget-form .activity-indicator").hide();
				$egg("#inspector .book-widget-form .search_button").show();
			});
		} else {
			$egg("#inspector #book-search-list").empty();
		}
	},
	updateAll: function() {
		var len = this.collection.length;
		for (var i=0;i<len;i++) {
			var item = this.collection[i];
			v.append(this.renderItem(item, i)).children().last().data({item:item});
		}
		v.find(".list-item").bind({
			mousedown: function(evt) {
				$egg(this).addClass('sel').siblings().removeClass('sel');
			},			
			dblclick: function(evt) {
				evt.preventDefault();
				evt.stopPropagation();
				//alert($egg(this).data().item.title);
				var item = $egg(this).data().item;
				var bookinfo = {};
				
				bookinfo.title = item.title;
				bookinfo.isbn13 = item.isbn13;
				bookinfo.author = item.author;
				bookinfo.pubdate = item.pubdate;
				bookinfo.publisher = item.publisher;
				bookinfo.description = item.description;
				
				Collage.mainController.add_book_by_search(bookinfo);
				
			}
		});
	},
	renderItem: function(item, index) {
	    console.log(item.title);
		return '<div class="sc-collection-item list-item" style="position:relative"><div class="thumbnail"><img src="%@"/></div><div class="message"><span class="from">%@</span><span class="body">%@</span></div><div style="clear:both;"></div></div>'.fmt(item.thumbnail, item.title, item.description);
	}
};




var app = {
	isDirtySnap: false,
	
	initMessageQueue: function() {
		$egg('#message_queue').bind('message.canvasitem', Collage.mainController.messageCanvasItem.bind(Collage.mainController));
		
	},
	sendMessage: function(message_type, obj) {
		$egg('#message_queue').trigger('message.'+message_type, obj);
	},
	////////////////////////////////////////////////////////
	// action Delegate
	//
	closeDocument: function() {
		this._pauseHashChangeMonitor();	
		
		$egg('body').removeClass('preview_mode').addClass('canvas_mode');
		Collage.previewController.close();
			
		this._resumeHashChangeMonitor();
	},
	makeReadAll: function() {
		Collage.mainController.content.each(function(i) {
			i.unread = false;
			$egg('#chat-balloon-view .chat-item-%@'.fmt(i.uid)).remove();
		});
		$egg.post('/canvas/make_read_all', {id:canvas.id});
		Collage.mainController.updateAll();
	},
	openDocument: function(content) {
		//var content = this.currentItem;
		if (!content) {
			console.log("openDocument:null");
			return;
		}
		var resType = content.resource_type;
		
		if (resType=='Canvas')
		{
		    canvas.savePrefs();  // home_canvas 위치 저장		    
		    // if (canvas.isEggs) 를 추가해야함
		    // map, 자기 자신의 context를 저장
		    app.prefs = {
		        zoom: Collage.mainController.getZoom(),
		        center: "%@,%@".fmt(Collage.mainController._oldCenter[0], Collage.mainController._oldCenter[1])
		    };
		    app.home_snap = document.createElement('canvas');//$egg('#canvas2d').clone();
		    app.home_snap.width = 1250;
		    app.home_snap.height = 750;
		    
		    if (!app.staticMode)
		    {
		        app.home_snap.getContext("2d").drawImage($('canvas-back'), 0 ,0, $('canvas-back').width, $('canvas-back').height, 0, 0, 1250, 750);
		    }
		    

		    if (!content.pref) 
		        content.pref = { zoom: 100, center: "2500,1500" };

            this.transitionCanvas(content.pref, content.img, content.url);
		    return;

		} 
		else if (resType.oneOf('MovieItem ImageItem DocItem BookItem TableItem WebItem NoteItem')) 
		{		
			if (resType=="TableItem" && !canvas.loggedIn) {
				app.showMessage('로그인하세요.', "로그인하셔야 이용하실 수 있는 아이템입니다.");
				return;
			}
			this._pauseHashChangeMonitor();


			$egg('#dashboard-button.sel').click();
			Collage.previewController.preview(content);
				
			//TT if (content.id != this._oldLocation.canvasItem)
			if (content.id != this._oldLocation.canvasItem)
				this._oldLocation_changeCanvasItem(content.id);
			this._resumeHashChangeMonitor();
			
			
			if (content.unread) 
			{
				var unread_count = -1;
				Collage.mainController.content.each(function(i) {
					if (i.unread && i.resource_type!="LabelItem" && i.resource_type!='Canvas') unread_count++;
				});
				$egg.post('canvas/pref', {canvas_uid:canvas.uid, unread_count:unread_count});
				$egg("#chat-balloon-view .chat-item-%@".fmt(content.uid)).remove();
			}
			
			content.unread = false;
			Collage.mainController.updateItem(content, false);
			
			$egg('body').removeClass('canvas_mode MovieItem ImageItem DocItem BookItem TableItem WebItem').addClass('preview_mode').addClass(content.resource_type);
			
			
			
			
		} 
	},
	showCanvas: function(snapImageUrl) {
	    if (!app.staticMode)
	    {
			var img = new Image();
		    img.src = snapImageUrl;
		    var self = this;
			
	        $('canvas2d').getContext('2d').clearRect(0, 0, $('canvas2d').width, $('canvas2d').height);
			
    	    $egg(img).bind({
    	        load: function() {
    	            try {
        	            if (!Collage.mainController._initialRenderComplete)
        	            {
        	                $('canvas2d').getContext('2d').drawImage(img, 0, 0, $('canvas2d').width, $('canvas2d').height);
							//$egg('#canvas2d').css({opacity:0});
        	                //$egg('#canvas2d').animate({opacity:1}, 800);
        	            }
        	            
    	            } catch(e) { alert(e); }
    	        },
    	        error: function() {
					//if (!Collage.mainController._initialRenderComplete) $egg('#canvas2d').css({opacity:0});
    	            //$egg('#canvas2d').animate({opacity:1}, 800);
    	        },
    	        abort: function() {
					//if (!Collage.mainController._initialRenderComplete) $egg('#canvas2d').css({opacity:0});
    	            //$egg('#canvas2d').animate({opacity:1}, 800);
    	        }
    	    });
	    } else {
	        $('canvas2d').src = snapImageUrl;
			$egg('#canvas2d').css({opacity:1});
	        //$egg('#canvas2d').animate({opacity:1}, 800);
	    }
	    Collage.mainController.updateAll();
	    
	},
	transitionCanvas: function(afterPref, afterSnapImage, canvasUrl) {
	    console.log('TRANSITION CANVAS:');
	    
	    this._inTransition = true;
	    if (app.isDirtySnap) app.snapCanvas(true);
	    
	    // focused-item 제거
	    Collage.mainController.selectItem(null);
        canvas.prefs = afterPref;
        
        // fadeout
        var self = this;
        
		$egg('#canvas2d').css({opacity:0});
	    Collage.mainController.clearAll();
	        
		// rendering이 끝나지 않은 상태라면 배경에 snap 표시, 이럴 가능성은 없으니 테스트 후 배제하자   
        if (!app.staticMode)
        {
            $('canvas2d').getContext('2d').clearRect(0, 0, $('canvas2d').width, $('canvas2d').height);
    	   	if (afterSnapImage && afterSnapImage.width>0 && afterSnapImage.height>0) 
				$('canvas2d').getContext('2d').drawImage(afterSnapImage, 0, 0, $('canvas2d').width, $('canvas2d').height);     
        }
        else
        {
            $egg('#canvas2d').attr('src', '/images/app/blank.gif');
        }
		// zoom, center 적용
		var center = afterPref.center.split(",");
		canvas.zoom = parseInt(afterPref.zoom, 10);
		var z = canvas.zoom / 100;

		$egg('#canvas-zoom-slider').slider('value', parseInt(afterPref.zoom, 10));
		$egg('#main-view').scrollLeft(center[0]*z - $egg('#main-view').width()/2);
		$egg('#main-view').scrollTop(center[1]*z - $egg('#main-view').height()/2);

		app.openCanvas(canvasUrl);
	},
	////////////////////////////////////////////////////////
	//
	//
	logout: function() {
	    new Ajax.Request('/logout', {
			method: 'GET',
			parameters: {id:window.location.hash.substring(2)}
		});
	},
	openDialog: function(title, url, mod_opts) {
		mod_opts = mod_opts || {};
		mod_opts.title = title;
		mod_opts.autoOpen = false;
		mod_opts.close = function() { 
			$egg('#dialog_content').die(); 
		};
		var opts = Object.extend(Object.clone(PLAIN_DIALOG_OPTIONS), mod_opts);
		$egg('#dialog_content').dialog('destroy').dialog(opts).dialog('open').load(url);
	},
	closeDialog: function() {
		$egg('#dialog_content').dialog('close');
	},
	confirm: function(msg) {
		$egg("#dialog_content").dialog({
					resizable: false,
					height:140,
					modal: true,
					buttons: {
						'Delete all items': function() {
							$egg(this).dialog('close');
						},
						Cancel: function() {
							$egg(this).dialog('close');
						}
					}
				});
	},
	showMessage: function(title, message) {
		$egg("#dialog-message").dialog("option", "title", title).dialog({ 
			modal: true,
			buttons: {
				Ok: function() { $egg(this).dialog('close'); }
			}
		}).find("p").html(message);
	},
	hideMessage: function() {
		$egg("#dialog-message").dialog("close");
	},
	
	confirmDeleteCanvas: function() {
		$egg("#dialog_content").dialog('destroy');
		
		$egg("#dialog_content")
		.html('<div style="margin:10px 0px;">게시판을 삭제하시겠습니까?</div><small>관련된 모든 정보가 삭제되며 복구되지 않으니 주의하세요.</small>')
		.dialog({
			resizable: false,
			height:200,
			modal: true,
			buttons: {
				'삭제': function() {
					new Ajax.Request('/canvas/destroy', {
						parameters: {
							_method: 'DELETE',
							target_uid: canvas.uid
						}
					});
				},
				'취소': function() {
					$egg(this).dialog('close').dialog('destroy');
				}
			}
		});
	},
	showBubbleMenu: function(anchor, controls, width) {
		var anchor = $egg(anchor);
		
		var bubble = $egg("#bubble-menu");
		
		var self = this;
		this.closeBubbleMenu();
		bubble.setClass('has-search-field', false);
		controls.each(function(control) {
			if (control.type=="button") 
			{
				bubble.append('<a id="%@" class="touch-button %@" href="javascript:void(0);">%@</a>'.fmt(control.id, control.className, control.label));
				bubble.find('.touch-button').last().bind('click', control.action);
			}
			else if (control.type=="menu")
			{
				bubble.append('<div class="canvas-list list-container"><div style="padding:10px 0px; text-align:center;"><img src="/images/spinner32.gif"/></div></div>');
				control.params = control.params || {};
				bubble.find(".list-container").load(control.url, control.params).live('click', function(evt) { control.handler(evt.target); });
			}
			else if (control.type=="html")
			{
				bubble.append('<div id="%@" class="html-view"><div style="padding:10px 0px; text-align:center;"><img src="/images/spinner32.gif"/></div></div>'.fmt(control.id));
				control.params = control.params || {};
				bubble.find(".html-view").load(control.url, control.params, control.onload);
			}
			else if (control.type=="search_field")
			{
				//bubble.setClass('has-search-field', menu.hasSearchField);
				bubble.setClass('has-search-field', true);
			}
			else if (control.type=="textarea")
			{
				bubble.append('<textarea id="%@" class="%@"></textarea>'.fmt(control.id, control.className));
			}
			else if (control.type=="label")
			{
				bubble.append('<div class="label">%@</div>'.fmt(control.text));
			}
		});
		if (width===undefined) 
		{
			width = 200;
		}
		
		var top = anchor.offset().top + anchor.height() + 20;
		var left = anchor.offset().left+anchor.width()/2 - width/2;
		var old_left = left;
		var anchor_left = (width-anchor.width())/2 - 4;
		
		if (left < 5) 
		{
			left = 5;
			anchor_left += (old_left - left);
			console.log("Adjust 1");
		}
		else if (left + width + 10 + 5> window.innerWidth)  // 10은 padding
		{
			left = window.innerWidth - width - 15;
			anchor_left += (old_left - left);
			console.log("Adjust 2");
		}
		bubble.css({
			top: "%@px".fmt(top),
			left: "%@px".fmt(left),
			width: "%@px".fmt(width)
		}).show();
		bubble.find(".anchor").css({'left':'%@px'.fmt(anchor_left)});
	},
	closeBubbleMenu: function() {
		$egg("#bubble-menu").find(".touch-button").unbind('click').remove();
		$egg("#bubble-menu").hide().find(".list-container").die('click').remove();
		$egg("#bubble-menu .html-view").remove();
		$egg("#bubble-menu textarea").remove();
		$egg("#bubble-menu .label").remove();
	},
	snapCanvas: function(force) {	

        if (!!app.staticMode) return;
		/*
	    console.log("===================");
	    console.log(canvas.modified_on);
	    console.log(canvas.snapshot_on);
	    console.log(canvas.firstSnap);
	    console.log(force);
		*/
        var refresh = false;
		if (canvas.snapshot_on && canvas.modified_on) {
			refresh = (new Date(canvas.snapshot_on)<new Date(canvas.modified_on));
		} else if (!canvas.snapshot_on) {
		    refresh = true;
		}

		//console.log("Force:"+force);
		//console.log("snapshot_on:"+canvas.snapshot_on);
		
		//if (canvas.firstSnap && !canvas.isTop && (force || !canvas.snapshot_on)) {
		if (/*!canvas.isTop && */((canvas.firstSnap && refresh) || force)) {    
			var scratch = document.createElement('canvas');
			scratch.width=2000; scratch.height=1200;
			
			var data = null;
			var canvasCon = Collage.mainController;
			if (canvasCon.applyUnreadFilter && !app.staticMode) 
			{
				// filter 적용 안하고 다시 그림
				canvasCon._renderingQueue_clearAll();

		    	var ctx = scratch.getContext("2d");  
		    	ctx.save();
				ctx.scale(scratch.width/$('canvas-back').width, scratch.height/$('canvas-back').height);
		        var len = canvasCon.content.length;
		    	for(var idx=0;idx<len;idx++) {
		    		var item = canvasCon.content[idx];
		    		var cellRect = canvasCon.getCellRectByItem(item, {top:5, bottom:27, left:10, right:15});
		    		var f = {
		    			x: canvasCon._snapX*cellRect.startCol,
		    			y: canvasCon._snapY*cellRect.startRow,
		    			width: (cellRect.endCol-cellRect.startCol+1)*canvasCon._snapX,
		    			height: (cellRect.endRow-cellRect.startRow+1)*canvasCon._snapY
		    		};
					//canvasCon._renderingQueue_addItem(item, f);
					item.render2d(ctx, f, false);
		    	}
				ctx.restore();
				data = scratch.toDataURL();
				scratch.width=0; scratch.height=0;
				scratch = null;
			}
			else
			{
				scratch.getContext("2d").drawImage($('canvas-back'), 0, 0, 2000, 1200);
				data = scratch.toDataURL();
				scratch.width=0; scratch.height=0;
				scratch = null;
			}
			
			if (data)
			{
				$egg.post('/collage/snap', {
				   canvas_id: canvas.id,
				   inner_bound: Collage.mainController.innerBound(),
				   data_url: data
				});
				canvas.snapshot_on = new Date().toUTCString();
				canvas.firstSnap = false;
			}
		}
	},
	createCanvas: function() {
		if (canvas.loggedIn)
			$egg('#dialog_content').dialog(PLAIN_DIALOG_OPTIONS).load('/canvases/new');
		else
			$egg('#dialog_content').dialog(PLAIN_DIALOG_OPTIONS).load('/help/canvas');
	},
	
	////////////////////////////////////////////////////////
	// Navigations
	//
	_hashChangeTimer: null,
	_oldLocation: {hashString:"", canvas:null, canvasItem:null},
	
	_oldLocation_silentChangeCanvasItem: function(canvasItem) {
		if (!canvasItem)
			this._oldLocation.hashString = "/%@".fmt(this._oldLocation.canvas);
		else {
			this._oldLocation.canvasItem = canvasItem;
			this._oldLocation.hashString = "/%@/%@".fmt(this._oldLocation.canvas, canvasItem);
		}
	},
	
	_oldLocation_changeCanvasItem: function(canvasItem) {
		if (!canvasItem)
			this._oldLocation.hashString = "/%@".fmt(this._oldLocation.canvas);
		else {
		    this._oldLocation.canvasItem = canvasItem;
			this._oldLocation.hashString = "/%@/%@".fmt(this._oldLocation.canvas, canvasItem);
		}
		window.location.hash = this._oldLocation.hashString;
	},
	_parseHash: function(hashStr) {
		var parts = hashStr.split('/');
		return {
			hashString: hashStr,
			canvas: (parts[1] || ""),
			canvasItem: (parts[2] || null)
		};
		
	},
	_startTrackingHashChange: function() {
	    this._oldLocation.hashString = "__empty__";
		// 기본 네비게이터, hash가 없으면 top으로 지정 이때 _oldHash는 비어있게 됨
		/*
		if (window.location.hash=="") window.location.hash = "#!top"; // 메인으로 직접 들어온 경우
		
		if (window.location.hash=="#!top") canvas.isTop = true;
		else canvas.isTop = false;
		*/
		if (!this._hashChangeTimer) {
			this._hashChangeTimer = setTimeout("app._checkHashChange()", 500);
		}
	},
	_resumeHashChangeMonitor: function() {
		clearTimeout(this._hashChangeTimer);
		this._hashChangeTimer = setTimeout("app._checkHashChange()", 500);
	},
	_pauseHashChangeMonitor: function() {
		clearTimeout(this._hashChangeTimer);
	},
	_checkHashChange: function() {
		// location hash 모니터, 이전과 비교하여 달라졌으면 이동시킨다.
		if (this._oldLocation.hashString != window.location.hash) {
			var newLocation = this._parseHash(window.location.hash);
			
			if (this._oldLocation.member == newLocation.member && this._oldLocation.canvas == newLocation.canvas ) 
			{
				// 현재 페이지 유지하고, canvas Item을 열것인지 결정한다.
				// 만약 canvas_item에 변동이 있었으면 이를 반영한다.
				console.log("location 변동");
				if (this._oldLocation.canvasItem != newLocation.canvasItem) {
					if (!newLocation.canvasItem) {
						console.log("location 변동 닫기");
						this.closeDocument();
					} else {
						// 아이템 선택하고
						console.log("location 열기 : " + newLocation.canvasItem);
						
						var idx = this.content.length;
						while(--idx>=0) {
							var content = this.content[idx];

							if (content.id==newLocation.canvasItem) {
								this.selectItem(content);
								break;
							}
						}
						this.openDocument();
					}
				}
				this._oldLocation = newLocation;
				this._resumeHashChangeMonitor();
				 
			} 
			else 
			{
				// 새 페이지를 띄운다.
				if (!newLocation.canvasItem) {
					this.closeDocument();
				}
				this._oldLocation = newLocation;
				// document 자동 띄우기 위해
				//this._oldLocation_silentChangeCanvasItem();
				//window.location.hash = newLocation;//.canvas;
				this._openCanvas();
			}
		} else {
			this._resumeHashChangeMonitor();
		}
	},
	_openCanvas: function() {
		$egg('#load-progress').css({
		    left:"%@px".fmt(($egg('#canvas_main').width()-$egg('#load-progress').width())/2),
		    //top:"%@px".fmt(($egg('#canvas_main').height()-$egg('#load-progress').height())/2)
		    bottom: "10px"
		})
		.progressbar('value', 0)
		.show();
		
		$egg('#notepad-button.sel').click();
		$egg('#tb-canvas-info.sel').click();
		$egg('#tb-canvas-ring.sel').click();
		
		if ($egg('#dialog_content').dialog('option', 'title')!="브라우저 안내") this.closeDialog();
		this.hideMessage();
		
		Collage.mainController.selectItem(null);
		this._pauseHashChangeMonitor();
		console.log("==============%@".fmt(window.location.hash));
		
		if (window.location.hash.length < 3 ) {
		    console.log(canvas);
		    if (canvas.loggedIn)
		        window.location.hash = "/%@".fmt(canvas.member_name);
			else
			    window.location.hash = "/guide";
			this._oldLocation = this._parseHash(window.location.hash);
		}

		$egg("#info-panel .tab .label").text("");
		canvas.target_item_id = (!this._oldLocation.canvasItem) ? 'none' : this._oldLocation.canvasItem;
		canvas.url = this._oldLocation.canvas;	
		canvas.url = window.location.hash.substring(2);	
		
		console.log(canvas.url);
		
		Collage.itemController.setCurrentItem(null);
		
		
		// 새로운 location을 지정하고 load 시작	
		
		if (!app._inTransition && app.isDirtySnap) app.snapCanvas(true);
		
		app.isDirtySnap = false;
		canvas.firstSnap = true;
		//canvas.rRefresh();
		
		if (!app.staticMode)
		{
			if (app._inTransition !== true)
			{
				$egg('#canvas2d').css({opacity:0});
				Collage.mainController.listFor();
			} 
			else
			{
			    Collage.mainController.listFor();
			}
		}
		else
		{
			$egg('#canvas2d').attr('src', '/images/app/blank.gif');
			$egg('#canvas2d').css({opacity:0});
			Collage.mainController.listFor();
		}	
	},
	
	openCanvas: function(canvas_url) {  
		// canvas_url에는 #!이 포함되어 있지 않다.
		//window.location.hash="#!"+canvas_url;
		//this._pauseHashChangeMonitor();
		
		var dest = "";
		
		if (canvas_url && canvas_url.strip().length > 0)
		    dest = canvas_url.strip();
		
		var newLocation = this._parseHash(dest);
		if (this._oldLocation.member != newLocation.member || this._oldLocation.canvas != newLocation.canvas) 
		{
			// 새 페이지를 띄운다.
			this.closeDocument(); // 띄워져 있는 상태면 닫고
			if (!newLocation.canvasItem) {
				this._oldLocation = newLocation;
			} else {
				this._oldLocation.canvas = newLocation.canvas;
				this._oldLocation.hashString = newLocation.canvas;
				this._oldLocation.canvasItem = newLocation.canvasItem;
				//this._oldLocation_silentChangeCanvasItem();
			}
			//window.location.hash = newLocation.canvas;
			window.location.hash = canvas_url;
			this._openCanvas();
		}
		else 
		{
		    console.log('same location');
		}
			
	}
};
Popegg.DocItemListener = new EGGListener();

/*
var paletteView = new CollectionViewController().initWithObject({
	
	renderItem: function(item, index) {
		return '<div class="swatch" style="background-color:%@;color:%@"></div>'.fmt(item.split(",")[0], item.split(",")[1]);
	}
});
*/

Canvas = {};

var imageCache = {  
    loadLimit: 20,
    loadingCount: 0,
    _queue: [],
    _imgTimeout: null,

    loadImage: function(canvasitem, source) {
        this._queue.push({canvasitem:canvasitem, source:source});
        if (!this._imgTimeout) this._imgTimeout = setTimeout("imageCache.loadNextImage()", 100);
    },
    releaseWorker: function() {
        this.loadingCount--;
        if (!this._imgTimeout) this._imgTimeout = setTimeout("imageCache.loadNextImage()", 20);
        //console.log("RELEASE WORKER");
    },
    loadNextImage: function() {
        
        while((this._queue.length > 0) && (this.loadingCount < this.loadLimit)) {   
            var job = this._queue.shift() ;
            if (job.canvasitem.img == null)
            {
                this.loadingCount++;
                job.canvasitem._thumbnailReady = 0;

        		job.canvasitem.img = new Image();
        		var self = this;
        		var canvasitem = job.canvasitem;
        		
        		job.canvasitem.img.onload = canvasitem._thumbnailLoaded.bind(canvasitem);
        		job.canvasitem.img.onerror = canvasitem._thumbnailLoadError.bind(canvasitem);
        		job.canvasitem.img.onabort = canvasitem._thumbnailLoadError.bind(canvasitem);
        		
        		canvasitem.img.src = job.source;
        		//console.log("loading:"+job.source);
            }
        }
        this._imgTimeout = null;
    }
};

function main(initialParams) {
	prefs.load();
	
	
	Collage.canvasItemRenderHelper.badgeImage = new Image();
	Collage.canvasItemRenderHelper.badgeImage.src = "/images/icons/cnt_badge_3.png";
	
	Collage.canvasItemRenderHelper.baloonInactiveImage = new Image();
	Collage.canvasItemRenderHelper.baloonInactiveImage.src = "/images/icons/tb_comment_inactive.png";
	
	Collage.canvasItemRenderHelper.baloonActiveImage = new Image();
	Collage.canvasItemRenderHelper.baloonActiveImage.src = "/images/icons/tb_comment_pressed.png";
	/**/
	
	//Collage.canvasItemRenderHelper.bookHardCover = new Image();
	//Collage.canvasItemRenderHelper.bookHardCover.src = "/images/hardback.png";
	
	//Collage.canvasItemRenderHelper.egg = new Image();
	//Collage.canvasItemRenderHelper.egg.src = "/images/egg_small.png";
	
	Canvas.corkboard = new Image();
	Canvas.corkboard.src = "/images/basic_corkboard.jpg";
	
	if (Prototype.Browser.IE) {
	    app.staticMode = true;
	    
	    $egg('#main-view').prepend('<img id="canvas2d" width="2000" height="1200" src="/images/app/blank.gif"/>');
    	//$egg('#main-view').prepend('<img id="canvas-back" width="5000" height="3000" src="/images/app/blank.gif"/>');
    	$egg('#map').prepend('<img id="map-canvas" width="180" height="108" src="/images/app/blank.gif"/>');
    	
	    
	} else {
	    $egg('#main-view').prepend('<canvas id="canvas2d" style="" width="5000" height="3000"></canvas>');
    	$egg('#main-view').prepend('<canvas id="canvas-back" style="" width="5000" height="3000"></canvas>');
    	$egg('#map').prepend('<canvas id="map-canvas" width="500" height="300" style="width:180px; height:108px;"></canvas>');
	}
	
    
    
	canvas.loggedIn = initialParams;
	app.initMessageQueue();
	
	$egg("#dialog_content").bind('dialogclose', function() {
		$egg(this).html('<div style="padding:50px 100px; margin:auto; text-align:center;"><img src="/images/spinner32.gif" style=""/></div>');
	});

	$egg("#tb-bookmark-button").click(function(evt) {
		if ($egg(this).hasClass('sel')) {

		} else {
			var controls = [
				{ 
					type: 'search_field' 
				},
				{
					type: 'menu',
					url: '/collage/menu_canvas_list',
					params: {
						keyword: $egg('#bubble-menu .search_field').val()
					},
					handler: function(item) {
						if ($egg(item).is('.list-item'))
						{
							app.openCanvas('/%@'.fmt($egg(item).idattr('target-canvas-').replace('-', '/')));
							app.closeBubbleMenu();
						}
					}
				}
			];
			
			if (canvas.loggedIn) controls.push({
				type: 'button',
				id: '#tb-create-canvas',
				label: '새 게시판',
				action: function() { 
					app.closeBubbleMenu();
					$egg("#dialog_content")
					.html('<div style="margin:10px 0px;">새 게시판을 만드시겠습니까?</div>')
					.dialog('destroy')
					.dialog({
						resizable: false,
						height:180,
						modal: true,
						buttons: {
							'확인': function() {
								new Ajax.Request('/canvas/create');
							},
							'취소': function() {
								$egg(this).dialog('close').dialog('destroy');
							}
						}
					})
					.dialog('open');
				}
			});
			
			app.showBubbleMenu(this, controls);
		}
	});		
	
	$egg('#tb-home-button').click(function() {
		app.openCanvas('/');
	});
	$egg('#tb-inbox-button').click(function() {
		app.openCanvas('/inbox');
	});
	
	$egg("#auth_button").click(function() {
		if (canvas.loggedIn) {
			app.showBubbleMenu(this, [
				{
					type: 'button',
					id: "account-button",
					label: "회원정보변경",
					action: function() { 
						app.openDialog('회원정보변경', '/member/settings');
						app.closeBubbleMenu();
					}
				},
				{
					type: 'button',
					id: "logout-button",
					label: "로그아웃",
					action: function() { 
						app.logout();
						app.closeBubbleMenu();
					}
				}
			]);
		} else {
			app.openDialog("로그인", '/login/'+window.location.hash.substring(2).split('/')[0]);
		}
	});

	$egg('#back_to_canvas').click(function() {
		window.history.back();
	});
	
	
	
	$egg('#open_website_button').click(function() {
		Collage.itemController.openWebsite();
	});
	
	$egg('#opt-button').click(function() {
		app.openDialog('회원정보변경', '/member/settings');
	});
	

	$egg('#inspector .canvas-list').mousedown(function(evt) { evt.stopPropagation(); });
	$egg('#inspector .canvas-list').scroll(function(evt) { evt.stopPropagation(); evt.preventDefault(); });
	$egg('#inspector .canvas-list').live('click', Collage.mainController.downloadHandler.bind(Collage.mainController));
	
	$egg("#inspector .widget-form").live('click keydown mousedown change', function(evt) {
		var target = $egg(evt.target);
		
		if (evt.type=="click")
		{		
			if (target.is('.label-widget-form .widget-button.submit')) 
			{
				var field = $egg("#inspector .label-widget-form .content_body");
				var value = field.attr('value');

				var colorStr = "%@,%@".fmt($egg(field).css('background-color'), $egg(field).css('color'));
				if (colorStr.split(',').length>2) {
					colorStr = "%@/%@".fmt($egg(field).css('background-color'), $egg(field).css('color'));
				}
				Collage.mainController.add_label(value, colorStr);

			} 
			else if (target.is('.photo-widget-form .widget-button.submit')) 
			{
				var value = $egg("#inspector .widget-form .content_body").attr('value');
				Collage.mainController.add_image_by_url(value);

			} 
			else if (target.is('.movie-widget-form .widget-button.submit')) 
			{
				var value = $egg("#inspector .widget-form .content_body").attr('value');
				Collage.mainController.add_movie_by_url(value);

			} 
			else if (target.is('.webclip-widget-form .widget-button.submit')) 
			{
				var value = $egg("#inspector .widget-form .content_body").attr('value');
				Collage.mainController.add_web_by_url(value);

			} 
			else if (target.is('.book-widget-form .button.submit'))
			{
				bookSearchController.searchHtml( $egg("#inspector .search_field.content_body").attr('value') );

			} 
			else if (target.is(".book-widget-form .search_clear_button") ) 
			{
				$egg("#inspector .search_field.content_body").attr('value', '');
				bookSearchController.searchHtml(null);
			} 
			else if (target.is('.book-widget-form .list-item') || target.parents('.book-widget-form .list-item').length > 0) 
			{
				var listitem = null;
				
				if (target.is('.book-widget-form .list-item')) listitem = target;
				if (!listitem || listitem.length == 0)
				 	listitem = target.parents('.book-widget-form .list-item');

				if (listitem && listitem.length > 0)
				{
					
					var bookinfo = {};

					bookinfo.title = listitem.find('.title').text();
					bookinfo.isbn13 = listitem.find('.isbn13').text();
					bookinfo.author = listitem.find('.author').text();
					bookinfo.pubdate = listitem.find('.pubdate').text();
					bookinfo.publisher = listitem.find('.publisher').text();
					bookinfo.description = listitem.find('.description').text();

					Collage.mainController.add_book_by_search(bookinfo);

				}
			} 
			else if (target.is('#new-canvas-button')) 
			{
				var self = this;
				var f = Collage.mainController.tempCanvasItem.metric;
				$egg.post('/canvas/create_canvas', {
				    x: f.x, 
					y: f.y,
					canvas_id: canvas.id
				}, function(data) {
				    if (data && !!data.id)
				    {
				        var canvasItem = new Collage.CanvasItem().initWithObject(data);			
						canvasItem._temporaryMetric = false;

						Collage.mainController.addItems([canvasItem]);
				    }
				    else
				    {
				        console.log("FAIL");
				    }
				});
				return;
			} 
			else if (target.is('#select-canvas-button')) 
			{
				$egg('#canvas-list').load('/collage/common_canvas_list', {current_canvas_id:canvas.id});
				$egg("#inspector .widget-form").addClass('select-canvas-mode');
			}
			else if (target.is('.canvas-widget-form .list-item') || target.parents('.canvas-widget-form .list-item').length > 0) 
			{
				
				var listitem = null;

				if (target.is('.canvas-widget-form .list-item')) listitem = target;
				if (!listitem || listitem.length == 0)
				 	listitem = target.parents('.canvas-widget-form .list-item');

				if (listitem && listitem.length > 0)
				{					
					var f = Collage.mainController.tempCanvasItem.metric;
					$egg.post('/canvas/create_canvas', {
					    x: f.x, 
						y: f.y,
						canvas_id: canvas.id,
						source_canvas_uid: listitem.idattr('canvas-')
					}, function(data) {
					    if (data && !!data.id)
					    {
					        var canvasItem = new Collage.CanvasItem().initWithObject(data);			
							canvasItem._temporaryMetric = false;

							Collage.mainController.addItems([canvasItem]);
					    }
					    else
					    {
					        console.log("FAIL");
					    }
					});
					return;
				}
			}
		}
		else if (evt.type=="keydown")
		{
			if (target.is('.search_field.content_body'))
			{
				if (evt.keyCode == '13') {
					bookSearchController.searchHtml(target.attr('value'));
				}
			}
			else if (target.is('.label-widget-form .content_body'))
			{
				if (evt.keyCode=='13')
			        $egg('#inspector .label-widget-form .submit').click();
			}
		}
		else if (evt.type=="change")
		{
			if (target.is('.file_selector'))
			{
				var content = Collage.mainController.tempCanvasItem;
				if (!content) return;
				
				if (target[0].files && target[0].files.length > 0) {
					var file = target[0].files.item(0);

					if (file.fileName.toLowerCase().match(/.+\.(jpg|jpeg|gif|png)/)!=null) {
						content.resource_type = 'ImageItem';
					} else if (file.fileName.toLowerCase().match(/.+\.(pdf|ppt|pptx|xls|xlsx|doc|docx|rtf)/)!=null) {
						content.resource_type = 'DocItem';
					} else {
						app.showMessage('안내', "지원하지 않는 형식입니다. 현재는 이미지 파일들과 문서파일 중 pdf, ppt, xls, doc만을 지원하고 있습니다.");
						return;
					}
					content.title = file.fileName.split('.')[0];
					content._file = file;		

					content._temporaryMetric = true;
					content.isTemporaryItem = false;
					content.metric_str = content.get_metric_str();
					console.log(content);
					content.startUpload();	

					$egg("#inspector").removeClass(INSPECTOR_MODES).addClass('buttonmode').find('.widget-form').empty();
				}
			}
		}
		else if (evt.type=="mousedown")
		{
			if (target.is('.list-container'))
			{
				evt.stopPropagation();
				return false;
			}
			else if (target.is(".swatch"))
			{
				var field = $egg("#inspector .label-widget-form .content_body");
				field.css({color:target.css('color'), 'background-color':target.css('background-color')});
			}
		}

	});
	
	//$egg('#comment-bar').addClass("sidebar");
	
	$egg('#comment-bar .widget-content').listview({
	    rowHeight: 300,
   
		updateItem: function(item, view, position) {
			return;
            //console.log("%@~%@ <-- %@".fmt(position.start, position.end, position.index));
	        if (view.hasClass('loaded')) return;

	        view.removeClass('blank').addClass('loaded');
	        
	        //view.addClass("NoteItem");
	        view.find("img.canvasitem-thumbnail").attr('src', item.thumbnail);
			view.find(".label").html(item.canvas_title);
			view.find(".body").text(item.title);
			view.find(".comment").text(item.latest_comment.body);
			view.find(".shorttime").text(item.shorttime);
	    },
	    template: function(item, index) {
			var html = [];
			html.push('<div id="canvasitem-%@" class="canvasitem blank egg-list-item" style="position:absolute; top:%@px; left:%@px">'.fmt(item.uid, 0, 250*index));
			
	        html.push('<div class="canvas_info">');
			html.push('<div class="thumbnail">');
			html.push('<div class="shorttime">%@</div>'.fmt(item.shorttime));
			html.push('<img class="canvasitem-thumbnail" src="%@"/></div>'.fmt(item.thumbnail));
			html.push('<div class="canvasitem-title">');
			html.push('<div class="label" title="게시판으로 이동">%@</div>'.fmt(item.canvas_title));
			html.push('<div class="body">%@</div>'.fmt(item.title));
			html.push('<div class="comment">%@</div>'.fmt(item.latest_comment.body));

			html.push('</div></div></div>');
			
			return html.join('');
	    }
	});
	
	$egg('#comment-bar').live('click dblclick', Collage.itemController.eventHandler.bind(Collage.itemController));
	
	/***
	$egg('#comment-bar.notepad .reload-button').click(function() {
		$egg("#comment-bar .widget-content").load("/canvas/notes/"+canvas.id, function() {
			
		});
	});
	****/
	
	$egg('#comment-bar.inbox .reload-button').click(function() {
	    app.inboxItems = [];
	    $egg.getJSON("/canvas/inbox", function(data) {
			$egg('#comment-bar').removeClass('empty');
			var len = data.length;
			
			for (var i=0;i<len;i++) {
				var item = new Collage.CanvasItem();
				item = Object.extend(item, data[i]);
				app.inboxItems.push(item);
			}
			$egg('#comment-bar.inbox .widget-content').listview('collection', app.inboxItems);
		});
	});
	
	$egg('#info-panel .tab').click(function() {
		$egg('#tb-canvas-info').click();
	});
	
	
	$egg('#bubble-menu .search_field').bind({
		keydown: function() {
			if (app.textFieldTimer) {
				clearTimeout(app.textFieldTimer);
			}
			app.textFieldTimer = setTimeout(function() {
				$egg('#bubble-menu .search_field').change();
				app.textFieldTimer = null;
			}, 100);
		},
		change: function() {
			var val = $egg(this).val().strip().toLowerCase();

			$egg('#bubble-menu .list-item').each(function() {
				var text = $egg(this).text().strip().toLowerCase();
				$egg(this).setClass('hidden', text.indexOf(val)==-1 );
			});
			
		}
	});
	$egg('#bubble-menu .search_wrapper .search_clear_button').click(function() {
		$egg('#bubble-menu .search_field').val('').change();
	});
	
	$egg(window).bind({
		resize: Collage.mainController.canvas_resize.bind(Collage.mainController)
		/*
		mousedown: function(evt) {
			if ($egg("#bubble-menu:visible").length > 0) {
				if ($egg(evt.target).is("#bubble-menu") || $egg(evt.target).parents('#bubble-menu').length == 0) {
					app.closeBubbleMenu();
				}
			}
		},
		keydown: function(evt) {
		    if (evt.keyCode==8) {
		        evt.preventDefault();
		        //evt.stopPropagation();
		    }
		},
		keydown: function(evt) {
			console.log("WINDOW:%@".fmt(evt.keyCode));
			if (evt.keyCode==37 || evt.keyCode==38) Collage.itemController.selectPrevItem();
			else if (evt.keyCode==39 || evt.keyCode==40) Collage.itemController.selectNextItem();
			
		}*/
	});
	$egg('body').bind({
		mousedown: function(evt) {
			if ($egg("#bubble-menu:visible").length > 0) {
				if ($egg(evt.target).is("#bubble-menu") || $egg(evt.target).parents('#bubble-menu').length == 0) {
					app.closeBubbleMenu();
				}
			}
		}
	});
	
	
	///////////////////////////////////////////////////
	// TOOLBAR
	//
	$egg("#tb-delete-canvasitem").click(function() {
	    if (!!app.staticMode) {
            app.openDialog('브라우저 안내', '/help/browser_warning');
            return false;
        };
        
		if (!$egg(this).hasClass('disabled')) Collage.mainController.deleteCanvasItem();
		//app.confirm("정말 삭제하시겠습니까? 댓글을 포함한 관련정보가 모두 삭제됩니다.");
	});
	$egg('#tb-download-canvasitem').click(function() {
		if (!$egg(this).hasClass('disabled')) Collage.itemController.download();
	});
	$egg('#tb-share-canvasitem').click(function() {
		if (!$egg(this).hasClass('disabled')) app.openDialog('보내기', '/share/document/%@'.fmt(Collage.mainController.currentItem.uid));
	});
	
	$egg('#tb-unread-filter').click(function() {
		$egg(this).toggleClass('sel');
		Collage.mainController.setUnreadFilter($egg(this).is('.sel'));
	});
	$egg('#tb-canvas-info').click(function() {
		//$egg(this).toggleClass('sel');
		if ($egg("#info-panel .tab").is(".expand"))
		{
			$egg('#info-panel .content').empty();
		}
		else
		{
			if (canvas.editable)
				app.openDialog('캔버스 정보', '/canvas/edit/%@'.fmt(canvas.id));
				//$egg('#info-panel .content').load('/canvas/edit/%@'.fmt(canvas.id));
			else
				app.openDialog('캔버스 정보', '/canvas/info/%@'.fmt(canvas.id));
				//$egg('#info-panel .content').load('/canvas/info/%@'.fmt(canvas.id));
		}
		//$egg('#info-panel').toggleClass('expand', 200);
	});
	
	$egg('#tb-canvas-chat').click(function() {
		//app.openDialog('Chat', '/iphone/list/%@'.fmt(canvas.id));
		var controls = [
			{
				type:'html', 
				id: 'chat-window',
				url:'/iphone/list/'+canvas.id,
				onload: function() {
					$egg(this).scrollTop($egg(this).children().first().height());
				}
			}
		];
		
		if (canvas.loggedIn) {
			controls.push({
				type: 'textarea',
				id: 'comment-form',
				className: 'comment-form'
			});
			controls.push(
				{
					type: 'button',
					id: 'send-comment-button',
					label: '댓글저장',
					className: 'send-comment',
					action: function() { 
						var body = $egg('#comment-form').val();
						$egg("#chat-window .chat-container").ajaxAppend('/comment/create_canvas_comment', {
							canvas_uid: canvas.uid,
							body: body
						}, function() {
							$egg('#comment-form').val('');
							$egg("#chat-window").scrollTop($egg("#chat-window .chat-container").height());
						});
					}
				}
			);
			
		}
			
		app.showBubbleMenu($egg(this), controls, 320);
		
	});
	
	$egg('#tb-add-comments').click(function() {

		$egg('#preview-panel .comments-threads').ajaxAppend('/comment/create_thread', 
			{ top: $egg('#preview-panel .comments-threads').parent().scrollTop() }
			, 
			function() {
				$egg(this).find('.comments-bubble').last()
					.draggable({axis: 'y', scroll:true, handle:'.header'})
					.resizable({handles:'se'})
					.bind({
						resizestop: function() {
							if (!canvas.loggedIn) return;
							$egg.post('/comment/meta', { 
								top: ($egg(this).frame().y),
								width: $egg(this).width(),
								thread_id: $egg(this).idattr('thread-'),
								resource_id: Collage.previewController.selectedItem.resourece_id,
								canvas_item_uid: Collage.previewController.selectedItem.uid
							});
						},
						dragstop: function() {
							if (!canvas.loggedIn) return;
							$egg.post('/comment/meta', { 
								top: ($egg(this).frame().y),
								width: $egg(this).width(),
								thread_id: $egg(this).idattr('thread-'),
								resource_id: Collage.previewController.selectedItem.resourece_id,
								canvas_item_uid: Collage.previewController.selectedItem.uid
							});
						}
					})
					.find('.comment_reply .label').click();
				
				if (!$egg('#tb-toggle-comments').hasClass('sel')) $egg('#tb-toggle-comments').click();
			}
		);
	});
	
	$egg('#tb-toggle-comments').click(function() {
		if ($egg(this).hasClass('sel')) {
			$egg('body').addClass('hide-comments');
		} else {
			$egg('body').removeClass('hide-comments');
		}
		$egg(this).toggleClass('sel');
	});
	
	$egg('#close-quickview-button').click(function () {
		$egg('#notepad-button').click();
	});
	
	
	$egg('#notepad-button').click(function() { 
		
		if ($egg(this).hasClass("sel")) {
			$egg('#comment-bar').hide();
			$egg('body').removeClass('quickview_mode');
			/***
			$egg('#canvas_main').animate({right:"0px"}, 300);
			$egg('#preview-panel').animate({right:"0px"}, 300);
			$egg('#comment-bar').animate({right:"-250px"}, 300, function() {
				$egg('#main-view').resize();
			});
			prefs.save("notepad", false);
			***/
		} else {
			$egg('#comment-bar').show();
			$egg('#comment-bar.inbox.empty .reload-button').click();
			$egg('body').addClass('quickview_mode');
			/***
			$egg('#canvas_main').animate({right:"250px"}, 300);
			$egg('#preview-panel').animate({right:"250px"}, 300);
			$egg('#comment-bar').css({right:"-250px"}).show().animate({right:"0px"}, 300, function() {
				$egg('#main-view').resize();
			});
			prefs.save("notepad", true);
			$egg('#comment-bar.inbox.empty .reload-button').click();
			***/
		}
		
		
		//$egg('#comment-bar').toggle();
		$egg(this).toggleClass('sel');
	});
	
	$egg('#close-faceboard-button').click(function () {
		$egg('#tb-canvas-ring').click();
	});
	$egg('#tb-canvas-ring').click(function() {
		$egg(this).toggleClass('sel');
		$egg('#face-board').toggle();
		$egg('body').setClass('faceboard_mode', $egg('#face-board:visible').length>0);
		if ($egg('#face-board:visible').length>0)
		{
			$egg('#face-board').load('/canvas/ring', {id: canvas.uid});
		}
	});
	$egg('#tb-add-ring').click(function() {
		app.openDialog('', '/canvas/add_ring/%@'.fmt(canvas.uid), {width:450});
	});
	
	$egg('#face-board').live('click dblclick', function(evt) {
		var target = $egg(evt.target);
		var item = null;
		if (target.is('.friend-item'))
		 	item = target;
		else 
			item = target.parents('.friend-item');
			
		
		if (item.length > 0)
		{
			item.addClass('sel').siblings().removeClass('sel');
			var controls = [
				{
					type: 'label',
					text: $egg(item).find('.bubble-text').text()
				}
			];
			if (item.is('.me'))
			{
				controls.push({
					type: 'button',
					label: 'Edit',
					action: function() { 
						app.openDialog('', '/canvas/edit_ring/%@'.fmt($egg('#face-board .list-item.sel').idattr('ringitem-')), {width:350});
						app.closeBubbleMenu();
					}
				});
				controls.push({
					type: 'button',
					label: 'Remove',
					action: function() {
						$egg.post('/canvas/remove_ring', {id: $egg('#face-board .list-item.sel').idattr('ringitem-')}, function(data) {
							console.log(data);
							try { eval(data); } catch(e) {}
						});
					}
				});
			}
			app.showBubbleMenu(item, controls, 200);
		}
	});
	
	$egg('#dashboard-button').click(function() { 
		if ($egg(this).hasClass("sel")) {
			$egg('#canvas_main').animate({bottom:"0px"}, 300);
			$egg('#preview-panel').animate({bottom:"0px"}, 300);
			$egg('#dashboard').animate({bottom:"-118px"}, 300, function() {
				$egg('#main-view').resize();
				$egg(this).hide();
				$egg("#dashboard-button .label").text("새 아이템을 추가해보세요");
			});
			prefs.save("dashboard", false);
		} else {
			$egg('#canvas_main').animate({bottom:"118px"}, 300);
			$egg('#preview-panel').animate({bottom:"118px"}, 300);
			$egg('#dashboard').show().animate({bottom:"0px"}, 300, function() {
				$egg('#main-view').resize();
				$egg("#dashboard-button .label").text("아래 아이콘을 게시판으로 드래그하세요");
			});
			prefs.save("dashboard", true);
		}
		$egg(this).toggleClass('sel');
	});
	
	
	/*
	$egg(window).bind('resize', function() {
		console.log("resize");
		var f = $egg('#comment-bar').frame();
		var width = $egg('#wrapper').width();
		var height = $egg('#wrapper').height();
		
		console.log("width:%@".fmt(width));
		console.log("height:%@".fmt(width));
		debug_frame("f", f);
		if (f.x+f.width > width) {
			f.x = Math.max(width - f.width - 10, 10);
			$egg('#comment-bar').frame(f);
		}
			
		if (f.y+f.height > height) {
			f.y = Math.max(50, height - f.height - 10);
			$egg('#comment-bar').frame(f);
		}

	});
	*/
	
	//dashboard
    var widget_drag_opts = {containment:'#canvas2d', scroll:false, helper:'clone'};
    $egg("#dashboard .widget-icon").draggable(widget_drag_opts)
    .bind('dragstop', Collage.mainController.canvas_widget_drop.bind(Collage.mainController));
    

	
    $egg('#load-progress').progressbar({value:0});
    /*
    $egg('#canvas2d').droppable({accept:"#dashboard .widget-icon", greedy:true}).bind('drop', Collage.mainController.canvas_widget_drop.bind(Collage.mainController));
    */
	$egg("#inspector .touch-button").bind({
		mousedown: function(evt) {
			$egg(this).addClass('active');
		},
		mouseup: function(evt) {
			$egg(this).removeClass('active');
		}
	});
    $egg("#inspector .touch-button.style-button").bind({
		click: function(evt) {
			$egg('#inspector').removeClass(INSPECTOR_MODES).addClass('stylemode');
		}
	});
	$egg("#inspector .touch-button.copy-button").bind({
		click: function(evt) {
			$egg('#inspector').removeClass(INSPECTOR_MODES).addClass('canvaslistmode');
			$egg('#inspector .canvas-list').load('/collage/target_canvas_list', {canvas_id: canvas.id}).show();
		}
	});
	$egg("#inspector .touch-button.remove-button").bind({
		click: function(evt) {
			$egg('#tb-delete-canvas').click();
		}
	});
	/*
	$egg("#inspector .touch-button.scrap-button").bind({
		click: function(evt) {
			$egg.getJSON('/collage/feeding_canvas_item', 
				{ 
					canvas_item_uid:Collage.mainController.currentItem.uid, 
				}, 
				function(data) {
					console.log(data);
					if (!data || data.error) {
						alert(data.error);
					}
					else
					{
					
					}
				}
			);
		}
	});
	*/
	$egg("#inspector .touch-button.open-button").bind({
		click: function(evt) {
			app.openDocument(Collage.mainController.currentItem);
		}
	});
	$egg("#inspector .touch-button.open-canvas-button").bind({
		click: function(evt) {
			//if (this.is('#inspector.topmode .open-canvas-button')) {
				if (Collage.mainController.currentItem)
					app.openCanvas("%@".fmt(Collage.mainController.currentItem.url));
			//}
			
		}
	});
	
	
    $egg("#inspector input[type='checkbox']").bind({
        change: function(evt) {
            if (!!app.staticMode) {
                app.openDialog('브라우저 안내', '/help/browser_warning');
                return false;
            };
            var item = Collage.mainController.currentItem;
            if (!item) return;

    		if ($egg(this).is('.shadow')) {
    			item.visual_style.vshadow = $egg(this).attr('checked');
    			item.saveStyleChanges();
    			Collage.mainController.updateItem(item);

            } else if ($egg(this).is('.border')) {
                item.visual_style.vborder = $egg(this).attr('checked');
                item.saveStyleChanges();
                Collage.mainController.updateItem(item);

            } else if ($egg(this).is('.title')) {
                item.visual_style.vshow_title = $egg(this).attr('checked');
                item.saveStyleChanges();
                Collage.mainController.updateItem(item);
            }
        }
    });
    $egg("#inspector .upload_info .progress").progressbar();
    $egg("#inspector .body").click(function(evt) {
        var elem = $egg(this);
        
        if (!elem.is("#inspector.editable .body")) return;
        
        if ($egg('#inplace-editor').length>0) 
		{
		    /**
			$egg('#inplace-editor')
				.unbind('blur keydown').hide()
				.siblings(".body").show()
				.parents('#inplace-editor').removeClass('editing');
				
			$egg('#inplace-editor').remove();		
			**/
			$egg('#inplace-editor').blur();
		}
		elem.before('<div contenteditable="true" id="inplace-editor" style="background-color:white;">%@</div>'.fmt(elem.text())).hide();

		$egg("#inplace-editor").bind({
			blur: function(evt) {
				$egg(this).unbind('blur keydown').hide().removeClass('editing').siblings(".body").show();
				$egg(this).remove();
				$egg('#inspector').removeClass('editing');
			},
			keydown: function(evt) {
				if (evt.keyCode == '13') {
				    var val = $egg(this).text();
				    
				    var item = Collage.mainController.currentItem;
				    if (item) {
				        item.title = val;
				        item.rUpdate(['title']);
				    }
				    $egg(this).siblings(".body").text(val);
				    $egg(this).blur();
				    Collage.mainController.updateItem(Collage.mainController.currentItem);
				    
				} else if (evt.keyCode == '27') {
				    $egg(this).blur();
				}
			}
		}).val(elem.text()).focus();

		$egg('#inspector').addClass('editing');
		if (document.getSelection)
		{
		    //if (document.getSelection().collapseToEnd) document.getSelection().collapseToEnd();
		} 
		else if (document.selection)
		{
		    //var r = document.selection.createRange();
		    //r.collapse(true);
		    //r.select();
		}
		$egg("#inplace-editor").focus();
    });
    
	
	Collage.mainController.attachView();
	
	Collage.previewController.attachView({
		view:'#preview-panel', 
		tabView:'#image_viewer_tool_segment',
		listviewer: {
			view:"#preview-panel .list-scroll-view .list-view"
		},
		bookviewer: {
			view:"#preview-panel .book-viewer .page_list_view",
			scrollView:"#preview-panel .book-viewer"
		},
		tableviewer: {
			view:"#preview-panel .table-viewer"
		}
	});
	
	Collage.itemController.attachView({view:'#comment-bar'});
	Collage.mainController.scrollToCenter();
	
	/// 쿠키 처리 시작
	//  legacy 쿠키 제거
	Popegg.Cookie.removeCookie('stack', '/');
	Popegg.Cookie.removeCookie('stack', '/collage/canvas');

	//$egg('#tb-unread-filter').addClass('sel');
	//Collage.mainController.applyUnreadFilter = true;
	//
	if (window.location.hash.split('/').length>2) {
		window.location.hash = window.location.hash.split('/').slice(0,2).join('/');
	}
	if (Prototype.Browser.IE) {
		$egg('body').addClass('IE');
		if (Prototype.Browser.IE6) {
			window.location = "/help/browser_warning_ie60";
			return;
		}
		
		
		app._startTrackingHashChange();
		//SC.page.msgbox.hideMessage();  // '로드 중' 메시지 없앰
		//SC.page.htmlDlg.open('/help/browser_warning', null, true);
		app.openDialog('브라우저 안내', '/help/browser_warning');
		
		return;
	}
	Collage.mainController.makeCanvasSmart();
	app._startTrackingHashChange();
    
    //$egg('#comment-bar.inbox .reload-button').click();
};

var INSPECTOR_MODES = "buttonmode stylemode canvaslistmode widgetmode uploading Canvas ImageItem MovieItem WebItem BookItem DocItem NoteItem LabelItem";
