DocumentManager = Class.create({

    table     	 : null, 	// parent DOM element that lists document categories
		url					 : null,	   // base url in format /Controller/Action, used to send AJAX requests
    categories   : new Hash(), // will hold all categories and their documents
		popup				 : {},
		error 			 : null,


    categoryTR : new Template(
		    '<tbody class="cat #{stat}" id="cat#{id}" rel="#{location}">'
			+ '<tr>'
			+ '<td class="name"><div class="expandImage"></div><span>#{name}</span></td>'
			+ '<td class="location"><a href="">#{url}</a></td>'
			+ '<td class="num">#{num}</td>'
			+ '<td class="mod">'
			+ '<a href="" class="add">addDoc</a>&nbsp;'
			+ '<a href="" class="edit">edit</a>&nbsp;'
			+ '<a href="" class="delete">delete</a>&nbsp;&nbsp;'
			+ '<div class="sort up">&nbsp;&nbsp;&nbsp;&nbsp;</div>'
			+ '<div class="sort down">&nbsp;&nbsp;&nbsp;&nbsp;</div>'
			+ '</td>'
			+ '</tr>'
			+ '</tbody>'
    ),
		
		documentListTR: new Template(
			 '<tr class="docList">'
			+ '<td colspan="4">'
			+	'<table cellspacing="0" class="list" id="catList#{cat_id}">'
			+	'<tbody><tr class="heading">'
			+	'<td width="20%">Document Title</td><td width="15%">Download File</td><td width="5%">&nbsp;</td><td width="25%">Document Description</td><td width="10%">Posted By</td><td width="8%">Uploaded</td><td width="30%">Modify</td>'
			+	'</tr></tbody>'
			+	'</table>'
			+	'</td>'
			+	'</tr>'
    ),
		
	/*documentTR : new Template(
			  '<tbody id="doc#{id}" class="doc">'
			+	'<tr>'
			+ '<td class="name">#{name}</td>'
			+ '<td class="filename"><a href="#{url}">#{file}</a></td>'
			+ '<td>#{created}</td>'
			+ '<td width="160" class="mod">'
			+ '<a href="" class="postcmt">post comment</a>&nbsp;'
			+ '<a href="" class="edit">edit</a>&nbsp;'
			+ '<a href="" class="delete">delete</a>&nbsp;&nbsp;'
			+ '<div class="sort up">&nbsp;&nbsp;&nbsp;&nbsp;</div>'
			+ '<div class="sort down">&nbsp;&nbsp;&nbsp;&nbsp;</div>'
			+ '</td>'
			+ '</tr>'
			+ '</tbody>'
    ),*/
    
    documentTR : new Template(
			  '<tbody id="doc#{id}" class="doc">'
			+	'<tr>'
			+ '<td class="name">#{name}</td>'
			+ '<td class="filename"><a href="#{url}">#{file}</a></td>'
			+ '<td><a href="#{url}"><img src="/images/#{ftype}.png" width="15" height="15"></a></td>'
			+ '<td class="name">#{docdesc}</td>'
			+ '<td class="filename"><a href="http://realty-developer.com/index/memberprofile/proId/#{uid}">#{user}</a></td>'			
			+ '<td>#{created}</td>'
			+ '<td class="mod">'
			+ '<a href="" class="postcmt">comments</a>&nbsp;'
			+ '<a href="" class="edit">edit</a>&nbsp;'
			+ '<a href="" class="delete">delete</a>&nbsp;&nbsp;'
			+ '<input type="hidden" id="sesid#{id}" name="sesid" value="#{sid}">'
			+ '<input type="hidden" id="userid#{id}" name="userid" value="#{uid}">'			
			+ '</td>'
			+ '</tr>'
			+ '</tbody>'
    ),

    initialize : function(cats, table, url, popup)
    {
			
			this.table = $(table);
			this.url = url;
			this.popup = popup; 
						
			this.notice=$('notice');
			this.error=$('error');
			
			this.table.select('.divide a').each(function(link) {	
					link.observe('click',  this.openLocationWin.bindAsEventListener(this));		
					}, this);
								
			// if no cats passed in, skip cat initialization;
			if(Object.isArray(cats) && !cats.length)
				return;
				
			this.categories = $H(cats);
			this.categories.each(function(pair){
					var cat = pair.value;
					cat.dom = this.table.down('#cat'+cat.id); 
					cat.docs = new Hash();
					var cat = $H(cat);
					this.categories.set(pair.key, cat);
					this.addCatListeners(cat);
			}, this);

    },
		
	 updateCategories : function()
    {	
				
				this.categories.each(function(pair){
							var cat = pair.value;
							if(!cat)
								return;
							var dom = cat.get('dom');
							
							var numDocs = cat.get('num');
							var numDocsShown = parseInt(dom.down('.num').innerHTML);
							
							// if num docs has changed, update
							if (numDocs != numDocsShown){
								
								dom.down('.num').update(numDocs);
								var img = dom.down('.name .expandImage');
																	
								if(!numDocsShown){
									dom.removeClassName('minus');
									dom.removeClassName('inactive');
									dom.addClassName('plus');
									
									img.observe('click', this.toggleDocList.bindAsEventListener(this));
									// turn class name oon
								}
								else if(!numDocs){
									
									dom.removeClassName('minus');
									dom.removeClassName('plus');
									dom.addClassName('inactive');
									
									cat.unset('domList');
									cat.set('docs', new Hash());
									dom.down('.docList').remove();
									
									img.stopObserving('click');
								}
							}
							
																
							}, this);

    },
		
	addCatListeners: function(cat){

					var dom = cat.get('dom');
					var img = dom.down('.name .expandImage');
					
					if(cat.get('num'))
						img.observe('click', this.toggleDocList.bindAsEventListener(this));
					
					/*var deleteLink = dom.down('.mod .delete');
					deleteLink.observe('click', this.deleteCat.bindAsEventListener(this));	*/
								
					var editLink = dom.down('.mod .edit');
					editLink.observe('click', this.editCat.bindAsEventListener(this));				
					
					var addLink = dom.down('.mod .add');
					addLink.observe('click', this.addDoc.bindAsEventListener(this));
					
					//var locLink = dom.down('.location a');
					//locLink.observe('click', this.openLocationWin.bindAsEventListener(this));
					
					dom.select('.sort').each(function(img) {	
					img.observe('click',  this.sortCat.bindAsEventListener(this));		
					}, this);
				
		},
		
		
		onFailure : function(transport)
    	{
			
			alert('no go');
			
		},
			
		
		getDocuments : function(cat_id)
    	{
			
			if(!parseInt(cat_id))
				return;
				
				var options = {
            method     : 'POST',
						parameters : 'action=getDocuments&cat_id='+cat_id,
            onSuccess  : this.onGetDocuments.bind(this),
            onFailure  : this.onFailure.bind(this)
        };
		//alert(this.url);		
        new Ajax.Request(this.url, options);
				
		},
		
		// method to add docs upon category toggle, uses same logic as addDocument()
		// ADDED for performance: attach one HTML string for all documents instead of calling addDocument on each
		onGetDocuments : function(transport)
    	{
			//alert(transport.responseText)
			var json = transport.responseText.evalJSON(true);
			
			if(json.error){
				alert('error getting documents');
				return false;
			}
			var docs = json.docs;
			if(!docs.length || !docs[0].category_id)
				return;
			
			var cat = this.categories.get(docs[0].category_id);
			var docList = cat.get('domList');
			if(!docList)
				return;

			var docHTML = '';
			var length = docs.length;
			
			for(var i=0; i<length; i++){
				
				var doc = docs[i];
				var resl=doc.file.split('.');
				var filetype=resl[1];
				docHTML +=this.documentTR.evaluate({id:doc.id,
								name:doc.name,
								file:doc.file,
								url:doc.url,
								user:doc.userName,
								uid:doc.user_type_id,
								sid:doc.sessid,
								ftype:filetype,
								docdesc:doc.descr,
								created:doc.created});								
			}
	
			//docList.innerHTML=docHTML;
			
			//alert(docHTML);
			docList.insert(docHTML);
			//alert();
			this.table.select('.docList table').invoke('addClassName','show');
			
			var docHash = cat.get('docs');
			for(var i=0; i<length; i++){
				var doc = docs[i];
				doc.dom = docList.down('#doc'+doc.id);
				var id = doc.id;
				var newDoc = $H(doc);
				docHash.set(id, newDoc);
				this.addDocListeners(newDoc);
			}

		},
		
		
		addCategory : function(cat)
    	{

			if(!cat.id)
				return;

			cat.num = parseInt(cat.num) ? parseInt(cat.num) : 0;
			var status = cat.num ? 'plus' : 'inactive';
			
			var catTR = this.categoryTR.evaluate({id:cat.id,
							location:cat.location,
							url:cat.url,
							num:cat.num,
							stat:status,
							name:cat.name});

			var regExp = new RegExp('id="?cat(\\\d+)"? rel="?'+cat.location+'"?', "mi");
			
			var order = $A([]);
			this.table.innerHTML.gsub(regExp, function(match){
									order.push(match[1]);
			});
			
			if(order.size())		
				this.categories.get(order[order.size()-1]).get('dom').insert({'after':catTR});
				
			else{
				var loc = $('loc'+cat.location);
				loc.insert({'after':catTR});
			}

			// store reference to dom for easier/later manipulation
			cat.dom = this.table.down('#cat'+cat.id); 
			
			// hash container for documents
			cat.docs = new Hash();
			var newCat = $H(cat);
			this.categories.set(cat.id, newCat);
			
			this.addCatListeners(newCat);

		},
		
		onUpdateDoc: function(doc,mode){
		
			
			if(!doc.id || !doc.category_id)
				return;

			var oCat = this.categories.get(doc.category_id);

			if(mode=='edit'){
				/*alert(doc.user_type_id+' '+doc.sessid);
				if(doc.user_type_id!=doc.sessid){
			     return;
				}*/
			     
				Lightview.hide();
				this.notice.update('<strong>"'+doc.file+'"</strong> ('+doc.name+') updated.').show();
				
				var oDoc = oCat.get('docs').get(doc.id);
				var swapCategory = (doc.old_cat_id && doc.old_cat_id!=doc.category_id);

				if(swapCategory){
					oCat.set('num', oCat.get('num')+1);
					var oldCat = this.categories.get(doc.old_cat_id);
					oldCat.set('num', oldCat.get('num')-1);
					
					this.removeDoc(doc.id, doc.old_cat_id);
					this.addDocument(doc);
					this.updateCategories();
				}
					
				else{
					oDoc.get('dom').down('.name').update(doc.name);
				}
			}
			
			else if(mode=='add'){
				
				oCat.set('num',parseInt(oCat.get('num')+1));
				this.addDocument(doc);
				this.updateCategories();
				
			}
			
		},	
		
		onUpdateCat: function(cat,mode){
		
			if(!cat.id || !cat.name)
				return;

			if(mode=='edit'){
				
				Lightview.hide();
				this.notice.update('Category <strong>"'+cat.name+'"</strong> in '+cat.location+' updated.').show();
				
				var oCat = this.categories.get(cat.id);
				

				if(oCat.get('name')!=cat.name){
					this.categories.get(cat.id).set('name', cat.name);
					oCat.get('dom').down('.name span').update(cat.name);
					var locLink = oCat.get('dom').down('.location').update('<a href="">'+cat.url+'</a>');
					locLink.observe('click', this.openLocationWin.bindAsEventListener(this));
				}
				
				
				var locationSwap = (cat.location != oCat.get('location'));

				if(locationSwap){
					oCat.get('dom').remove();
					this.addCategory(cat);
				}
		
			}
			
			else if(mode=='add'){
				
				var loc = $('loc'+cat.location);
				
				// no locatons or categories existed before, so turn off/on parent page dom elements/listeners
				if(!$('loc'+cat.location).visible()){
					$('loc'+cat.location).show();
					if($$('#addNewCategory a').size())
						$$('#addNewCategory a')[0].stopObserving('click');
					if($('addNewCategory'))
						$('addNewCategory').remove();
					if(!$('addDocLink').visible()){
						$('addDocLink').show();
						$('addDocLink').observe('click', this.addDoc.bind(this));
					}
				}
				
				this.addCategory(cat);
			}
				
		},
			
		addDocument : function(doc)
    	{
			
			if(!doc.id || !doc.category_id)
				return;
		
			var cat = this.categories.get(doc.category_id);
			
			var docList = cat.get('domList');
			//docList.up(1).addClassName('show');
			if(!docList)
				return;
				
			var docHTML = this.documentTR.evaluate({id:doc.id,
							name:doc.name,
							file:doc.file,
							url:doc.url,
							user:doc.userName,
							uid:doc.user_type_id,
							sid:doc.sessid,
							created:doc.created});
			
			
			docList.insert(docHTML);

			// store reference to dom for easier manipulation
			doc.dom = docList.down('#doc'+doc.id);
			
			var docs = cat.get('docs');
			var id = doc.id;
			
			var doc = $H(doc);
			docs.set(id, doc);

			this.addDocListeners(doc);
			
		},
		
		// event handler for edit doc links
		editDoc: function(e){
			
			Event.stop(e);
			//for surfer user
			alert('Please login first to edit the document');
			document.location="/account/login";
			//alert(doc.user_type_id+' '+doc.sessid);
			var link = $(Event.element(e));
			var id = link.up('.doc').id.gsub(/\D/,'');
			//var doc = doc.get('dom');
			//alert(doc);
			this.showPopup({'type':'doc','id':id});

		},
		
		addCmt: function(e){
			
			Event.stop(e);
			alert('Please login first to post the comment')
			//for surfer user
			document.location="/account/login";
			var link = $(Event.element(e));
			var id = link.up('.doc').id.gsub(/\D/,'');
			//alert(link+' '+id);
			this.showPopup({'type':'doccomments','id':id});

		},
		
		// event handler for edit cat links
		editCat: function(e){
			
			Event.stop(e);
			//for surfer user
			alert('Please login first to edit the category');
			document.location="/account/login";
		
			var link = $(Event.element(e));
			var id = link.up('.cat').id.gsub(/\D/,'');
			
			this.showPopup({'type':'cat','id':id});

		},
		
		// event handler for add doc links
		addDoc: function(e){
			
			Event.stop(e);
			//for surfer user
			alert('Please login first to upload the document');
			document.location="/account/login";			
			
			var link = $(Event.element(e));
			
			var cat_id = null;
			if(link.up('.cat'))
			 	cat_id = link.up('.cat').id.gsub(/\D/,'');
			
			this.showPopup({'type':'doc','cat_id':cat_id});
					
		},
		
		// event handler for add doc links
		addCat: function(e){
			
			Event.stop(e); 
			//for surfer user
			alert('Please login first to create the category');
			document.location="/account/login";
			
			this.showPopup({'type':'cat'});
					
		},
		
				
		openLocationWin: function(e){			
			Event.stop(e);
			var link = $(Event.element(e));
			var url = null;
			
			if(link.up().className=='location')
				url = $(Event.element(e)).innerHTML;
			else{
				url = link.href;
			}

			window.open(url, 'locations').focus();
		
		},
		
		// event handler for add doc links
		deleteDoc: function(e){
			
			Event.stop(e);
			
			var doc = $(Event.element(e)).up('.doc');
			var id = doc.id.gsub(/\D/,'');
			var name = doc.down('.name').innerHTML;
			var dses='sesid'+id;
			var dus='userid'+id;
			var sesid =document.getElementById(dses).value;
			var usrid =document.getElementById(dus).value;			
			if(sesid!=usrid) {
				alert('Please login first to delete a document!')
				window.parent.location.href="/account/login";
				return;
			}
			if(!id)
				return;
				
			if(confirm("Cofirm deleting file \""+name+'"?')){
				
				
				var options = {
            method     : 'POST',
						parameters : 'action=deleteDocument&id='+id,
            onSuccess  : this.onDeleteDoc.bind(this),
            onFailure  : this.onFailure.bind(this)
        };
				
        new Ajax.Request(this.url, options);
				
			}
			//this.showPopup('doc',null);
		},
		
		onDeleteDoc: function(transport){
			
			alert(transport.responseText);
			var json = transport.responseText.evalJSON(true);
			
			if(json.error){
				alert('error deleting document');
				return false;
			}
			
			var doc = json.doc;
			
			this.removeDoc(doc.id, doc.category_id);
			var cat = this.categories.get(doc.category_id);
			cat.set('num', cat.get('num')-1);
			
			this.updateCategories();
			
		},
		
		removeDoc: function(id, cat_id){
			
			var docTR = this.categories.get(cat_id).get('docs').get(id).get('dom');
			docTR.down('.edit').stopObserving('click');	
			docTR.remove();
			this.categories.get(cat_id).get('docs').unset(id);
					
		},
		
		// event handler for sort doc links
		sortDoc: function(e){
		
			Event.stop(e);
			
			var img = $(Event.element(e));
			var dir = (img.className=='sort up') ? 'up' : 'down';
			var tbody  =	img.up('.doc');
			var tbodySibling = (dir=='up') ? tbody.previous() : tbody.next();
			
			if(tbodySibling && tbodySibling.id.include("doc")){
				
				tbody.remove();	
				if(dir=='up')
					tbodySibling.insert({before:tbody});
				else{
					tbodySibling.insert({after:tbody});
				}
					
				var order = $A([]);
				
				tbody.up('table').select('.doc').each(function(el){
					var id = el.id.gsub(/\D/, '');
					order.push(id);
					//order
				});
				
				var options = {
						parameters : 'action=sortDocuments&order='+order.toJSON(),
						method     : 'POST'
				};
	
				new Ajax.Request(this.url, options);
				
			}
				
		},
		
		// event handler for sort cat links
		sortCat: function(e){
		
			Event.stop(e);
			
			var img = $(Event.element(e));
			var dir = (img.className=='sort up') ? 'up' : 'down';
			var tbody  = img.up('.cat');
			var id = tbody.id.gsub(/\D/,'');
			var oCat = this.categories.get(id);
			
			var tbodySibling = (dir=='up') ? tbody.previous() : tbody.next();	
				
			var location = this.categories.get(id).get('location');
			
			if(tbodySibling && tbodySibling.readAttribute('rel') && tbodySibling.readAttribute('rel').include(location)){
				
				tbody.remove();	
				if(dir=='up')
					tbodySibling.insert({before:tbody});
				else{
					tbodySibling.insert({after:tbody});
				}
					
				var order = $A([]);
				
				var regExp = new RegExp('id="?cat(\\\d+)"? rel="?'+location+'"?', "mi");
				
				this.table.innerHTML.gsub(regExp, function(match){
									order.push(match[1]);
				});
				
				var options = {
						parameters : 'action=sortCategories&order='+order.toJSON(),
						method     : 'POST'
				};
	
				new Ajax.Request(this.url, options);
				
			}
				
		},

		// event handler for delete cat links
		deleteCat: function(e){
			
			Event.stop(e);
			
			var cat = $(Event.element(e)).up('.cat');
			var id = cat.id.gsub(/\D/,'');
			var name = this.categories.get(id).get('name');
			
			if(!id)
				return;
				
			if(confirm("Cofirm deleting category \""+name+'"?')){
				
				
				var options = {
            method     : 'POST',
						parameters : 'action=deleteCategory&id='+id,
            onSuccess  : this.onDeleteCat.bind(this),
            onFailure  : this.onFailure.bind(this)
        };
				
        new Ajax.Request(this.url, options);
				
			}
			//this.showPopup('doc',null);
		},


		onDeleteCat: function(transport){
			
			var json = transport.responseText.evalJSON(true);
			
			if(json.error){
				alert('error deleting document');
				return false;
			}
			
			var cat = json.cat;
			
			this.categories.get(cat.id).get('dom').remove();
			
		},
		
		removeDoc: function(id, cat_id){
			
			var docTR = this.categories.get(cat_id).get('docs').get(id).get('dom');
			docTR.down('.edit').stopObserving('click');	
			docTR.remove();
			this.categories.get(cat_id).get('docs').unset(id);
					
		},
		
		
		showPopup: function (options){
		
			var type = options.type;
			if(!/^(doc|cat|doccomments)$/.test(options.type))
				return false;
			
			var options = $H(options);
			options.unset('type');
			
			var url = "/account/"+type+"?"+options.toQueryString();
			//alert(url);	
			/*Lightview.show({
				href: url,
				rel:'iframe',
				options:{ 
					width:this.popup.width,
					height:this.popup.height
				} 
			});*/
		},

		addDocListeners : function(doc)
    {
			// doc dom/element
			var doc = doc.get('dom');
			doc.down('.edit').observe('click', this.editDoc.bindAsEventListener(this));		
			doc.down('.delete').observe('click', this.deleteDoc.bindAsEventListener(this));
			doc.down('.postcmt').observe('click', this.addCmt.bindAsEventListener(this));
			/*var acmt = dom.down('.mod .postcmt');
					acmt.observe('click', this.addCmt.bindAsEventListener(this));*/				
			doc.select('.sort').each(function(img) {	
				img.observe('click',  this.sortDoc.bindAsEventListener(this));		
			}, this);
			
		},
		
		
		toggleDocList : function(e)
    {
			
			var img = $(Event.element(e));
			var trCat = img.up('.cat');
			
			var trDocList = trCat.down('.docList');
		
			if(trCat.className.include('plus')){
					trCat.removeClassName('plus');
					trCat.addClassName('minus');
				}
			else{
					trCat.removeClassName('minus');
					trCat.addClassName('plus');
			}
			
			// check if document list exists in DOM, if so, just toggle visibility
			if(trDocList){
				trDocList.toggle();
				return;
			}
			
			// else, add doclist after category TR
			var trDocList = this.documentListTR.evaluate({'cat_id':trCat.id.gsub(/\D/,'')});
			trCat.insert(trDocList);

			//alert(trCat.outerHTML + "\n\n" + trDocList);
			// store reference to dom for easier/later manipulation
			var cat_id = trCat.id.gsub(/\D/,''); 
			var cat = this.categories.get(cat_id);
			cat.set('domList',trCat.down('.list'));

			// if category has documents, add to trDocList
			if(parseInt(cat.get('num')))
				this.getDocuments(cat_id);
 }

} );

