/****************************************************/
/*   K O M E N T A R E                              */
/****************************************************/


/********************************************************/
/* CommentPost - reprezentuje jeden prispevek komentare */
/********************************************************/

/* Komentar lze vytvorit v neuplne verzi, ktera obsahuje jen udaje
 * commentID, userID, albumID, photoID a ostatni jsou null.
 * Komentar muze docasne existovat take bez sveho IDcka a to v dobe
 * od jeho vzniku do ziskani IDcka ze serveru. */
function CommentPost(commentID, userID, albumID, photoID, ownerID, userName, dateTime, text, thumbFileName) {
    this.CommentID = commentID;
    this.UserID = userID;
    this.AlbumID = albumID || null;
    this.PhotoID = photoID || null;
	this.OwnerID = ownerID || null;
	this.UserName = userName || null;
    this.DateTime = dateTime || null;
    this.Text = text || null;
	this.ThumbFileName = thumbFileName || null;
	this.UndoInfo = null;
}

/* Vrati true, pokud komentar je cely nacteny v cache */
CommentPost.prototype.IsLoaded = function() {
    return this.Text != null;
}

/* Vrati true, pokud komentar smazany */
CommentPost.prototype.IsDeleted = function() {
    return this.UndoInfo != null;
}


/****************************************************************/
/* CommentCache - slouzi k uchovani komentaru na strane klienta */
/****************************************************************/

CommentCache = {
    posts: [],
    postCount: 0,
    indexByPhotoID: [],
    indexByAlbumIDWithPhotos: [],
    indexByAlbumIDWithoutPhotos: [],
    indexByUserIDWithoutAlbums: [],

    /* Zaindexuje komentar do jednoho indexu */
	AddToIndex: function(index, post, key) {
		if (key != null) {
            if (typeof index[key] == "undefined") {
                index[key] = [];
            }
            index[key].push(post.CommentID);
        }
	},
	
	/* Smaze komentar z jednoho indexu */
	DeleteFromIndex: function(index, commentID, key) {
        if (key != null && typeof index[key] != "undefined") {
            var indexToRemove = null;
            for (var i = 0; i < index[key].length; i++) {
                if (index[key][i] == commentID) {
                    indexToRemove = i;
                    break;
                }
            }
            if (indexToRemove != null) {
                var rest = index[key].slice(indexToRemove + 1);
                index[key].length = indexToRemove;
                index[key].push.apply(index[key], rest);
            }		
        }
    },

    /* Zaindexuje komentar (i neuplny) */
    AddToIndexes: function(post) {
        // pridani do indexu podle photoID
		this.AddToIndex(this.indexByPhotoID, post, post.PhotoID);

        // pridani do indexu podle albumID s fotkami
		this.AddToIndex(this.indexByAlbumIDWithPhotos, post, post.AlbumID);

        // pridani do indexu podle albumID bez fotek
		if (post.PhotoID == null) {
			this.AddToIndex(this.indexByAlbumIDWithoutPhotos, post, post.AlbumID);
		}

        // pridani do indexu podle userID bez alb a fotek
		if (post.AlbumID == null) {
			this.AddToIndex(this.indexByUserIDWithoutAlbums, post, post.UserID);
		}
    },
    
    /* Odstrani z indexu komentar dle ID */
    DeleteFromIndexes: function(commentID) {
        var post = this.Get(commentID);

        // smazeni z indexu podle photoID
		this.DeleteFromIndex(this.indexByPhotoID, commentID, post.PhotoID);
		
		// smazeni z indexu podle albumID s fotkami
        this.DeleteFromIndex(this.indexByAlbumIDWithPhotos, commentID, post.AlbumID);
		
        // smazeni z indexu podle albumID bez fotek
        if (post.PhotoID == null) {
    		this.DeleteFromIndex(this.indexByAlbumIDWithoutPhotos, commentID, post.AlbumID);
		}
		
        // smazeni z indexu podle userID bez alb a fotek
        if (post.AlbumID == null) {
    		this.DeleteFromIndex(this.indexByUserIDWithoutAlbums, commentID, post.UserID);
		}
    },

    /* Pridani komentare do cache */
    Add: function(post) {
        if (typeof this.posts[post.CommentID] == "undefined") {
            this.AddToIndexes(post);
        }
        this.posts[post.CommentID] = post;
        this.postCount++;
    },
    
    /* Smaze komentar z cache */
    Delete: function(commentID, undoInfo) {
        if (typeof this.posts[commentID] != "undefined") {
            //this.DeleteFromIndexes(commentID);
            this.posts[commentID].UndoInfo = undoInfo;
            //this.postCount--;
        }
    },
	
	/* Smaze komentar z cache */
    Undo: function(commentID) {
        if (typeof this.posts[commentID] != "undefined") {
            //this.DeleteFromIndexes(commentID);
            this.posts[commentID].UndoInfo = null;
            //this.postCount--;
        }
    },    

    /* Vrati IDcka komentaru k dane fotce */
    GetByPhotoID: function(photoID) {
        if (typeof this.indexByPhotoID[photoID] == "undefined") {
            return [];
        } else {
            return this.indexByPhotoID[photoID];
        }
    },

    /* Vrati IDcka komentaru k danemu albu (nikoli k fotkam alba) */
    GetByAlbumIDWithPhotos: function(albumID) {
        if (typeof this.indexByAlbumIDWithPhotos[albumID] == "undefined") {
            return [];
        } else {
            return this.indexByAlbumIDWithPhotos[albumID];
        }
    },

    /* Vrati IDcka komentaru k danemu albu a fotek v nem */
    GetByAlbumIDWithoutPhotos: function(albumID) {
        if (typeof this.indexByAlbumIDWithoutPhotos[albumID] == "undefined") {
            return [];
        } else {
            return this.indexByAlbumIDWithoutPhotos[albumID];
        }
    },

    /* Vrati IDcka komentaru k danemu uzivateli (jen uzivateli, ne jeho album ci fotkam) */
    GetByUserIDWithoutAlbums: function(userID) {
        if (typeof this.indexByUserIDWithoutAlbums[userID] == "undefined") {
            return [];
        } else {
            return this.indexByUserIDWithoutAlbums[userID];
        }
    },

    /* Vrati komentar na zaklane IDcka komentare */
    Get: function(commentID) {
        return this.posts[commentID];
    },

    /* Vrati pocet komentaru v cache*/
    Count: function() {
        return this.postCount;
    }
}

