package jp.sourceforge.shovel.entity.impl;

import static jp.sourceforge.shovel.RepliesType.*;

import java.awt.Color;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.TimeZone;

import org.seasar.dao.annotation.tiger.Bean;
import org.seasar.dao.annotation.tiger.Id;
import org.seasar.dao.annotation.tiger.IdType;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.annotation.tiger.Binding;
import org.seasar.framework.container.annotation.tiger.BindingType;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;

import jp.sourceforge.shovel.RepliesType;
import jp.sourceforge.shovel.entity.IDevice;
import jp.sourceforge.shovel.entity.IServerFile;
import jp.sourceforge.shovel.entity.IStatus;
import jp.sourceforge.shovel.entity.IUser;
import jp.sourceforge.shovel.exception.ApplicationException;

@Bean(table = "users")
public class UserImpl implements IUser {
    boolean administrator_;
    long createdTime_;
    long creatorId_;
    boolean defaultDesign_;
    String description_;
    int directMessages_;
    String displayName_;
    String email_;
    int favorites_;
    int followers_;
    int friends_;
    String foreignKey_;
    String location_;
    long modifiedTime_;
    long modifierId_;
    String password_;
    boolean protect_;
    boolean removed_;
    int requests_;
    int statuses_;
    long userId_;
    int viewLines_;
    TimeZone timeZone_;
    boolean remove_;
    RepliesType repliesType_;
    int givenFavorites_;
    boolean tile_;
    String backgroundColor_;
    String color_;
    String nameColor_;
    String linkColor_;
    String sidebarBackgroundColor_;
    String sidebarFrameColor_;
    boolean newFriends_;
    boolean reply_;
    boolean recipientDirectMessage_;
    boolean growl_;
    String growlHost_;
    String growlPassword_;
    
