package org.richfaces.realworld.tree;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.model.SelectItem;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Observer;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.TransactionPropagationType;
import org.jboss.seam.annotations.Transactional;
import org.richfaces.realworld.domain.Album;
import org.richfaces.realworld.domain.Comment;
import org.richfaces.realworld.domain.FriendshipRequest;
import org.richfaces.realworld.domain.Image;
import org.richfaces.realworld.domain.Message;
import org.richfaces.realworld.domain.User;
import org.richfaces.realworld.fileupload.FileManager;
import org.richfaces.realworld.service.IAlbumAction;
import org.richfaces.realworld.service.IImageAction;
import org.richfaces.realworld.service.IMessageAction;
import org.richfaces.realworld.service.IUserAction;
import org.richfaces.realworld.util.NavigationEnum;
import org.richfaces.realworld.util.RatingHelper;
import org.richfaces.realworld.util.SelectedImageIndex;

@Name("treeActionManager")
@Scope(ScopeType.CONVERSATION)
public class TreeActionManager implements Serializable{
	
	@In
	private User user;
	
	@Out(required=false)
	private User selectedUser;
	
	@In(create=true, required=true)
	private IAlbumAction albumAction;
	
	@In(create=true, required=true)
	private RatingHelper ratingHelper;
	
	@In(create=true, required=true)
	private IMessageAction messageAction;
	
	@In(create=true, required=true)
	private IImageAction imageAction;
	
	@In(create=true, required=true)
	private IUserAction userAction;
	
	@In(create=true, required=true) @Out
	private Album album;
	
	@In(create=true) @Out
	private SelectedImageIndex selectedImageIndex;
	
	@In(create=true)
	FileManager fileManager;
	
	@In(create=true)  @Out(required=false)
	private Image selectedImage;

	@In(create=true)  @Out
	private Album selectedAlbum;
	
	@In(create=true) TreeSelectionManager treeSelectionManager;
	
	@In(create=true) @Out TreeRootItem treeRoot;
	
	private String selectedAlbumName;
	
	public String getSelectedAlbumName() {
		return selectedAlbumName;
	}

	public void setSelectedAlbumName(String selectedAlbumName) {
		this.selectedAlbumName = selectedAlbumName;
	}

	public void addAlbum(){
		albumAction.addAlbum(album);
		treeRoot.getAvailableAlbums().add(new SelectItem(album.getName()));
		TreeAlbumItem albumItem = new TreeAlbumItem(album.getId(), treeRoot, album);
		treeRoot.addAlbumToTree(albumItem);
		fileManager.addDirectory(user.getLogin() + fileManager.getFileSeparator() + album.getName());
		selectedImage = null;
		selectedAlbum = albumItem.getAlbum();
		
	}

	public List<String> availableUserLogins(Object suggest){
		List<String> suggestions = userAction.getUsers((String)suggest);
		return suggestions;
	}

