﻿
function UserStatus(isFriend, isBlocked) {
    this.isFriend = isFriend;
    this.isBlocked = isBlocked;
};

function ChatWindow(sessionUserId, preferences, guestMode) {
    Networker.logCount = 0;

    $(window).error(function(error, url, line) {
        if (!window.unloading && Networker.logCount++ < 10) {
            Networker.LogError("Window error: " + Networker.formatException(error) + " at " + url + " : " + line);
        }

        return false;
    });

    $(window).unload(function() {
        window.unloading = true;
    });

    Networker.Dialog.needCrossdomain = true;

    // Interface elements
	this.room = $("#ChatRoom");
	this.channelTabs = $("#ChannelTabs");
	this.inputAreaWrap = $(".InputAreaWrap");
	this.inputLine = $("#InputLine");
	this.channelDirectory = $("#ChannelDirectory");
	this.feed = $("#Feed");
	this.channelBodyWrap = $("#ChannelBodyWrap");
	this.subscriberListWrap = $("#SubscriberListWrap");
	this.stylePicker = $("#StylePicker");
	this.emoticonPicker = $("#EmoticonPicker");
	this.channelDirectoryLink = $("#ChannelDirectoryLink");
	this.navigationIndicator = $("#NavigationIndicator");

	this.channelDirectoryFilter = "Public";
	this.sessionUserId = sessionUserId;
	this.preferences = preferences;
	this.guestMode = guestMode;
	this.currentDialog = null;
	this.currentChannel = null;
	this.previousChannelId = null;
	this.privateSessions = [];
	this.firstChannel = true;
	this.users = [];

	chatWindow = this;
	
	// Load media
	jQuery.preloadImages("/Images/Backgrounds/ChatDetails.png", "/Images/Backgrounds/ChatDetailsBottom.png", "/Images/UserDetailsArrow.png", "/Images/PopupFlagUp.png");

	try {
	    soundManager.onload = function() {
	        chatWindow.privateRequestSound = soundManager.createSound({
	            id: 'PrivateRequest',
	            url: '/Audio/PrivateRequest.mp3'
	        });
	        chatWindow.newMessageLineSound = soundManager.createSound({
	            id: 'NewMessageLine',
	            url: '/Audio/NewMessageLine.mp3'
	        });
	    }
	} catch (ex) {
	    Networker.LogError("Failed to setup sound manager " + Networker.formatException(ex));
	}
	
	// Hook up basic interface elements
	this.channelDirectoryLink.click(function(event) { event.preventDefault(); chatWindow.showDirectory(); });
	$("#SaveStyleButton").click(function(event) { event.preventDefault(); chatWindow.saveStyle(); });
	$("#OptionsLink").click(function(event) { event.preventDefault(); chatWindow.openDialog("/Chat/Options.aspx?Modal=true"); });
	this.room.find(".StyleButton").click(function(event) { event.preventDefault(); chatWindow.stylePicker.toggle(); });
	this.room.find(".EmoticonButton").click(function(event) { event.preventDefault(); chatWindow.emoticonPicker.toggle(); });

    // Input line handler
    this.inputLine.keypress(function(e) {
        if (e.keyCode === 13) {
            chatWindow.currentChannel.sendLine($(this).val());
            $(this).val("");
            return false;
        }
    });
    $("#SendButton").click(function() {
        chatWindow.currentChannel.sendLine($(chatWindow.inputLine).val());
        $(chatWindow.inputLine).val("");
        $(chatWindow.inputLine).focus();
        return false;
    });

    this.setInputLineStyle();

    $(window).unload(function() {
        Networker.ChannelClient.leaveAllChannels();
    });

    this.emoticonPicker.find("a").click(function(event) {
        event.preventDefault();
        chatWindow.inputLine.val(chatWindow.inputLine.val() + " " + $(this).attr("title")) + " ";
        chatWindow.emoticonPicker.hide();
        chatWindow.inputLine.focus();
        chatWindow.focusInputLine();
    });

    $("#FontColor > .ColorSwatch").click(function(event) {
        event.preventDefault();
        window.chatWindow.preferences.ChatColor = $(this).attr("colorId");
        $(this).parent().children(".ColorSwatch").removeClass("SelectedDark").removeClass("SelectedLight");
        if (Networker.Customization.brightness($(this).css("background-color")) > 0.5)
            $(this).addClass("SelectedDark");
        else
            $(this).addClass("SelectedLight");
        return false;
    });
    

    if (jQuery.browser.msie) {
        this.checkResize();
    } else {
        var resizeTimer = null;
        $(window).resize(function() {
            if (jQuery.browser.msie) {
                resizeTimer = setTimeout(chatWindow.handleResize, 100);
                if (resizeTimer) {
                    clearTimeout(resizeTimer);
                }
            } else {
                chatWindow.handleResize();
            }
        });
    }
    
    // Register the control channel handler
    function ChatControlHandler(sessionId) {
        this.parent = ChannelHandler;
        this.parent(sessionId);
        this.ready = true;
    }

    ChatControlHandler.prototype.processMessage = function(type, sequence, data, requestedSequence) {
        switch (type) {
            case Networker.ControlMessageType.RoomInvitation:
                try {
                    setTimeout(function() {
                        chatWindow.joinChannel(data.ChannelId, data.Nickname, true, false, false);
                    }, 1);
                } catch (ex) {
                    Networker.LogError("Failed to join private room: " + Networker.formatException(ex));
                }

                break;
            case Networker.ControlMessageType.NewFeedItem:
                try {
                    // Remove the empty feed item if it exists
                    chatWindow.feed.find(".EmptyFeedItem").remove();

                    // Add the new item
                    var feedItem = $(data);
                    Networker.Feed.bindFeedActionsToElement(feedItem, true);
                    feedItem.hide();
                    chatWindow.feed.find("#FeedBody").prepend(feedItem);
                    feedItem.slideDown("slow");

                    // Highlight the tab
                    if (chatWindow.feedTab.hasClass("Selected") == false && chatWindow.feedTab.hasClass("Highlight") == false) {
                        chatWindow.feedTab.animate({ backgroundColor: "#b8ef23" }, 200);
                        chatWindow.feedTab.addClass("Highlight");
                    }
                } catch (ex) {
                    Networker.LogError("Failed to add feed item: " + Networker.formatException(ex));
                }

                break;
            case Networker.ControlMessageType.UpdateUser:
                try {
                    chatWindow.users[data.UserId] = new UserStatus(data.Friend, data.Blocked);
                    chatWindow.propogateUserStatusChange(data.UserId, chatWindow.users[data.UserId]);
                } catch (ex) {
                    Networker.LogError("Failed to set user status: " + Networker.formatException(ex));
                }

                break;
        }
    };

    ChatControlHandler.prototype.leaveChannel = function() {
    };


    // Create the feed channel
    this.feedTab = this.createTab(Networker.ChannelClient.userSession, "Notifications", false, false);
    this.feedTab.click(function() {
        chatWindow.channelTabs.children("span").removeClass("Selected");
        chatWindow.feedTab.addClass("Selected");
        chatWindow.showFeed();
        document.title = "Notifications";
    });
    this.feed.find("#FeedBody").load("/Notifications/Feed.ashx", function() {
        chatWindow.feed.find(".Time").remove();
        chatWindow.feed.find(".ThickFeedItemSeperator").text("");
        Networker.Feed.bindFeedActions(true);

        var emptyLink = $("<br /><br /><a href='javascript: void(0);'>Back to the <strong>Chat Rooms</strong></a>");
        emptyLink.click(function() { chatWindow.showDirectory(); });
        chatWindow.feed.find(".EmptyFeedItem .ItemBodyContent").append(emptyLink);
        chatWindow.feed.find(".ThickFeedItemSeperator:first").remove();
    });

    Networker.ChannelClient.channels[Networker.ChannelClient.userSession] = new ChatControlHandler(Networker.ChannelClient.userSession);
    Networker.ChannelClient.ready = true;

    if (guestMode) {
        
    } else {
        this.showDirectory();
        this.refreshDirectory();
    }
}