    public UserImpl() {
        profileImage_ = (IServerFile)getContainer().getComponent(IServerFile.class);
        backgroundImage_ = (IServerFile)getContainer().getComponent(IServerFile.class);
        device_ = (IDevice)getContainer().getComponent(IDevice.class);
        status_ = (IStatus)getContainer().getComponent(IStatus.class);
    }
    public boolean isAdministrator() {
        return administrator_;
    }
    public void setAdministrator(boolean administrator) {
        administrator_ = administrator;
    }
    public long getCreatedTime() {
        return createdTime_;
    }
    public void setCreatedTime(long createdTime) {
        createdTime_ = createdTime;
    }
    public long getCreatorId() {
        return creatorId_;
    }
    public void setCreatorId(long creatorId) {
        creatorId_ = creatorId;
    }
    public boolean isDefaultDesign() {
        return defaultDesign_;
    }
    public void setDefaultDesign(boolean defaultDesign) {
        defaultDesign_ = defaultDesign;
    }
    public String getDescription() {
        return description_;
    }
    public void setDescription(String description) {
        description_ = description;
    }
    public int getDirectMessages() {
        return directMessages_;
    }
    public void setDirectMessages(int directMessages) {
        directMessages_ = directMessages;
    }
    public String getDisplayName() {
        return displayName_ == null ? "" : displayName_;
    }
    public void setDisplayName(String displayName) {
        displayName_= displayName;
    }
    public String getEmail() {
        return email_ == null ? "" : email_;
    }
    public void setEmail(String email) {
        email_ = email;
    }
    public int getFavorites() {
        return favorites_;
    }
    public void setFavorites(int favorites) {
        favorites_ = favorites;
    }
    public int getFollowers() {
        return followers_;
    }
    public void setFollowers(int followers) {
        followers_ = followers;
    }
    public int getFollowing() {
        return friends_;
    }
    public void setFollowing(int following) {
        friends_ = following;
    }
    public int getFriends() {
        return friends_;
    }
    public void setFriends(int friends) {
        friends_ = friends;
    }
    public String getForeignKey() {
        return foreignKey_ == null ? "" : foreignKey_;
    }
    public void setForeignKey(String foreignKey) {
        foreignKey_ = foreignKey;
    }
    public String getLocation() {
        return location_;
    }
    public void setLocation(String location) {
        location_ = location;
    }
    public long getModifiedTime() {
        return modifiedTime_;
    }
    public void setModifiedTime(long modifiedTime) {
        modifiedTime_ = modifiedTime;
    }
    public long getModifierId() {
        return modifierId_;
    }
    public void setModifierId(long modifierId) {
        modifierId_ = modifierId;
    }
    public String getPassword() {
        return password_;
    }
    public void setPassword(String password) {
        password_ = password;
    }
    public boolean isProtect() {
        return protect_;
    }
    public void setProtect(boolean protect) {
        protect_ = protect;
    }
    public int getRequests() {
        return requests_;
    }
    public void setRequests(int requests) {
        requests_ = requests;
    }
    public long getProfileImageId() {
        return profileImage_.getServerFileId();
    }
    public void setProfileImageId(long profileImageId) {
        profileImage_.setServerFileId(profileImageId);
    }
    public long getBackgroundImageId() {
        return backgroundImage_.getServerFileId();
    }
    public void setBackgroundImageId(long backgroundImageId) {
        backgroundImage_.setServerFileId(backgroundImageId);
    }
    public int getStatuses() {
        return statuses_;
    }
    public void setStatuses(int statuses) {
        statuses_ = statuses;
    }
    public String getTimeZoneId() {
        return getTimeZone().getID();
    }
    public void setTimeZoneId(String tzId) {
        TimeZone tz;
        if (tzId == null || tzId.length() <= 0) {
            tz = TimeZone.getDefault();
        } else {
            tz = TimeZone.getTimeZone(tzId);
        }
        setTimeZone(tz);
    }
    public long getUserId() {
        return userId_;
    }
    @Id(value = IdType.IDENTITY)
    public void setUserId(long userId) {
        userId_ = userId;
    }
    public int getViewLines() {
        return viewLines_;
    }
    public void setViewLines(int viewLines) {
        viewLines_ = viewLines;
    }
    public boolean isRemove() {
        return remove_;
    }
    public void setRemove(boolean remove) {
        remove_ = remove;
    }
    public int getReplies() {
        return getRepliesType().getId();
    }
    public void setReplies(int replies) {
        setRepliesType(RepliesType.find(replies));
    }
    public RepliesType getRepliesType() {
        return repliesType_ == null ? ALWAYS : repliesType_;
    }
    public void setRepliesType(RepliesType repliesType) {
        repliesType_ = repliesType;
    }
    public int getGivenFavorites() {
        return givenFavorites_;
    }
    public void setGivenFavorites(int givenFavorites) {
        givenFavorites_ = givenFavorites;
    }
    public boolean isTile() {
        return tile_;
    }
    public void setTile(boolean tile) {
        tile_ = tile;
    }
    public String getBackgroundColorHex() {
        return backgroundColor_ == null ? "000000" : backgroundColor_.toUpperCase();
    }
    public void setBackgroundColorHex(String backgroundColor) {
        backgroundColor_ = backgroundColor;
    }
    public Color getBackgroundColor() {
        return Color.decode("0x" + getBackgroundColorHex());
    }
    public String getColorHex() {
        return color_ == null ? "000000" : color_.toUpperCase();
    }
    public void setColorHex(String color) {
        color_ = color;
    }
    public Color getColor() {
        return Color.decode("0x" + getColorHex());
    }
    public String getNameColorHex() {
        return nameColor_ == null ? "000000" : nameColor_.toUpperCase();
    }
    public void setNameColorHex(String nameColor) {
        nameColor_ = nameColor;
    }
    public Color getNameColor() {
        return Color.decode("0x" + getNameColorHex());
    }
    public String getLinkColorHex() {
        return linkColor_ == null ? "000000" : linkColor_.toUpperCase();
    }
    public void setLinkColorHex(String linkColor) {
        linkColor_ = linkColor;
    }
    public Color getLinkColor() {
        return Color.decode("0x" + getLinkColorHex());
    }
    public String getSidebarBackgroundColorHex() {
        return sidebarBackgroundColor_ == null ? "000000" : sidebarBackgroundColor_.toUpperCase();
    }
    public void setSidebarBackgroundColorHex(String sidebarBackgroundColor) {
        sidebarBackgroundColor_ = sidebarBackgroundColor;
    }
    public Color getSidebarBackgroundColor() {
        return Color.decode("0x" + getSidebarBackgroundColorHex());
    }
    public String getSidebarFrameColorHex() {
        return sidebarFrameColor_ == null ? "000000" : sidebarFrameColor_.toUpperCase();
    }
    public void setSidebarFrameColorHex(String sidebarFrameColor) {
        sidebarFrameColor_ = sidebarFrameColor;
    }
    public Color getSidebarFrameColor() {
        return Color.decode("0x" + getSidebarFrameColorHex());
    }
    public boolean isNewFriends() {
        return newFriends_;
    }
    public void setNewFriends(boolean newFriends) {
        newFriends_ = newFriends;
    }
    public boolean isReply() {
        return reply_;
    }
    public void setReply(boolean reply) {
        reply_ = reply;
    }
    public boolean isRecipientDirectMessage() {
        return recipientDirectMessage_;
    }
    public void setRecipientDirectMessage(boolean recipientDirectMessage) {
        recipientDirectMessage_ = recipientDirectMessage;
    }
    public boolean isGrowl() {
        return growl_;
    }
    public void setGrowl(boolean growl) {
        growl_ = growl;
    }
    public String getGrowlHost() {
        return growlHost_;
    }
    public void setGrowlHost(String growlHost) {
        growlHost_ = growlHost;
    }
    public String getGrowlPassword() {
        return growlPassword_;
    }
    public void setGrowlPassword(String growlPassword) {
        growlPassword_ = growlPassword;
    }
    