/*******************************************/
/* CommentAdapter - komunikuje se serverem */
/*******************************************/

CommentAdapter = {
    /* Odesle novy komentar na server. Callbackove funkci preda aktualizovany komentar vcetne ID. */
    Create: function(comment, onComplete) {
        // asynchronni odeslani na server
        // vraceni IDcka ze serveru
		var objectType = 'user';
		var objectID = comment.UserID;
        if (comment.AlbumID != null) {
            objectType = 'album';
            objectID = comment.AlbumID;
        }         
        if (comment.PhotoID != null) {
            objectType = 'photo';
            objectID = comment.PhotoID;
        }        

		$.ajax({
			type: "POST",
			url: "/_www_root_/ajax/comment.php",
			data: { act: "add", objectType: objectType, objectID: objectID, text: comment.Text },
			dataType: 'json',
			success: function(result) {
				if (result.errorCode == 0) {
					// ok
					comment.CommentID = result.commentID;
					comment.DateTime = result.dateTime;
					comment.UserName = result.userName;
					comment.ThumbFileName = result.thumbFileName;
					onComplete(comment, true); // true = povedlo se
				}
				else if (result.errorCode > 0) {
					onComplete(result.errorText, false);
				}
			},
			error: function(xhr, err, e) {
				onComplete('došlo k chybě při komunikaci se serverem', false);
			}
		});
		
    },

    /* Nacte komentare ze serveru dle seznamu IDckek. Callbackove funkci preda pole komentaru. */
    Load: function(commentIDs, onComplete) {		
		$.ajax({
			type: "POST",
			url: "/_www_root_/ajax/comment.php",
			data: { act: "getByAlbumID", albumID: commentIDs },
			dataType: 'json',
			success: function(result) {
                onComplete(result);
			},
			error: function(xhr, err, e) {
	            onComplete(false);
			}
		});
    },
    
    /* Smaze komentar s danym ID */
    Delete: function(commentID, onComplete) {
        $.ajax({
			type: "POST",
			url: "/_www_root_/ajax/comment.php",
			data: { act: "delete", commentID: commentID },
			dataType: 'json',
			success: function(result) {
                onComplete(result);
			},
			error: function(xhr, err, e) {
	            onComplete(false);
			}
		});
    },
	
	Undo: function(commentID, onComplete) {
		var undoInfo = CommentCache.posts[commentID].UndoInfo;
		$.ajax({
			type: "POST",
			url: "/_www_root_/ajax/comment.php",
			data: { act: "undo", undoInfo: undoInfo },
			dataType: 'json',
			success: function(result) {
                onComplete(result);
			},
			error: function(xhr, err, e) {
	            onComplete(result);
			}
		});
	}
}

/******************************************************************/
/* Spravce komentaru, ktery spojuje jednotlive nezavisle objekty. */
/* Take zastresuje komentare z vnejsiho pohledu.                  */
/******************************************************************/

CommentManager = {
    /* Inicializace - v parametru dostane pole komentaru (uplnych ci neuplnych). */
    Init: function(comments) {
        for (var i = 0; i < comments.length; i++) {
            CommentCache.Add(comments[i]);
        }
    },

    /* Zajisti vytvoreni komentare a zavola callback s aktualizovanym komentarem (vcetne ID)
     * nebo null (v pripade neuspechu). */
    Create: function(comment, callback) {
        CommentAdapter.Create(comment, function(comment, success) {
            if (success) {
                CommentCache.Add(comment);
                callback(comment);
            } else {
				//pri neuspesnem vytvoreni komentare hodnota comment = string chybove hlasky 
                callback(comment); 
            }
        });
    },

    /* Ziska seznam IDckek komentaru pro danou fotku. */
    GetByPhotoID: function(photoID) {
        return CommentCache.GetByPhotoID(photoID);
    },

    /* Ziska seznam IDckek komentaru pro dane album vcetne fotek. */
    GetByAlbumIDWithPhotos: function(albumID) {
        return CommentCache.GetByAlbumIDWithPhotos(albumID);
    },

    /* Ziska seznam IDckek komentaru pro dane album (bez fotek). */
    GetByAlbumIDWithoutPhotos: function(albumID) {
        return CommentCache.GetByAlbumIDWithoutPhotos(albumID);
    },

    /* Ziska seznam IDckek komentaru pro daneho uzivatele (bez alb). */
    GetByUserIDWithoutAlbums: function(userID) {
        return CommentCache.GetByUserIDWithoutAlbums(userID);
    },

    /* Vrati komentar na zaklade ID. */
    Get: function(commentID) {
        return CommentCache.Get(commentID);
    },

    /* Nacte (z cache nebo ze serveru) pozadavane komentare dane seznamem IDcek commentIDs.
     * Zavola callback onPreload po zjisteni, jak dlouho bude trvat ziskani komentaru
     * (tedy, zda je treba request na server) a tuto informaci predav v parametru.
     * Nakonec zavola callback onComplete a v parametru preda puvodni seznam ID.
     * Ziskane komentare je mozne nasledne ziskat pomoci metody CommentManager.Get(). */
    Load: function(commentIDs, onPreload, onComplete) {
        var commentsForLoad = [];
        for (var i = 0; i < commentIDs.length; i++) {
			if (!CommentCache.Get(commentIDs[i]).IsLoaded()) {
                commentsForLoad.push(commentIDs[i]);
            }
        }
        if (commentsForLoad.length > 0) {
            onPreload(true);
            CommentAdapter.Load(commentsForLoad, function(loadedComments) {
                for (var i = 0; i < loadedComments.length; i++) {
                    CommentCache.Add(loadedComments[i]);
                }
                onComplete(commentIDs);
            });
        } else {
            onPreload(false);
            onComplete(commentIDs);
        }
    },

    /* Zobrazi komentare podle zvoleneho pohledu. */
    Show: function(commentView) {
        var commentIDs = commentView.getComments();
        this.Load(
            commentIDs,
            function(wait) { commentView.preShow(wait); },
            function() { commentView.show(commentIDs); }
        );
    },
    
    /* Smaze komentar dle ID a zavola callback s vysledkem smazani (uspech/neuspech) */
    Delete: function(commentID, onComplete) {
        CommentAdapter.Delete(commentID, function(success) {
            if (success.errorCode == 0) {
				var undoInfo = success.undoInfo;
                CommentCache.Delete(commentID, undoInfo);
            }
            onComplete(success.errorCode != 0);
        });
    },
	
	Undo: function(commentID, onComplete) {
		CommentAdapter.Undo(commentID, function(success) {
			if(success.errorCode == 0) {
				CommentCache.Undo(success.commentID);
			}
			onComplete(success.errorCode == 0);
		})
	}
}