	public void editAlbum(Album album){
		boolean nameChanged = !album.getName().equals(album.getChangedName());
		if(nameChanged){
			String directoryOld = user.getLogin() + fileManager.getFileSeparator() + album.getName();
			String directoryNew = user.getLogin() + fileManager.getFileSeparator() + album.getChangedName();
			try {
				fileManager.renameDirectory(directoryOld, directoryNew);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			album.setName(album.getChangedName());
			album.setChangedName(null);
		}
		albumAction.editAlbum(album);
		treeRoot.updateChild(album);
		
	}

	public void deleteAlbum(Album album){
		String albumName = album.getName();
		albumAction.deleteAlbum(album);
		SelectItem item = treeRoot.getSelectItemByName(album.getName());
		treeRoot.getAvailableAlbums().remove(item);
		treeRoot.removeChild(album.getId());
		fileManager.deleteDirectory(user.getLogin() + fileManager.getFileSeparator() + albumName);
		selectedAlbum = user.getChildAlbums().get(0);
		selectedImage = selectedAlbum.getImages().get(0);
	}

	public void deleteImage(Image image){
		int index = image.getAlbum().getIndex(image);
		String albumName = image.getAlbum().getName();
		String imagePath = image.getPath();
		TreeAlbumItem parent = treeRoot.getAlbums().get(image.getAlbum().getId());
		imageAction.deleteImage(image);
		parent.removeChild(image.getId());
		fileManager.deleteImage(user.getLogin() + fileManager.getFileSeparator() + albumName + fileManager.getFileSeparator() + imagePath);
		if(selectedAlbum.getImages().size() > index){
			selectedImage = selectedAlbum.getImages().get(index);
		}else{
			selectedImage = selectedAlbum.getImages().get(index-1);
		}
	}

	public void editImage(Image image){
		TreeAlbumItem parent = treeRoot.getAlbums().get(image.getAlbum().getId());
		boolean parentChanged = !parent.getAlbum().getName().equals(image.getAlbumName());
		imageAction.editImage(image, parentChanged);
		
		if(parentChanged){
			parent.removeChild(image.getId());
			TreeAlbumItem albumItem = treeRoot.getAlbumByName(image.getAlbumName());
			TreeImageItem imageItem = new TreeImageItem(image.getId(),albumItem,image);
			albumItem.addChild(image.getId(), imageItem);
			String fileNameOld = user.getLogin() + fileManager.getFileSeparator() + image.getAlbum().getName() + fileManager.getFileSeparator() + image.getPath();
			String fileNameNew = user.getLogin() + fileManager.getFileSeparator() + image.getAlbumName() + fileManager.getFileSeparator() + image.getPath();
			fileManager.renameImage(fileNameOld, fileNameNew);
			selectedImage = imageItem.getImage();
			selectedAlbum = albumItem.getAlbum();
		}else{
			TreeImageItem imageItem = (TreeImageItem)parent.getChild(image.getId());
			imageItem.setImage(image);
		}	
	}


	@Observer("addImage")
	public void addImage(Image image) {
		imageAction.addImage(image);
		TreeAlbumItem albumItem = treeRoot.getAlbumByName(image.getAlbumName());
		TreeImageItem imageItem = new TreeImageItem(image.getId(),albumItem,image);
		albumItem.addChild(image.getId(), imageItem);
		selectedImage = imageItem.getImage();
		selectedAlbum = albumItem.getAlbum();
	}

	public void editComment(Comment comment) {
		imageAction.editComment(comment);
	}

	public void addComment(Comment comment) {
		imageAction.addComment(comment);
	}

	public void addAutoComment(Image image) {
		Comment comment = new Comment();
		comment.setAuthor(user);
		comment.setDate(new Date());
		comment.setImage(image);
		comment.setMessage("+1");
		imageAction.addComment(comment);
	}

	public void sendMessage(Message message) {
		messageAction.sendMessage(message);
	}

	public Long getCountUnreadedMessages() {
		Long count = userAction.countNotReadedMessages(user);
		return count!= null? count:0;
	}

	public void removeFromFriends(User owner, User removed){
		userAction.removeFromFriends(owner, removed);
		Message message = new Message();
		message.setAuthor(user);
		message.setDate(new Date());
		message.setOwner(removed);
		message.setFriendshipRequest(false);
		message.setReaded(false);
		message.setMessage("You are were removed from friends of "+ user.getLogin());
		message.setTheme("You are were removed from friends");
		messageAction.sendMessage(message);
	}

	public void addToFriends(User friend){
		FriendshipRequest request = friend.getFriendshipRequest(user, friend);
		if(request != null){
			if(!userAction.friendExist(user, friend)){
				userAction.addFriend(user, friend, request);
				Message message = new Message();
				message.setAuthor(user);
				message.setDate(new Date());
				message.setOwner(friend);
				message.setFriendshipRequest(false);
				message.setReaded(false);
				message.setMessage("You are were added to friends by User "+ user.getLogin());
				message.setTheme("You are were added to friends");
				messageAction.sendMessage(message);
			}	
		}/*else{
			throw new Exception("This user won't be your friend!");
		}*/
	}

	public void addToSharedAlbums(Image image){
		userAction.addSharedAlbum(image.getAlbum());
	}
	

	public void removeFromSharedAlbums(Album album){
		userAction.removeFromSharedAlbums(user, album);
	}

	public void vote(Image image){
		imageAction.vote(image, (Long)Long.valueOf(ratingHelper.getInputSlider().getValue().toString()));
	}

	public void showSharedAlbum(Image image){
		NavigationEnum mainArea = NavigationEnum.IMAGE_PREVIEW;
		treeSelectionManager.setMainArea(mainArea);
		selectedUser = image.getAlbum().getOwner();
		selectedAlbum = image.getAlbum();
		selectedImage = selectedAlbum.getImages().get(0);
		selectedImageIndex.setSelectedImageIndex(1);
	}
	

	public void updateSelectedAlbum(){
		selectedAlbum = user.getAlbumByName(this.getSelectedAlbumName());
		selectedImage = selectedAlbum.getImages().get(0);
		selectedImageIndex.setSelectedImageIndex(1);
	}
}
