package jp.sourceforge.shovel.logic.impl;

import java.util.Calendar;
import java.util.TimeZone;

import org.seasar.framework.container.S2Container;

import jp.sourceforge.shovel.RepliesType;
import jp.sourceforge.shovel.SortOrderType;
import jp.sourceforge.shovel.SortType;
import jp.sourceforge.shovel.dao.IUserCustomDao;
import jp.sourceforge.shovel.dao.IUserDao;
import jp.sourceforge.shovel.entity.IUser;
import jp.sourceforge.shovel.exception.ApplicationException;
import jp.sourceforge.shovel.logic.IDirectoryLogic;
import jp.sourceforge.shovel.util.ShovelUtil;

public class DirectoryLogicImpl implements IDirectoryLogic {
    public IUser createUser(String displayName, String foreignKey, String password,
            String email, long profileImageId, String location, String timeZoneId,
            String description, long creatorId, boolean protect) throws ApplicationException {
        long createdTime = Calendar.getInstance().getTimeInMillis();
        if (timeZoneId == null) {
            timeZoneId = TimeZone.getDefault().getID();
        }
        
        if (displayName == null) {
            displayName = "";
        }
        if (foreignKey == null) {
            foreignKey = "";
        }
        if (email == null) {
            email = "";
        }
        ShovelUtil.validateUser(displayName, foreignKey, email, false);
        
        IUser user = (IUser)getContainer().getComponent(IUser.class);
        user.setCreatorId(creatorId);
        user.setCreatedTime(createdTime);
        user.setDescription(description);
        user.setDisplayName(displayName);
        user.setEmail(email);
        user.setForeignKey(foreignKey);
        user.setLocation(location);
        user.setModifierId(creatorId);
        user.setModifiedTime(createdTime);
        user.setPassword(password);
        user.setProtect(protect);
        user.setProfileImageId(profileImageId);
        user.setTimeZoneId(timeZoneId);
        user.setDefaultDesign(true);
        user.setBackgroundColorHex("00A1D9");
        user.setColorHex("000000");
        user.setNameColorHex("000000");
        user.setLinkColorHex("0000ff");
        user.setSidebarBackgroundColorHex("E0FF92");
        user.setSidebarFrameColorHex("87BC44");
        user.setTile(true);
        user.setGrowl(false);
        user.setGrowlHost("");
        user.setGrowlPassword("");
        //TODO
        user.setViewLines(20);
        getUserDao().insert(user);
        
        return user;
    }
    public IUser createTemporaryUser() {
        return (IUser)getContainer().getComponent(IUser.class);
    }
    public IUser getUser(long userId) {
        return getUserDao().find(userId);
    }
    public IUser getUserByForeignKey(String foreignKey) {
        return getUserDao().findByForeignKey(foreignKey, false);
    }
    public IUser getUserByForeignKeyOrEmail(String foreignKey, boolean email) {
        return getUserDao().findByForeignKey(foreignKey, email);
    }
    public IUser getUserByDevice(String deviceType, String address) {
        return getUserDao().findByDevice(deviceType, address);
    }
    public IUser[] getUsers(SortType sortType, SortOrderType sortOrderType, int offset, int limit) {
        return getUserDao().findAll(sortType, sortOrderType, offset, limit);
    }
    public IUser[] getUsers(long[] userIds) {
        if (userIds == null || userIds.length <= 0) {
            return new IUser[0];
        }
        return getUserDao().findAllByUser(userIds, userIds.length);
    }
    public IUser[] getUsers(String[] foreignKeys) {
        if (foreignKeys == null || foreignKeys.length <= 0) {
            return new IUser[0];
        }
        return getUserDao().findAllByForeignKey(foreignKeys, foreignKeys.length);
    }
    public IUser[] searchUsers(String keyword, int offset, int limit) {
        String[] keywords = keyword.split("\\s");
        if (keywords == null || keywords.length <= 0) {
            return new IUser[0];
        }
        return getUserCustomDao().search(keywords, offset, limit);
    }
    public IUser[] getRandUsers(boolean remove, int offset, int limit) {
        return getUserDao().findAllByRand(remove, offset, limit);
    }
    public int updateUser(IUser user) throws ApplicationException {
        long modifiedTime = Calendar.getInstance().getTimeInMillis();
        user.setModifiedTime(modifiedTime);
        
        String displayName = user.getDisplayName();
        String foreignKey = user.getForeignKey();
        String email = user.getEmail();
        //TODO 後で定数に
        if (user.getUserId() == 1) {
            foreignKey = "Administrator";
            user.setForeignKey(foreignKey);
        }
        ShovelUtil.validateUser(displayName, foreignKey, email, false);
        
        return getUserDao().update(user);
    }
    public int updateUserFromImportCsv(IUser user) throws ApplicationException {
        //TODO 後で定数に
        if (user.getUserId() == 1) {
            //Administratorをcsvから変更させない
            throw new ApplicationException("");
        }

        long modifiedTime = Calendar.getInstance().getTimeInMillis();
        user.setModifiedTime(modifiedTime);
        
        String displayName = user.getDisplayName();
        String foreignKey = user.getForeignKey();
        String email = user.getEmail();
        ShovelUtil.validateUser(displayName, foreignKey, email, false);
        
        return getUserDao().updateFromImportCsv(user);
    }
    public int updateUserFromSettings(IUser user) throws ApplicationException {
        long modifiedTime = Calendar.getInstance().getTimeInMillis();
        user.setModifiedTime(modifiedTime);
        
        String displayName = user.getDisplayName();
        String foreignKey = user.getForeignKey();
        //TODO 後で定数に
        if (user.getUserId() == 1) {
            foreignKey = "Administrator";
            user.setForeignKey(foreignKey);
        }
        String email = user.getEmail();
        ShovelUtil.validateUser(displayName, foreignKey, email, false);
        
        return getUserDao().update(user);
    }
    public int updatePicture(long userId, long serverFileId) {
        long modifiedTime = Calendar.getInstance().getTimeInMillis();
        return getUserDao().updatePicture(userId, serverFileId, modifiedTime);
    }
    public int updatePassword(long userId, String password) {
        long modifiedTime = Calendar.getInstance().getTimeInMillis();
        return getUserDao().updatePassword(userId, password, modifiedTime);
    }
    public int updateNotices(long userId, RepliesType repliesType, boolean newFriends, boolean reply,
            boolean recipientDirectMessage, boolean growl, String growlHost, String growlPassword) {
        long modifiedTime = Calendar.getInstance().getTimeInMillis();
        return getUserDao().updateNotices(userId, repliesType, newFriends, reply,
                recipientDirectMessage, growl, growlHost, growlPassword, modifiedTime);
    }
    public int updateRemove(long[] userIds) {
        long modifiedTime = Calendar.getInstance().getTimeInMillis();
        return getUserDao().updateRemove(userIds, modifiedTime, true);
    }
    