/*************************************************/
/* Pohled pro komentare v fotce, albu, uzivateli */
/*************************************************/
var timeoutForLoadingComments;
var timeoutForSavingComments;

/* Kontruktoru se predaji nejake parametry pohledu */
function CommentView(userID, albumID, photoID, viewType) {
    this.userID = userID;
    this.albumID = albumID || null;
    this.photoID = photoID || null;
	this.viewType = viewType;
	this.commentBtnEnabled = true;
	var root;
	var textarea;
	var thumbSrc;
	var thumbPath;
}

/* Vrati IDcka komentaru, ktere budou zobrazeny pro dany pohled */
CommentView.prototype.getComments =  function() {
	switch(this.viewType) {
		case 'photo': 			this.root = $("#photoComments div.commentList");
								this.textarea = $("#photoComments form.commentForm textarea");
								this.textarea.autogrow();
								return CommentManager.GetByPhotoID(this.photoID);	
								break;

		case 'album' : 			this.root = $("#albumComments div.commentList");
								this.textarea = $("#albumComments form.commentForm textarea");
								this.textarea.autogrow();						
								return CommentManager.GetByAlbumIDWithPhotos(this.albumID);
								break;

		case 'user' : 			this.root = $("#userComments div.commentList");
								this.textarea = $("#userComments form.commentForm textarea");
								this.textarea.autogrow();
								return CommentManager.GetByUserIDWithoutAlbums(this.userID);
								break;

		case 'albumList' :		this.root = $("li#a_" + this.albumID).find('.commentList');
								this.textarea = $("li#a_" + this.albumID).find("textarea");
								this.textarea.autogrow();
								this.thumbSrc = $('#a_' + this.albumID).find('a.img img').attr('src');
								this.thumbPath = this.thumbSrc.substr(0,this.thumbSrc.indexOf('thumb'));
								this.thumbLink = $('#a_' + this.albumID).find('a.albumName').attr('href');								
								return CommentManager.GetByAlbumIDWithPhotos(this.albumID);							
								break;		
	}						 			
}

/* Zavolano pred zobrazenim komentaru - pokud bude treba stahnout neco ze serveru, delayedShow == true */
CommentView.prototype.preShow = function(delayedShow) {
    //this.root.append('<div class="loadingComments"> Načítám...</div>');
}