//- Directory --------------------------------------------------------------------
ChatWindow.prototype.loadDirectory = function() {
    var chatWindow = this;
    $("#DirectoryPlaceholder").load("/Chat/Directory.aspx", function() {
        var directory = chatWindow.channelDirectory;
        if (directory.html().indexOf("We are sorry but you must login to continue.") != -1) {
            chatWindow.requestLogin();
            return;
        }

        directory.find(".Channel a.Join").click(function(event) {
            event.preventDefault();
            chatWindow.joinChannel($(this).attr("channelId"), $(this).attr("title"), false, true, $(this).attr("shameRoom"));
            return false;
        });
        directory.find(".CreateChannelButton").click(function(event) {
            event.preventDefault();
            chatWindow.openDialog("/Chat/NewCreateRoom.aspx?Modal=true");
        });
        directory.find("#RoomFilterShowPublic").click(function(event) {
            event.preventDefault();
            chatWindow.channelDirectoryFilter = "Public";
            chatWindow.filterDirectory();
        });
        directory.find("#RoomFilterShowUser").click(function(event) {
            event.preventDefault();
            chatWindow.channelDirectoryFilter = "User";
            chatWindow.filterDirectory();
        });
        directory.find("#RoomFilterShowFriend").click(function(event) {
            event.preventDefault();
            chatWindow.channelDirectoryFilter = "Friend";
            chatWindow.filterDirectory();
        });
        directory.find("#RoomFilterShowAll").click(function(event) {
            event.preventDefault();
            chatWindow.channelDirectoryFilter = "All";
            chatWindow.filterDirectory();
        });

        chatWindow.filterDirectory();
        chatWindow.handleResize();
    });
}