    /////
    
    public int incrementFavorites(long userId) {
        return getUserDao().updateIncrementFavorites(userId);
    }
    public int incrementFavorites(String foreignKey) {
        return getUserDao().updateIncrementFavoritesByForeignKey(foreignKey);
    }
    public int decrementFavoritesAll(long statusId) {
        return getUserDao().updateDecrementFavoritesAll(statusId);
    }
    public int decrementFavorites(long userId) {
        return getUserDao().updateDecrementFavorites(userId);
    }
    public int decrementFavorites(String foreignKey) {
        return getUserDao().updateDecrementFavoritesByForeignKey(foreignKey);
    }
    public int incrementGivenFavorites(long userId) {
        return getUserDao().updateIncrementGivenFavorites(userId);
    }
    public int incrementGivenFavorites(String foreignKey) {
        return getUserDao().updateIncrementGivenFavoritesByForeignKey(foreignKey);
    }
    public int decrementGivenFavorites(long userId) {
        return getUserDao().updateDecrementGivenFavorites(userId);
    }
    public int decrementGivenFavorites(String foreignKey) {
        return getUserDao().updateDecrementGivenFavoritesByForeignKey(foreignKey);
    }
    public int incrementDirectMessages(long userId) {
        return getUserDao().updateIncrementDirectMessages(userId);
    }
    public int incrementDirectMessages(String foreignKey) {
        return getUserDao().updateIncrementDirectMessagesByForeignKey(foreignKey);
    }
    public int decrementDirectMessages(long userId) {
        return getUserDao().updateDecrementDirectMessages(userId);
    }
    public int decrementDirectMessages(String foreignKey) {
        return getUserDao().updateDecrementDirectMessagesByForeignKey(foreignKey);
    }
    public int incrementStatuses(long userId) {
        return getUserDao().updateIncrementStatuses(userId);
    }
    public int incrementStatuses(String foreignKey) {
        return getUserDao().updateIncrementStatusesByForeignKey(foreignKey);
    }
    public int decrementStatuses(long userId) {
        return getUserDao().updateDecrementStatuses(userId);
    }
    public int decrementStatuses(String foreignKey) {
        return getUserDao().updateDecrementStatusesByForeignKey(foreignKey);
    }
    
    /////
    
    S2Container container_;
    
    public S2Container getContainer() {
        return container_;
    }
    public void setContainer(S2Container container) {
        container_ = container;
    }
    IUserDao getUserDao() {
        return (IUserDao)getContainer().getComponent(IUserDao.class);
    }
    IUserCustomDao getUserCustomDao() {
        return (IUserCustomDao)getContainer().getComponent(IUserCustomDao.class);
    }
}