/* Zobrazi komentare - v parametru jsou jejich IDcka. Je mozne je ziskavat pres CommentManager.Get(). */
CommentView.prototype.show =  function(commentIDs) { 
	var $this = this;
    var userID = this.userID;
    var albumID = this.albumID || null;
    var photoID = this.photoID || null;
	var viewType = this.viewType;
	var root = this.root;
	var textarea = this.textarea;
	var thumbPath = this.thumbPath || null;
	var thumbLink = this.thumbLink || null;
	var sortedCommentIDs = commentIDs.sort(sortCommentIDs);	//nutno setridit commentIDs pro chronologicke zobrazovani
	
	$('.commentBtn').unbind('click');
	
	//storage je definovano pouze na strance alba, jinak ho musim ziskat z cesty k nahledu alba
	if(typeof storage != 'undefined') {
		thumbPath = storage;
		thumbLink = 'http://www.' + albumUserName + '.' + domain + '/' + albumServerDir + '/';
	}
	
	//zorbazeni pro pocet komentaru < 5
	if (sortedCommentIDs.length <= 5) {		
		for (var i = 0; i < sortedCommentIDs.length; i++) {
			var data = CommentManager.Get(sortedCommentIDs[i]);
				if (data.PhotoID != null) {					
                    root.append(this.createCommentHtmlWithThumb(data, thumbPath, thumbLink));
                } else {
                    root.append(this.createCommentHtml(data));
                } 	
		}		
	}
	
	//zobrazeni pro pocet komentaru > 5
    else{		
		var commentsOnLoad = 3; 
		var hiddenComments = sortedCommentIDs.length - commentsOnLoad; 
		var showAllCommentsInnerHtml;
		var showNext = ( hiddenComments > 4 ) ? ' dalších ' : ' další ' ;
		
		showAllCommentsInnerHtml = '<div id="hiddenCommentsFor_' + albumID + '" class="showAllComments"><a href="#">' + showNext + (commentIDs.length-commentsOnLoad) + ' ' + inflectNounCommentCZ(hiddenComments) + '</a></div>'; 
		var visibleComments = [CommentManager.Get(sortedCommentIDs[0]), CommentManager.Get(sortedCommentIDs[sortedCommentIDs.length - 2]), CommentManager.Get(sortedCommentIDs[sortedCommentIDs.length - 1])];
		for (var i = 0; i < visibleComments.length; i++) {
			if (i == 1) {
				root.append(showAllCommentsInnerHtml);
				$('#hiddenCommentsFor_' + albumID).data('hiddenComments', hiddenComments);
				
				$('.showAllComments').hover(function(){
					$(this).css('background','#eee');
				},
				function(){
					$(this).css('background','#f5f5f5');
				});
			}
			if (visibleComments[i].PhotoID == null) {
				root.append(this.createCommentHtml(visibleComments[i]));
			} else {
				root.append(this.createCommentHtmlWithThumb(visibleComments[i], thumbPath, thumbLink));
			}   
		}	
	}
	
	resizeCommentThumbImage(root);
	
	//automaticke scrolovani chceme na seznamech alb ale ne na seznamu razenem dle posledniho komentare, komentare se zde rozbaluji automaticky
	if ( (this.viewType == 'albumList' && typeof sortedBy == 'undefined') || (this.viewType == 'albumList' && typeof sortedBy != 'undefined' && sortedBy != 'lastComment')) {
		scrollCommentsIntoView(root);		
	}
	
	$('div.loadingComments').remove();
	
	//udalosti po kliku na tlacitko 'pridat komentar'
    $('.commentBtn').click(function() {
		// tlacitko je neaktivni pri prekroceni limitu poctu znaku nebo pri delce komentare == 0
		if($this.commentBtnEnabled) { 
			var progressDiv = '<div id="progressDiv" class="comment"><p>ukládám...</p></div>';

			//nutno rozlisit na strane uzivatele kdy jsou komentare pridavany k uzivateli
			if ($(this).is('#userCommentBtn')) {
				textarea = $(this).parent().find('textarea');
				userID = albumUserID;
				albumID = null;
				photoID = null;
				root = $(this).parents('#userComments').find('.commentList');
			}
			
			//pridani komentare v seznamech alb a reakce na kometare fotek tam kde sou komenateer alb a fotek smichane
			else if ($(this).is('.albumListCommentBtn') || $(this).is('#albumCommentBtn')) {
				textarea = $(this).parent().find('textarea');
				root = ( $this.viewType == 'albumList' ) ? $(this).parents('li').find('.commentList') : $('#albumComments .commentList');
				albumID = ( $this.viewType == 'albumList' ) ? $(this).parents('li').attr('id').substr(2) : albumID;
				
				//pokud se jedna o odpoved na komentar fotky ze seznamu komentaru k albu priradi se hodnota photoID 
				if (typeof $(this).data('photoCommentData') != 'undefined') {					
					photoID = $(this).data('photoCommentData').photoID;
				}
				else {
					photoID = null;
				}				
			}
			
			//nalezeni cesty k nahledu a linku v seznamech alb
			if ($(this).is('.albumListCommentBtn')) {
				thumbSrc = $('#a_' + albumID).find('a.img img').attr('src');
				thumbPath = thumbSrc.substr(0,thumbSrc.indexOf('thumb'));
				thumbLink = $('#a_' + albumID).find('a.albumName').attr('href');							
			} 
			
			var text = textarea.val();
	        if (text == "" || text == textarea.attr('title')) {
				return false;
			}  
	            				
	        textarea.val(textarea.attr('title'));
	        timeoutForSavingComments = setTimeout(function(){root.append(progressDiv)},400);
			//vytvorime novy komentar 
			CommentManager.Create(new CommentPost(null, userID, albumID, photoID, authUserID, null, null, text, null), function(comment) {
				if (comment != null && comment instanceof CommentPost) {
					//komentare k fotce jsou s nahledem
					if (comment.PhotoID != null) {
						root.append($this.createCommentHtmlWithThumb(comment, thumbPath, thumbLink));						
					}
					//vsechny ostatni komentare bez nahledu
					else {
						root.append($this.createCommentHtml(comment));	
					}
					
					resizeCommentThumbImage(root);
					$this.bindDeleteEvent();
					$this.bindReplyLinkClickEvent();
					clearTimeout(timeoutForSavingComments);
					$('#progressDiv').remove();
					  
	            } else {
					clearTimeout(timeoutForSavingComments);
					if ($('#progressDiv p').length > 0) {
						$('#progressDiv p').text(comment).css('color','red'); //  zde promenna comment predstavuje string errorText z XHR
					}
	                else {
						root.append(progressDiv);
						$('#progressDiv p').text(comment).css('color','red'); //  zde promenna comment predstavuje string errorText z XHR
					}
					var t = setTimeout(function(){$('#progressDiv').fadeOut(2000, function(){$(this).remove()});},5000);
	            }
	        });
			
			$(this).removeData("photoCommentData");						
			textarea.css({height: '28px',border: 'thin solid #EEEEEE',background: '#fff'});
			textarea.parents('.commentForm').find('span.charCount').text('');
			textarea.parents('.commentForm').find('div.commentBtn').hide();
			//pokud byla textarea zabalena do divu tento je odebran po odeslani komentare
			
			//vraceni textarey do puvodni graficke podoby po odeslani odpovedi na komentar fotky
			var textareaParent = textarea.parent();		
			if (textareaParent.is('.textareaWrapper')) {				
				textareaParent.find('.commentThumb').remove();
				textareaParent.replaceWith(textareaParent.contents());
				textarea.removeClass('textareaShortMode');
			}
			
	        return false;
		}	
    });
	
	//udalosti po kliku na link 'dalsich n komentaru'
	$(".showAllComments").click(function() {
		root = $(this).parent('.commentList');
		root.empty();
		for (var i = 0; i < sortedCommentIDs.length; i++) {
			var data = CommentManager.Get(sortedCommentIDs[i]);
			if (data.PhotoID != null) {
				root.append($this.createCommentHtmlWithThumb(data, thumbPath, thumbLink));
			} else {
				root.append($this.createCommentHtml(data));	
			}	
		}
		
		resizeCommentThumbImage(root);
		$(this).remove();
		$this.bindDeleteEvent();
		$this.bindReplyLinkClickEvent();
		scrollCommentsIntoView(root);		
		return false;
	});
	
	//udalost po ztrate fokusu na textareu
	textarea.blur(function() {
		keysEnabled=true;
		var commentBtn = $(this).parents('.commentForm').find('div.commentBtn');
		var textareaThumb = $(this).parents('.commentForm').find('div.commentThumb');
		
		if ($(this).val() == '') {

			if (!$(this).is("#photoCommentsTextarea")) {
				//pokud byl pri reply pridan nahled je odebran, ale jak bylo pozdeji rozhodnuto
				//nahled ma byt i v detalilu fotky, kde ho nechceme odebrat.
				textareaThumb.remove();  	
			}
			
			$(this).val($(this).attr('title'));
			$(this).css({border: '1px solid #eee',background: '#fff'});
			
			//pokud byla textarea zabalena do divu pri funkcnosti odpovedet, tento div je odebran
			var textareaParent = $(this).parent();		
			if (textareaParent.is('.textareaWrapper')) {				
				textareaParent.replaceWith(textareaParent.contents());
				$(this).removeClass('textareaShortMode');
			}
			
			else if (textareaParent.is('#photoTextareaWrapper')) {
				textareaParent.css({border: '1px solid #eee',background: '#fff'});
			}
			
			commentBtn.removeData("photoCommentData");
			commentBtn.hide();
		} 
	});
	
	//udalost na focus na textareu
	textarea.focus(function() {
		keysEnabled=false;
		$(this).css('min-height','40px');
		var commentBtn = $(this).parents('.commentForm').find('div.commentBtn');
		$this.charCounter();
		
		commentBtn.focus(function(){			
			$(document).keyup(function(event){
				//enter
				if(event.keyCode == 13 && (commentBtn.is('.hasFocus')) && $this.commentBtnEnabled) {
					commentBtn.click();
				}
			});
		});
		
		if ($(this).val() == $(this).attr('title')) {
			$(this).val('');
			$(this).css({border: '1px solid #ddd',background: '#f5f5f5'});
			commentBtn.show();
		}
		
		var textareaParent = $(this).parent();
		if (textareaParent.is('#photoTextareaWrapper')) {
			textareaParent.css({border: '1px solid #ddd',background: '#f5f5f5'});
		}
		 
	});
	
	//trideni pole s cisly
	function sortCommentIDs(a,b){
		return a - b;
	}
	
	this.bindDeleteEvent();
	this.bindReplyLinkClickEvent();
	commentBtnOnFocusEvent();
	
}