ChatWindow.prototype.filterDirectory = function() {
    var directory = this.channelDirectory;
    directory.find(".Channel").hide();

    // Set the selected 'tab'
    directory.find(".Filters a").removeClass("Selected");
    directory.find("#RoomFilterShow" + this.channelDirectoryFilter).addClass("Selected");

    // Apply the filter
    if (this.channelDirectoryFilter != "All") {
        directory.find("." + this.channelDirectoryFilter).show();
    } else {
        directory.find(".Channel").show();
    }

    // Zebra stripes
    directory.find(".Channel").removeClass("Odd");
    directory.find(".Channel:visible:odd").addClass("Odd");

    // Scroll up
    $("#ChannelList").scrollTop(0);
};

ChatWindow.prototype.showDirectory = function() {
    document.title = "Chat Rooms";
    this.room.hide();
    this.feed.hide();

    if (this.currentChannel !== null) {
        this.currentChannel.blur();
        this.currentChannel = null;
        this.previousChannel = null;
    }

    this.channelTabs.children("span").removeClass("Selected");
    this.channelDirectory.show();
    this.channelDirectoryLink.addClass("Selected");
    this.moveNavigationIndicator(this.channelDirectoryLink);

    this.loadDirectory();
    this.handleResize();
};

ChatWindow.prototype.refreshDirectory = function() {
    var chatWindow = this;
    setTimeout(function() {
        if (!chatWindow.currentChannel) {
            chatWindow.loadDirectory();
        }
        chatWindow.refreshDirectory();
        }, 1000 * 60 * 2);
};

ChatWindow.prototype.hideDirectory = function() {
    this.channelDirectory.find("#DirectoryPlaceholder").empty();
    this.channelDirectory.hide();
    this.channelDirectoryLink.removeClass("Selected")
};

//- Feed -------------------------------------------------------------------------

ChatWindow.prototype.hideFeed = function() {
    this.feed.hide();
};

