//文字コード判別用
(function($) {
    var window = this;


    $(function() {
        var domains = new DomainCollection();
        var usedDomainChecker = new UsedDomainChecker(domains);
        var userName = new UserName(domains, usedDomainChecker);

        domains.selected.add(function(event) {
            var opener = window.opener;
            if (!opener) return;

            var doc = opener.document;
            var userNameElement = doc.getElementById("account");
            var domainNamesElement = doc.getElementById("domain");

            if (userNameElement && domainNamesElement) {
                userNameElement.value = userName.getValue();
                for (var i = 0, len = domainNamesElement.options.length; i < len; i++ ) {
                    var option = domainNamesElement.options[i];
                    if (option.value == event.domainName) {
                        option.usedDomain = false;
                        option.style.color = 'black';
                        option.style.textDecoration = 'none';
                        option.selected = true;
                    }
                }
                if (opener.getUsedDomain) opener.getUsedDomain();
            }
            window.close();
        });
    });


    function DomainCollection() {
        this.initialize.apply(this, arguments);
    }
    DomainCollection.prototype = {
        initialize: function() {
            EventDispatchable.includeTo(this);
            EventDispatchable.setEventProperties(this, ["selected"]);
            this.setDomains();
        },
        setDomains: function() {
            var selectableDomains = $("td.selectable");
            this.domains = {};
            var self = this;
            selectableDomains.each(function() {
                var domain = new Domain(this);
                domain.selected.add(function(event) {
                    self.selected.fire({
                        domainName: event.domainName,
                        domain: event.domain
                    });
                });
                self.domains[domain.domain] = domain;
            });
        },
        getDomainNames: function() {
            var result = [];
            this.each(function(domain, domainName) {
                result.push(domainName);
            });
            return result;
        },
        get: function(domain) {
            return this.domains[domain];
        },
        has: function(domain) {
            return !!(domain in this.domains);
        },
        each: function(iterator, context) {
            var counter = 0;
            for (var domain in this.domains) {
                iterator.call(context, this.domains[domain], domain, counter);
                counter++;
            }
        },
        setUsedDomain: function (usedDomain) {
            this.each(function(domain) {
                domain.setUsedDomain(usedDomain);
            });
        },
        setInvalidUserName: function (invalid) {
            this.each(function(domain) {
                domain.setInvalidUserName(invalid);
            });
        }
    };


    function Domain() {
        this.initialize.apply(this, arguments);
    }
    Domain.prototype = {
        initialize: function(element) {
            EventDispatchable.includeTo(this);
            EventDispatchable.setEventProperties(this, ["selected"]);
            this.element = $(element);
            this.domain = this.getDomain(this.element.text());
            this.observe();
        },
        observe: function() {
            var self = this;
            this.element.click(function(event) {
                if (self.isDisable()) return;
                self.selected.fire({ domainName: self.domain });
            });
        },
        isDisable: function() {
            return (this.element.hasClass("usedDomain") || this.element.hasClass("invalidUserName"));
        },
        setUsedDomain: function (usedDomain) {
            if (usedDomain) {
                this.element.addClass("usedDomain");
            } else {
                this.element.removeClass("usedDomain");
            }
        },
        setInvalidUserName: function (invalid) {
            if (invalid) {
                this.element.addClass("invalidUserName");
                this.setUsedDomain(false);
            } else {
                this.element.removeClass("invalidUserName");
            }
        },
        getDomain: function(text) {
            text = (text || "") + "";

            // &nbsp; => String.fromCharCode(160)
            var separators = [String.fromCharCode(160), "（"];
            var domain = "";
            for (var i = 0, len = separators.length; i < len; i++ ) {
                var separator = separators[i];
                var split = text.split(separator);
                if (split.length < 2) continue;
                domain = split[0];
                break;
            }
            return domain;
        }
    };


    function UserName() {
        this.initialize.apply(this, arguments);
    }
    UserName.prototype = {
        initialize: function(domains, usedDomainChecker) {
            this.element = $("#username");
            this.setValue(this.getDefaultValue());
            this.domains = domains;
            this.usedDomainChecker = usedDomainChecker;
            this.changedUserName(this.getDefaultValue());
            this.observe();
            this.focus();
        },
        getValue: function() {
            return this.element.val() || "";
        },
        setValue: function(value) {
            this.element.val(value);
        },
        observe: function() {
            var self = this;
            var lastValue = self.getValue();
            var id = setInterval(function() {
                var value = self.getValue();
                if (lastValue != value) {
                    lastValue = value;
                    self.changedUserName(value);
                }
            }, 800);
        },
        changedUserName: function(userName) {
            if (this.isInvalidUserName(userName)) {
                this.domains.setInvalidUserName(true);
                return;
            }

            this.domains.setInvalidUserName(false);
            this.usedDomainChecker.check(userName);
        },
        isInvalidUserName: function(name) {
            return !(this.userNameRegexp.test(name));
        },
        userNameRegexp: /^[0-9a-z]{3,16}$/,
        defaultUserName: "ninja",
        getDefaultValue: function() {
            if (this.element.val()) {
                return this.element.val();
            } else {
                return this.defaultUserName;
            }
        },
        focus: function() {
            this.element.focus();
        }
    };


    function UsedDomainChecker() {
        this.initialize.apply(this, arguments);
    }
    UsedDomainChecker.prototype = {
        initialize: function(domains) {
            this.domains = domains;
            this.pageType = $("#pageType").text() || "blog";
        },
        check: function(userName) {
            var self = this;
            $.get(this.getUrl(), { username: userName }, function(data) {
                self.checked(data);
            });
        },
        checked: function(data) {
            this.domains.setUsedDomain(false);

            var usedDomainList = this.parseUsedDomain(data);
            for (var i = 0, len = usedDomainList.length; i < len; i++ ) {
                var usedDomain = usedDomainList[i];
                if (this.domains.has(usedDomain)) {
                    this.domains.get(usedDomain).setUsedDomain(true);
                }
            }
        },
        getUrl: function() {
            if (this.pageType == "blog") {
                return "/home/getuseddomain_blog.xml";
            } else {
                return "/home/getuseddomain.xml";
            }
        },
        parseUsedDomain: function(doc) {
            var result = [];
            if (doc) {
                var list = doc.getElementsByTagName('used_domain');
                for (var i = 0, len = list.length; i < len; i++ ) {
                    result.push(list[i].childNodes[0].nodeValue);
                }
            }

            //allなんてフラグがused_domainフィールドに入ってくるのはデータ構造おかしいだろ
            if (result[0] == "all") {
                result = this.domains.getDomainNames();
            }

            return result;
        }
    };

})(jQuery);