//navaze udalost smazat/obnovit komentar, podle tridy deleteComment/undoComment prirazene k linku kose
CommentView.prototype.bindDeleteEvent = function(){
    $(".commentTrashLink").unbind('click');
	
    $(".commentTrashLink").click(function(){
		var id = $(this).parent().parent().attr('id').substr(8);
		
		if($(this).is('.deleteComment')) {	
	        CommentManager.Delete(id, function(success){
	            var deletedComment = $('#comment_' + id);
	            deletedComment.addClass('deletedComment').removeClass('visibleComment');
	            trashLink = deletedComment.find('a.commentTrashLink');
	            trashLink.removeClass('deleteComment').addClass('undoComment').attr('title', 'obnovit komentář');                      
				return false;
	        });
		}
		
		else if($(this).is('.undoComment')) {
	        CommentManager.Undo(id, function(success){
	            var undoComment = $('#comment_' + id);
	            undoComment.removeClass('deletedComment').addClass('visibleComment');
	            trashLink = undoComment.find('a.commentTrashLink');
	            trashLink.removeClass('undoComment').addClass('deleteComment').attr('title', 'smazat komentář');                      
				return false;
	        });
		}
		
   	return false;	    
    });
}

//umozni po kliku na link "odpovedet" odpovedet na komentar k fotce i v senzamech alb a albu
CommentView.prototype.bindReplyLinkClickEvent = function() {
	$('.replyToPhotoCommentLink').unbind('click');
	var $this = this;
	
	$('.replyToPhotoCommentLink').click(function(){	
		var photoID = $(this).attr('id').substr(8);
		var respondDiv = $(this).parents('.commentList').next('.respond');
		var thumbDiv = $(this).parents('.comment').find('.commentThumb').clone();
		var textarea = respondDiv.find('textarea');
		var commentBtn = respondDiv.find('.commentBtn');
		commentBtn.data("photoCommentData", { photoID: photoID });		

		//wrapper se vytvori pokud jeste nebyl vytvoren
		if (respondDiv.find('div.textareaWrapper').length < 1) {
			textarea.wrap("<div class='textareaWrapper comment'></div>")
					.removeClass('comment')
					.addClass('textareaShortMode');	
		} 
		
		var areaWrapper = respondDiv.find('div.textareaWrapper');
		//pokud byl jiz nahled vlozen je po opakovanem kliku na 'odpovedet' nahrazen novym
		if (areaWrapper.find('.commentThumb').length > 0) {
			areaWrapper.find('.commentThumb').replaceWith(thumbDiv);
		}
		//nahled jeste nebyl vlozen, pripoji se k obalovacimu wrapperu
		else {
			areaWrapper.prepend(thumbDiv);
		}
		areaWrapper.css({border: '1px solid #ddd',background: '#f5f5f5'});
		textarea.focus();
		$this.charCounter();      		
		return false;
	});
}

//zobrazuje/schovava pocitadlo zbyvajicich znaku + tlacitko 'pridat komentar'
CommentView.prototype.charCounter = function(){
	var $this = this;
    var maxLength = 255; //maximalni pocet znaku pro komentar
    var charLeft = 50; //pocet zbyvajicich znaku do limitu
    var counterElement = this.textarea.parents('.commentForm').find('span.charCount');
	var commentBtnInner = this.textarea.parents('.commentForm').find('div').not('.textareaWrapper, #photoTextareaWrapper, .commentThumb'); //oznaci vsechny vnitrni DIVy bezobrazkoveho tlacitka	
 
	this.textarea.keyup(function(){
        var inputText = $(this).val();
        var comment = $.trim(inputText);
        var length = parseInt(comment.length);

		//uzivatel nic nenapsal, tlacitko je sede a neaktivni
		if (length < 1) {
			commentBtnInner.children().addClass('disabledBtn');
			$this.commentBtnEnabled = false;
		}
		//pri napsani aspon jednoho znaku je tlacitko cervene a aktivni
		if (length > 0) {
			commentBtnInner.children().removeClass('disabledBtn');
			$this.commentBtnEnabled = true;
		}		
		//pocet zbyvajicich znaku je viditelny, tlacitko je cervene a aktivni  
        if (length >= (maxLength - charLeft) && length <= maxLength) {
            $this.commentBtnEnabled = true;
			counterElement.text(maxLength - length).css('color','#666');
			commentBtnInner.children().removeClass('disabledBtn');
        }
		//prekrocen max povolena delka, tlacitko je sede a neaktivni		
        else if (length > maxLength) {
			$this.commentBtnEnabled = false;
			counterElement.text((maxLength - length)).css('color','red');
			commentBtnInner.children().addClass('disabledBtn');
        }
		//pocitadlo je chovane pokud se neblizim k maximalni delce
        else {
            counterElement.text('');
        }

    });
}