ChatWindow.prototype.showFeed = function() {
    this.hideDirectory();
    this.room.hide();
    if (this.currentChannel !== null) {
        this.currentChannel.blur();
        this.currentChannel = null;
        this.previousChannel = null;        
    }

    this.feedTab.removeClass("Highlight");
    this.feedTab.css("background-color", "");
    this.feed.show();
    this.handleResize();
    this.moveNavigationIndicator(this.feedTab);
}

//- Dialogs ----------------------------------------------------------------------

ChatWindow.prototype.openDialog = function(url) {
    if (this.currentDialog !== null)
        return;
    $("#ChatWindow").append("<iframe id='Dialog' allowtransparency='true' hspace='0' vspace='0' marginheight='0' marginwidth='0' frameborder='0' src='" + url + "&Crossdomain=true'></iframe>");
    this.currentDialog = $("#Dialog");
    this.handleResize();
};

ChatWindow.prototype.closeDialog = function() {
    $("#Dialog").remove();
    this.currentDialog = null;
};

//- Channel Handling -------------------------------------------------------------
ChatWindow.prototype.switchChannels = function(channelId) {
    if (this.currentDialog) {
        this.closeDialog();
    }

    if (this.currentChannel) {
        this.previousChannelId = this.currentChannel.channelId;
        this.currentChannel.blur();
    }

    this.currentChannel = Networker.ChannelClient.channels[channelId];
    this.currentChannel.focus();
    if (!this.currentChannel) {
    } else {
        this.navigationIndicator.hide();
        this.hideDirectory();
        this.hideFeed();
        this.room.show();
    }

    this.channelTabs.children("span").removeClass("Selected");
    this.currentChannel.parentTab.addClass("Selected");

    document.title = this.currentChannel.name;

    this.handleResize();

    if (chatWindow.tabHint) {
        chatWindow.tabHint.remove();
        chatWindow.tabHint = null;
    }

    // Must be last
    this.inputLine.focus();
};

ChatWindow.prototype.leaveChannel = function(channelId, message) {

    var channel = Networker.ChannelClient.channels[channelId];
    channel.leaveChannel();

    var oldChannels = Networker.ChannelClient.channels;
    Networker.ChannelClient.channels = [];
    for (var channel in oldChannels) {
        if (channel != channelId) {
            Networker.ChannelClient.channels[channel] = oldChannels[channel];
        }
    }

    if (this.previousChannelId === channelId) {
        this.previousChannelId = null;
    }

    if (this.currentChannel !== null && channelId === this.currentChannel.channelId) {
        this.currentChannel = null;
        if (this.previousChannelId !== null) {
            this.switchChannels(this.previousChannelId);
            this.previousChannelId = null;
        } else {
            this.showDirectory();
        }
    }

    if (message) {
        alert(message);
    }
};


ChatWindow.prototype.tabId = function(channelId) {
    return "Channel" + channelId + "tab";
};

ChatWindow.prototype.createTab = function(channelId, name, privateChat, closeButton) {
    var tabName = name.replace(" ", "&nbsp;");
    var tab = $("<span id='" + this.tabId(channelId) + "'><div><a class='Select' href='#' >" + (privateChat ? "<img src='/Images/Icons/LinkProfile.gif' />&nbsp;" : "") + tabName + "</a>" + (closeButton ? "<a class='Close' href='#'>X</a>" : "") + "</div></span>");
    this.channelTabs.append(tab);
    return tab;
};

ChatWindow.prototype.joinChannel = function(channelId, name, privateChat, userInitiated, shameRoom) {
    var chatWindow = this;
    if (Networker.ChannelClient.channels[channelId] === null || Networker.ChannelClient.channels[channelId] === undefined) {
        var tab = this.createTab(channelId, name, privateChat, true);
        tab.click(function(event) { event.preventDefault(); chatWindow.switchChannels(channelId); });
        tab.find("a.Close").click(function(event) { event.preventDefault(); chatWindow.leaveChannel(channelId); });
        Networker.ChannelClient.channels[channelId] = new ChatChannel(this.sessionUserId, channelId, this.room, name, tab, this.preferences, privateChat, shameRoom, this.guestMode);
    }

    if (userInitiated) {
        this.switchChannels(channelId);
        if (!this.guestMode && this.firstChannel) {
            this.firstChannel = false;
            this.tabHint = $("<div class='TabHint'>Click to<br />switch tabs</div>").appendTo(this.room).hide().slideDown("fast", function() {
                setTimeout(function() {
                    chatWindow.tabHint.slideUp("fast");
                }, 1000 * 3);
            });
        }
    }

    if (privateChat && userInitiated == false && this.preferences.ChatPlaySounds) {
        this.playPrivateChatRequestSound();
    }

};