    /////

    public String getProfileImageCharset() {
        return profileImage_.getCharset();
    }
    public void setProfileImageCharset(String charset) {
        profileImage_.setCharset(charset);
    }
    public String getProfileImageMime() {
        return profileImage_.getMime();
    }
    public void setProfileImageMime(String mime) {
        profileImage_.setMime(mime);
    }
    public String getProfileImageName() {
        return profileImage_.getName();
    }
    public void setProfileImageName(String name) {
        profileImage_.setName(name);
    }
    public int getProfileImageSize() {
        return profileImage_.getSize();
    }
    public void setProfileImageSize(int size) {
        profileImage_.setSize(size);
    }
    public int getProfileImageWidth() {
        return profileImage_.getWidth();
    }
    public void setProfileImageWidth(int width) {
        profileImage_.setWidth(width);
    }
    public int getProfileImageHeight() {
        return profileImage_.getHeight();
    }
    public void setProfileImageHeight(int height) {
        profileImage_.setHeight(height);
    }
    public long getProfileImageCreatedTime() {
        return profileImage_.getCreatedTime();
    }
    public void setProfileImageCreatedTime(long createdTime) {
        profileImage_.setCreatedTime(createdTime);
    }
    /////

    public String getBackgroundImageCharset() {
        return backgroundImage_.getCharset();
    }
    public void setBackgroundImageCharset(String charset) {
        backgroundImage_.setCharset(charset);
    }
    public String getBackgroundImageMime() {
        return backgroundImage_.getMime();
    }
    public void setBackgroundImageMime(String mime) {
        backgroundImage_.setMime(mime);
    }
    public String getBackgroundImageName() {
        return backgroundImage_.getName();
    }
    public void setBackgroundImageName(String name) {
        backgroundImage_.setName(name);
    }
    public int getBackgroundImageSize() {
        return backgroundImage_.getSize();
    }
    public void setBackgroundImageSize(int size) {
        backgroundImage_.setSize(size);
    }
    public int getBackgroundImageWidth() {
        return backgroundImage_.getWidth();
    }
    public void setBackgroundImageWidth(int width) {
        backgroundImage_.setWidth(width);
    }
    public int getBackgroundImageHeight() {
        return backgroundImage_.getHeight();
    }
    public void setBackgroundImageHeight(int height) {
        backgroundImage_.setHeight(height);
    }
    public long getBackgroundImageCreatedTime() {
        return backgroundImage_.getCreatedTime();
    }
    public void setBackgroundImageCreatedTime(long createdTime) {
        backgroundImage_.setCreatedTime(createdTime);
    }
    