//vytvori HTML kod pro jeden komentar bez nahledu fotky z objektu data
CommentView.prototype.createCommentHtml = function(data) {

	var strippedText = stripTags(data.Text);
	//42 testovany max pocet znaku v komentari nepretekajici hranice komenatare bez nahledu
	var brokenText = breakLongWord(strippedText, 42); 
	var linkifiedText = linkifyTextLinks(brokenText); 
	var convertedText = linkifiedText.replace(/\n/g, '<br />');
	var commentClasses = '';
	var trashLink = '';
	//nasteveni trid a titulku pro kos smazanemu komentari
	if(data.IsDeleted()) {
		commentClasses = 'comment deletedComment';
		trashLink = "<a href='#' class='commentTrashLink undoComment' title='obnovit komentář'>";
	}
	//nasteveni trid a titulku pro kos viditelnemu komentari
	else {
		commentClasses = 'comment visibleComment';
		trashLink = "<a href='#' class='commentTrashLink deleteComment' title='smazat komentář'>";
	}
	//odliseni barvy komentare pro komentar ktery napsal uzitevel ke sve fotce/albu/sam sobe
	if ( typeof albumUserID != 'undefined' && albumUserID == data.OwnerID ) {
		commentClasses += ' ownerComment';
	}
	
	var html = 	"<div id='comment_" + data.CommentID + "' class='" + commentClasses + "'>" +
        			"<div class='noThumbCommentInner'>";
					//zobrazeni kose pro majitele obsahu nebo majitele komentare
					if ((typeof authUserID != 'undefined' && authUserID == data.OwnerID) || (typeof authUserID != 'undefined' && authUserID == data.UserID)) {
					   html +=  trashLink +
					   				"<img width='9' height='10' border='0' alt='smazat komentář' src='http://www." + domain + "/img/common/ikon-smaz.gif'/>" + 
								"</a>";
					}
		    	html += "<a class='userName' href='http://www." + data.UserName + "." + domain + "/'>" + data.UserName + "</a> " + 
				        "<span class='commentDate' title='" + data.DateTime + "'>" + humane_date(data.DateTime) + "</span>" + 
						"<p>" + convertedText + "</p>" +
			        "</div>" + 
		        "</div>";						
	return html;			
}

//vytvori HTML kod pro jeden komentar s nahledem fotky z objektu data
CommentView.prototype.createCommentHtmlWithThumb = function(data, thumbPath, thumbLink) {	
	var strippedText = stripTags(data.Text);
	//37 testovany max pocet znaku v komentari nepretekajici hranice komenatare s nahledem
	var brokenText = breakLongWord(strippedText, 37); 
	var linkifiedText = linkifyTextLinks(brokenText);
	var convertedText = linkifiedText.replace(/\n/g, '<br />');
	var commentClasses = '';
	var trashLink = '';
	thumbLink = ( this.viewType == 'album' || this.viewType == 'photo') ? '' : thumbLink;

	if(typeof storage != 'undefined') {
		thumbPath = storage;
	}
	//nasteveni trid a titulku pro kos smazanemu komentari
	if(data.IsDeleted()) {
		commentClasses = 'comment deletedComment';
		trashLink = "<a href='#' class='commentTrashLink undoComment' title='obnovit komentář'>";
	}
	//nasteveni trid a titulku pro kos viditelnemu komentari
	else {
		commentClasses = 'comment visibleComment';
		trashLink = "<a href='#' class='commentTrashLink deleteComment' title='smazat komentář'>";
	}
	//odliseni barvy komentare pro komentar ktery napsal uzitevel ke sve fotce/albu/sam sobe
	if ( typeof albumUserID != 'undefined' && albumUserID == data.OwnerID ) {
		commentClasses += ' ownerComment';
	}
		
	var html = 	"<div id='comment_" + data.CommentID + "' class='" + commentClasses + "'>" +
		        	"<div class='commentThumb'>" + 
						"<a href='" + thumbLink + "#" + data.ThumbFileName + "' title='zobrazit detail fotky'>" + 
							"<img class='commentThumbImage' src='" + thumbPath + "thumb/" + data.ThumbFileName + "'/>" + 
						"</a>" + 
					"</div>" +
	        		"<div class='commentText'>";
					//zobrazeni kose pro majitele obsahu nebo majitele komentare
					if ((typeof authUserID != 'undefined' && authUserID == data.OwnerID) || (typeof authUserID != 'undefined' && authUserID == data.UserID)) {
						html += trashLink +
									"<img width='9' height='10' border='0' alt='smazat komentář' src='http://www." + domain + "/img/common/ikon-smaz.gif'/>" + 
								"</a>";
					}				
			html += "<a class='userName' href='http://www." + data.UserName + "." + domain + "/'>" + data.UserName + "</a> " + 
					"<span class='commentDate' title='" + data.DateTime + "'>" + humane_date(data.DateTime) + " </span>";
					//pridani linku "odpoveded" ke komentaru fotek tam kde jsou komentare fotek a alb smichane
					if (( this.viewType == 'album' || this.viewType == 'albumList' ) && (typeof authUserID != 'undefined' && authUserID != data.OwnerID && authUserID > 0)) {
						html += '<a id="replyTo_' + data.PhotoID + '" class="replyToPhotoCommentLink" href="#">odpovědět</a>';
					}
			html +=		"<p>" + convertedText + "</p>" +
					"</div>" + 
				"</div>";			
	return html;			
}

// vrati datum a cas ve formatu YYYY-MM-DD HH:MM:SS
CommentView.prototype.getCurrentTimeAndDate = function(){
  	var date = new Date();
	var day = date.getDate();
    var month = (date.getMonth()).toString();
	month = (month.length < 2) ? '0' + month : month;	
    var year =  date.getFullYear();
	var hours = date.getHours();
	var minutes = date.getMinutes();
	var seconds = date.getSeconds();
	
	return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
}

resizeCommentThumbImage = function(imgParent) {
	//tyhle hodnoty musi byt natvrdo, protoze v seznamech alb je neni mozne ziskat pred zobrazenim
	//jde o rozmer div.commentThumb ve kterem je nahled vlozen
	var containerWidth = 40; 
	var containerHeight = 40; 
	var newWidth;
	var	newHeight;
	var resizedImage = new Image();	 
	var images = imgParent.find('img.commentThumbImage');
	
	images.each(function(){		
		if (jQuery.browser.msie) {
			resizeImage($(this));
		}
		
		else {
			$(this).load(function(){
				resizeImage($(this));				
			});	
		}
	});
	
	function resizeImage(image) {
		resizedImage = image.clone();
			var w = image.width();
			var h = image.height();
			
			if ( w > h ) {
				newWidth = Math.ceil(w/(w/containerWidth));
				newHeight = Math.ceil(h/(w/containerWidth));
			}
			else if ( w < h ) {
				newHeight = Math.ceil(h/(h/containerHeight));
				newWidth = Math.ceil(w/(h/containerHeight));			
			}
			else {
				newWidth = Math.ceil(w/(w/containerWidth));
				newHeight = Math.ceil(h/(h/containerHeight));						
			}
			
			resizedImage.width(newWidth).height(newHeight).css('margin-top',((containerHeight-newHeight)/2));
			image.replaceWith(resizedImage);
			image.remove();
			resizedImage.css('visibility','visible');
	}
}