//- Resize Handling --------------------------------------------------------------

ChatWindow.prototype.resizeBodyElement = function(element) {
    if (element.is(":visible")) {
        var margin = 28; // ffffffuuuuuuuu
        element.height($(window).height() - this.headerHeight - margin);
    }
};

ChatWindow.prototype.resizeChildElement = function(element, parentElement) {
    if (element.size() > 0 && element.is(":visible")) {
        var outerDifference = element.outerHeight() - element.innerHeight();
        var position = element.position();
        var offsetTop = position.top - parentElement.position().top;
        element.height(Math.round(parentElement.innerHeight() - offsetTop - outerDifference));
    }
};

ChatWindow.prototype.handleResize = function() {
    if (this.currentDialog !== null) {
        this.currentDialog.height($(window).height());
    }

    this.headerHeight = $("#ChannelNavigationWrap").height();
    if (this.currentChannel != null) {
        this.currentChannel.handleResize(this.headerHeight);
    } else {
        if (this.channelDirectory.is(":visible")) {
            this.resizeBodyElement(this.channelDirectory);
            this.resizeChildElement($(".Channels"), this.channelDirectory);
        }
        if (this.feed.is(":visible")) {
            this.resizeBodyElement(this.feed);
            this.resizeChildElement($("#FeedBody"), this.feed);
        }
        this.moveNavigationIndicator(this.channelTabs.find(".Selected"));
    }
};

ChatWindow.prototype.checkResize = function() {
    var width = $(window).width();
    var height = $(window).height();
    if (this.windowWidth !== width || this.windowHeight !== height) {
        this.handleResize();
        this.windowWidth = width;
        this.windowHeight = height;
    }
    var chatWindow = this;
    setTimeout(function() { chatWindow.checkResize(); }, 1000);
};

//- UI Events ---------------------------------------------------------------------

ChatWindow.prototype.saveStyle = function() {
    var channel = this;
    this.preferences.ChatFont = $("#FontFace").attr("value");

    for (var channel in Networker.ChannelClient.channels) {
        Networker.ChannelClient.channels[channel].preferences = this.preferences;
    }

    $.get("/Channels/EventHandler.ashx", { Command: Networker.ChatCommand.ChangePreferences, FontColor: this.preferences.ChatColor, FontFace: this.preferences.ChatFont });
    this.setInputLineStyle();
    this.stylePicker.hide();
    this.focusInputLine();
};

ChatWindow.prototype.setInputLineStyle = function() {
    this.inputLine.css("font-family", Networker.Fonts[this.preferences.ChatFont]);
    this.inputLine.css("color", Networker.Colors[this.preferences.ChatColor]);
}

ChatWindow.prototype.focusInputLine = function() {
    this.inputLine.focus();
    var textbox = this.inputLine[0];
    if (textbox.setSelectionRange) {
        textbox.setSelectionRange(textbox.value.length, textbox.value.length);
    } else if (textbox.createTextRange) {
        var range = textbox.createTextRange();
        range.collapse(true);
        range.moveEnd('character', textbox.value.length);
        range.moveStart('character', textbox.value.length);
        range.select();
    }
};

/*- Private Chat -----------------------------------------------------------------*/
ChatWindow.prototype.requestPrivateChat = function(userId) {
    if (userId == this.sessionUserId) {
        return;
    }
    var chatWindow = this;
    $.ajax({
        url: "/Channels/EventHandler.ashx",
        data: { Command: Networker.ChatCommand.RequestPrivateSession, UserId: userId },
        dataType: "json",
        success: function(response) { chatWindow.handlePrivateChatResponse(response); },
        error: function() { chatWindow.privateChatError(); }
    });
};