    /////
    
    public String getAddress() {
        return device_.getAddress();
    }
    public void setAddress(String address) {
        device_.setAddress(address);
    }
    public int getAvailability() {
        return device_.getAvailability();
    }
    public void setAvailability(int availability) {
        device_.setAvailability(availability);
    }
    public long getDeviceId() {
        return device_.getDeviceId();
    }
    public void setDeviceId(long deviceId) {
        device_.setDeviceId(deviceId);
    }
    public String getType() {
        return device_.getType();
    }
    public void setType(String type) {
        device_.setType(type);
    }
    
    /////
    
    public IStatus getRecentlyStatus() {
        return status_;
    }
    public void setRecentlyStatus(IStatus status) {
        if (status != null) {
            status_ = status;
        }
    }
    public String getBody() {
        return status_.getBody();
    }
    public void setBody(String body) {
        status_.setBody(body);
    }
    public String getSource() {
        return status_.getSource();
    }
    public void setSource(String source) {
        status_.setSource(source);
    }
    public long getReferenceId() {
        return status_.getReferenceId();
    }
    public void setReferenceId(long referenceId) {
        status_.setReferenceId(referenceId);
    }
    public long getReferenceSenderId() {
        return status_.getReferenceSenderId();
    }
    public void setReferenceSenderId(long referenceSenderId) {
        status_.setReferenceSenderId(referenceSenderId);
    }
    public long getSenderId() {
        return status_.getSenderId();
    }
    public void setSenderId(long senderId) {
        status_.setSenderId(senderId);
    }
    public long getSentTime() {
        return status_.getSentTime();
    }
    public void setSentTime(long sentTime) {
        status_.setSentTime(sentTime);
    }
    public long getStatusId() {
        return status_.getStatusId();
    }
    public void setStatusId(long statusId) {
        status_.setStatusId(statusId);
    }
    public long getRemovedTime() {
        return status_.getRemovedTime();
    }
    public void setRemovedTime(long removedTime) {
        status_.setRemovedTime(removedTime);
    }
    
    /////
    
    public TimeZone getTimeZone() {
        return timeZone_ == null ? TimeZone.getDefault() : timeZone_;
    }
    public void setTimeZone(TimeZone timeZone) {
        timeZone_ = timeZone;
    }
    
    IServerFile profileImage_;
    IServerFile backgroundImage_;
    IDevice device_;
    IStatus status_;
    
    public IServerFile getProfileImage() {
        return profileImage_;
    }
    @Binding(bindingType=BindingType.NONE)
    public void setProfileImage(IServerFile profileImage) {
        profileImage_ = profileImage;
    }
    public IServerFile getBackgroundImage() {
        return backgroundImage_;
    }
    @Binding(bindingType=BindingType.NONE)
    public void setBackgroundImage(IServerFile backgroundImage) {
        backgroundImage_ = backgroundImage;
    }
    public IDevice getDevice() {
        return device_;
    }
    @Binding(bindingType=BindingType.NONE)
    public void setDevice(IDevice device) {
        device_ = device;
    }

    public String getReleaseKey() throws ApplicationException {
        //初回は解除キーを期待
        String address = getAddress();
        if (address == null || address.length() <= 0) {
            return null;
        }
        StringBuilder releaseKey = new StringBuilder(address);
        releaseKey.append(getPassword());
        
        byte[] hash;
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.reset();
            md5.update(releaseKey.toString().getBytes());
            hash = md5.digest();
        } catch (NoSuchAlgorithmException e) {
            //TODO
            throw new ApplicationException("");
        }
        
        releaseKey = new StringBuilder();
        for (int i = 0; i < hash.length; i++) {
            int digest = hash[i];
            if (digest < 0) {
                digest += 256;
            }
            if (digest < 16) {
                releaseKey.append("0");
            }
            releaseKey.append(Integer.toString(digest, 16));
        }
        
        int offset = Integer.parseInt(String.valueOf(getCreatedTime() & 3));
        offset *= 8;
        return releaseKey.toString().substring(offset, offset + 8);
    }
    
    /////
    
    S2Container getContainer() {
        return SingletonS2ContainerFactory.getContainer();
    }
}