//pokud by komentare po rozbaleni byly mimo viditelnou cast stranky, stranka je automaticky posunuta
scrollCommentsIntoView = function(commentList) {
	var docTop = $(window).scrollTop();
	var docHeight = $(document).height();
    var docAt = docTop + $(window).height();
	var windowHeight = $(window).height();
	var rootHeight = commentList.height();
	var rootOffset = commentList.offset();
	
	var commentListEndToWindowEnd = (docTop + windowHeight) - (rootOffset.top + rootHeight);
	var commentListTopToWindowTop = rootOffset.top - docTop; 
	
	if ( commentListEndToWindowEnd < 0 && (rootHeight > (windowHeight/2))) {
		$(window).scrollTo( commentList , 1000, {offset:-50} );
	}
	
	else if ( commentListEndToWindowEnd < 0 && rootHeight < (windowHeight/2) ) {
		//posunout okno o absolutni hodnotu schovane casti komentaru + pro odsazeni od spodniho okraje pridanych 100px
		var parametr = '+=' + (Math.abs(commentListEndToWindowEnd) + 100) + 'px';
		$(window).scrollTo( {top:parametr} , 1000 );
	}
}

//prevedeni textovych linku na klikatelne
linkifyTextLinks = function(text){
	var shortURLRegExp = /^(www){1}/;
	return text.replace(/((http\:\/\/|https\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi, function(m) {
    	if(shortURLRegExp.test(m)) {
			m = '<a href="http://' + m + '" target="_blank">' + m + '</a>';
		}
		else {
			m = '<a href="' + m + '" target="_blank">' + m + '</a>';
		}
		return m;		
	});
}

//vytvori HTML strukturu pro formular ke komentarum
createCommentForm = function() {
	var commentForm = 		'<div class="respond">' + 
							'<form class="commentForm">' +
								'<span class="charCount"></span>' + // <span class="infoForTesters">zkušební provoz komentářů - mohou je psát a vidí je jen testeři</span>
								'<textarea title="přidat komentář k albu...">přidat komentář k albu...</textarea>' + 
								'<div class="commentBtn imagelessBtn albumListCommentBtn" tabindex="0">' +
							        '<div class="imagelessBtnOuter disabledBtn" >' +
							            '<div class="imagelessBtnInner disabledBtn">' +
							                '<div class="imagelessBtnPos disabledBtn">' + 
							                    '<div class="imagelessBtnGloss disabledBtn"></div>' +
							                    '<div class="imagelessBtnText disabledBtn">přidat komentář</div>' +
							                '</div>' +
							            '</div>' +
							        '</div>' +
							    '</div>' +
							'</form>' +
							'</div>';
	return commentForm;
}


commentBtnOnFocusEvent = function() {
	//pri focusu na commentBtn se zmeni barva okraju vnitrnich elementu tlacitka
	$('.commentBtn').focus(function(){
		if (!$(this).find('div:eq(0)').is('.disabledBtn')) {
			$(this).find('div:eq(0)').add($(this).find('div:eq(1)')).css('border-color','#cc3300');
			$(this).addClass('hasFocus');	
		}
	});
	//pri ztrate focusu commentBtn se zmeni barva okraju vnitrnich elementu tlacitka	
	$('.commentBtn').blur(function(){
		$(this).find('div:eq(0)').add($(this).find('div:eq(1)')).css('border-color','#CCCCCC');
		$(this).removeClass('hasFocus');
	});
}

//funkce na sklonovani ceskeho slova ' komentář'
inflectNounCommentCZ = function(number) {
	var nounCommentCZ = ' komentář';
	
	if ( number > 1 && number < 5) {
		nounCommentCZ = ' komentáře';
	}
	else if ( number > 4 ) {
		nounCommentCZ = ' komentářů';
	}
	return nounCommentCZ;
}

//odstraneni tagu
stripTags = function(text) {
	return text.replace(/<\/?[^>]+>/gi,'');
}

//dlouhe slova delsi nez num pismen rozdeli na vice radku
breakLongWord = function(text, num) { 
  return text.replace(new RegExp("(\\w{" + num + "})(?=\\w)", "g"), "$1<wbr>");
}

/*
 * Javascript Humane Dates
 * Copyright (c) 2008 Dean Landolt (deanlandolt.com)
 * Re-write by Zach Leatherman (zachleat.com)
 * localized by Radek Pleskac for use in the Czech language
 * 
 * Adopted from the John Resig's pretty.js
 * at http://ejohn.org/blog/javascript-pretty-date
 * and henrah's proposed modification 
 * at http://ejohn.org/blog/javascript-pretty-date/#comment-297458
 * 
 * Licensed under the MIT license.
 */

function humane_date(date_str){
        var time_formats = [
                [60, 'právě teď'],
                [90, 'minutou'], // 60*1.5
                [3600, 'minutami', 60], // 60*60, 60
                [5400, 'hodinou'], // 60*60*1.5
                [86400, 'hodinami', 3600], // 60*60*24, 60*60
                [129600, 'jedním dnem'], // 60*60*24*1.5
                [604800, 'dny', 86400], // 60*60*24*7, 60*60*24
                [907200, 'týdnem'], // 60*60*24*7*1.5
                [2628000, 'týdny', 604800], // 60*60*24*(365/12), 60*60*24*7
                [3942000, 'měsícem'], // 60*60*24*(365/12)*1.5
                [31536000, 'měsíci', 2628000], // 60*60*24*365, 60*60*24*(365/12)
                [47304000, 'jedním rokem'], // 60*60*24*365*1.5
                [3153600000, 'roky', 31536000], // 60*60*24*365*100, 60*60*24*365
                [4730400000, '1 století'] // 60*60*24*365*100*1.5
        ];

        var time = ('' + date_str).replace(/-/g,"/").replace(/[TZ]/g," "),
                dt = new Date,
                //seconds = ((dt - new Date(time) + (dt.getTimezoneOffset() * 60000)) / 1000),
				seconds = ((dt - new Date(time)) / 1000),
                token = 'před ',
                i = 0,
                format;	

        if (seconds < 0) {
                seconds = Math.abs(seconds);
                token = '';
        }
		
        while (format = time_formats[i++]) {
				if (seconds < format[0]) {
                        if (format.length == 2) {
                                return (i > 1 ? token : '') + format[1]; // Conditional so we don't return Just Now Ago
                        } else {
                                return (i > 1 ? token : '') + Math.round(seconds / format[2]) + ' ' + format[1];
                        }
                }
        }

        // overflow for centuries
        if(seconds > 4730400000)
                return Math.round(seconds / 4730400000) + ' centuries' + token;

        return date_str;
}

commentsAfterLoad = function() {
	
	//nacteni komentaru do cache pokud jsou poslany ve strance
	if (typeof commentsInPage != 'undefined') {
		CommentManager.Init(commentsInPage);	
	}
	
	//zobrazeni komentaru k uzivateli na strance uzivatele
	if ($('body').is(".maxi") && typeof albumUserID != 'undefined') {
		CommentManager.Show(new CommentView(albumUserID, null, null, 'user'));
	}
	
	//zobrazeni komentaru v seznamu alb po kliku na link 'n komentaru'
	$('a.commentCount').click(function(){
		var albumID = $(this).parents('li').attr('id').substr(2);
		var albumComments = $('li#a_' + albumID + ' .commentList');
		var albumCommentsLength = $('li#a_' + albumID + ' .commentList div.visibleComment').length;
		var commentForm = $('li#a_' + albumID + ' .respond');
		var commentLink = $('li#a_' + albumID).find('a.commentCount');
		var loadingProgressDiv = '<div id="loadingProgressDiv">načítám...</div>';

		//komentare jsou jiz nacteny v cache a jsou viditelne na strance
		if (albumComments.is(":visible")) {	
			albumComments.hide();
			commentForm.hide();
			
			//k albu nejsou zatim zadne komentare
			if (albumCommentsLength == 0) {
				commentLink.text('přidat komentář');
				commentLink.attr('title','přidat komentář');
			}
			//album ma aspon jeden nebo vice komentaru
			else {
				//pokud jsou komantare zabalene, musim pripocist i zabalene komentare
				if ($('#hiddenCommentsFor_' + albumID).length > 0) {
					albumCommentsLength += $('#hiddenCommentsFor_' + albumID).data('hiddenComments');	
				}
				commentLink.text(albumCommentsLength + ' ' + inflectNounCommentCZ(albumCommentsLength));
				commentLink.attr('title','zobrazit komentáře');	
			}
		}		
		//komentare jsou jiz nacteny v cache ale nejsou zobrazene		
		else if (albumComments.is(":hidden") && albumCommentsLength > 0){
			albumComments.show();
			commentForm.show();
			commentLink.text('skrýt komentáře');
			commentLink.attr('title','skrýt komentáře');
			scrollCommentsIntoView(albumComments);
		}		
		//komentare jeste nejsou nactene a nactou se ze serveru
		else {
			
			albumComments.remove();
			commentForm.remove();
			var commentsParent = $('li#a_' + albumID).find('.basic');
			commentsParent.append('<div class="commentList"></div>');
			
			//formular pro pridani komentare zobrazit jen pro prihlasene uzivatele
			if (authUserID > 0) {
				commentsParent.append(createCommentForm());
				commentBtnOnFocusEvent();
			}
			
			else {
				commentsParent.append('<a class="href-user" href="http://www.' + domain + '/prihlasit">přidat komentář</a>');
			}
			
			//pokud ma album komentare, nactou se ze serveru
			if(!$(this).is('.addComment')) {
				timeoutForLoadingComments = setTimeout(function(){$('li#a_' + albumID + ' .commentList').before(loadingProgressDiv);},400);
				CommentAdapter.Load(albumID, function(result){
					if(result) {
						CommentManager.Init(result);
						CommentManager.Show(new CommentView(authUserID,albumID,null,'albumList'));												
						clearTimeout(timeoutForLoadingComments);
						$('#loadingProgressDiv').remove();
						commentLink.text('skrýt komentáře');																							
					}
					else {
						clearTimeout(timeoutForLoadingComments);
						if ($('#loadingProgressDiv').length > 0) {
							$('#loadingProgressDiv').text('došlo k chybě při komunikaci se serverem').css('color','red'); //  zde promenna comment predstavuje string errorText z XHR
						}
		                else {
							$('li#a_' + albumID + ' .commentList').before(loadingProgressDiv);
							$('#loadingProgressDiv').text('došlo k chybě při komunikaci se serverem').css('color','red'); //  zde promenna comment predstavuje string errorText z XHR
						}
						var t = setTimeout(function(){$('#loadingProgressDiv').fadeOut(2000, function(){$(this).remove()});},5000);												
					}
					
				});					
			}			
			//album nema zadne komentare, pouze se initializuje pohled pro albumList
			else {
				CommentManager.Show(new CommentView(authUserID,albumID,null,'albumList'));
				commentLink.text('skrýt komentáře');
				commentLink.attr('title','skrýt komentáře');
			}												
		}					
	});
	
	//zobrazeni komentaru v seznamu alb serazenych podle posledniho komentare
	if ($('body').is(".maxi") && typeof sortedBy != 'undefined' && sortedBy == 'lastComment') {
		
		$('ul#albumList li').each(function(i){
			$(this).find('div.desc').hide();
			var commentCountLink = $(this).find('a.commentCount');
			
			if (!commentCountLink.is('.addComment')) {
				commentCountLink.text('skrýt komentáře');
				$(this).find('.basic').append('<div class="commentList"></div>');
	
				//formular pro pridani komentare zobrazit jen pro prihlasene uzivatele
				if (authUserID > 0) {
					$(this).find('.basic').append(createCommentForm());
					$('.commentForm textarea').css('min-height','20px');
					commentBtnOnFocusEvent();					
				}
				var albumID = $(this).attr('id').substr(2);			
				CommentManager.Show(new CommentView(albumUserID,albumID,null,'albumList'));
			}		
		});
	}
}

$(document).ready(commentsAfterLoad);