ChatWindow.prototype.handlePrivateChatResponse = function(response) {
    
    switch (response.Type) {
        case Networker.InvitationResultType.Accepted:
            this.joinChannel(response.ChannelId, response.Nickname, true, true, false);
            break;

        case Networker.InvitationResultType.Blocked:
            alert(response.Nickname + ' does not want to talk to you right now!')
            break;

        case Networker.InvitationResultType.RequirementNotMet:
            alert(response.Nickname + ' has messaging requirements in place. Unfortunately you do not meet the criteria.')
            break;

        case Networker.InvitationResultType.Spammer:
            alert('Budda kawak nashari butsyan anuq varnak!')
            break;

        case Networker.InvitationResultType.Offline:
            alert('Cannot start private chat because ' + response.Nickname + ' is now offline')
            break;

        case Networker.InvitationResultType.OnlyFriendsCanStartPrivateSessions:
            alert(response.Nickname + ' only accepts private sessions from friends')
            break;

        case Networker.InvitationResultType.PrivateSessionNotAllowed:
            alert(response.Nickname + ' does not want to have private sessions with anyone')
            break;

        default:
            alert('Something went wrong and we were not able to initiate your private session. Please try again later!')
    }
};

ChatWindow.prototype.privateChatError = function() {
    if (this.currentChannel) {
        this.currentChannel.addLine("There was an error starting a private chat room", "Error");
    }
};

/*- "Global" controller ------------------------------------------------------------*/
ChatWindow.prototype.propogateUserStatusChange = function(userId, userStatus) {
    for (var channel in Networker.ChannelClient.channels) {
        if (Networker.ChannelClient.channels[channel].setUserBlockedStatus) {
            Networker.ChannelClient.channels[channel].setUserBlockedStatus(userId, userStatus.isBlocked);
        }
        if (Networker.ChannelClient.channels[channel].setUserFriendStatus) {
            Networker.ChannelClient.channels[channel].setUserFriendStatus(userId, userStatus.isFriend);
        }
    }
};

ChatWindow.prototype.setBlockedStatus = function(userId, blocked) {
    if (!this.users[userId]) {
        this.users[userId] = new UserStatus(false, false);
    }
    this.users[userId].isBlocked = blocked;
    this.propogateUserStatusChange(userId, this.users[userId]);
};

ChatWindow.prototype.setFriendStatus = function(userId, friend) {
    if (!this.users[userId]) {
        this.users[userId] = new UserStatus(false, false);
    }
    this.users[userId].isFriend = friend;
    this.propogateUserStatusChange(userId, this.users[userId]);
};

ChatWindow.prototype.requestLogin = function() {
    window.location = "/Chat/Room.aspx?Login=true";
};

ChatWindow.prototype.playPrivateChatRequestSound = function() {
    if (typeof (chatWindow.privateRequestSoundchat) != typeof (undefined)) {
        chatWindow.privateRequestSound.play();
    }
};

ChatWindow.prototype.playNewMessageSound = function() {
    if (typeof (chatWindow.newMessageLineSound) != typeof (undefined)) {
        chatWindow.newMessageLineSound.play();
    }
};

ChatWindow.prototype.logError = function(error) {
    $.get("/Channels/EventHandler.ashx", { Command: Networker.ChatCommand.LogError, Error: error });
};

/*- Pretty Effects ---------------------------------------------------------------*/
ChatWindow.prototype.moveNavigationIndicator = function(tabElement) {
    if (tabElement.length > 0) {
        this.navigationIndicator.show();
        this.navigationIndicator.css("left", Math.round(tabElement.position().left + (tabElement.outerWidth() / 2) - (this.navigationIndicator.width() / 2)) + "px");
        this.navigationIndicator.css("top", $("#ChannelNavigationWrap").height() + 6);
    }
};