var chat;
var role = 'user';

function playSound( soundname ) {
    if ( soundbase == null ) {
        soundbase = '';
    }
    if ( soundname == null || soundname == '' ) {
        soundname = 'arrive.wav';
    }

    var sound = '<embed src="' + soundbase + '/' + soundname +'" width="0" height="0" autostart="true" loop="false" controller="false" id="arrivesound" name="arrivesound" enablejavascript="true"/>';

    if ( navigator && navigator.mimeTypes && navigator.mimeTypes.length > 0 ) {
        if ( navigator.mimeTypes["audio/x-wav"] != null ) {
             if ( navigator.mimeTypes["audio/x-wav"].enabledPlugin != null ) { 
                 $('soundbucket').innerHTML = sound; 
                 return 0;
             }
             else {
                 var userAgent = navigator.userAgent;
                 var reOperaVersion = new RegExp("Opera (\\d+\\.\\d+)");
                 reOperaVersion.test( navigator.userAgent);
                 var operaVersion = parseFloat(RegExp["$1"]);

                 if ( userAgent.indexOf('Windows') > -1 && ( navigator.appName == 'Opera' || operaVersion >= 6) ) {
                     $('soundbucket').innerHTML = sound;
                     return 0;
                 }
             }
        }
    }
    else if (window.ActiveXObject) {
        try {
            new ActiveXObject("QuickTime.QuickTime");
            $('soundbucket').innerHTML = sound;
            return 0;
        }
        catch ( e ) {
            try {
                new ActiveXObject("WMPlayer.OCX");
                $('soundbucket').innerHTML = sound;
                return 0;
            }
            catch (e) {
            }
        }
    }
    return 1;

}

function Chat ( role ) {
    this.role = role;

    this.url  = baseurl + '/chat.cgi';
    this.opts = {
        method: 'post',
        postBody: 'role=' + role,
        onSuccess: handleResponse
    };
    this.frequency = 5 * 1000;
    this.sessions = [];
    this.lastWindowPosition = 0;
    this.maxsession_id = 0;
};

Chat.prototype.updateStaffStatus = function ( departments ) {
    var newul = document.createElement('ul');
    newul.id = 'staff_departments';

    var oldul = $('staff_departments');

    var maxsession_id = 0;
    
    for( var i = 0; i < departments.length; i++ ) {
        var department = departments[i];
        var users      = department.users;
        var depli;

        depli = document.createElement('li');

        depli.className = users.length ? 'req' : 'nousers';
        depli.id        = department.name;
        depli.innerHTML = department.name;
        
        var depul = document.createElement('ul');
        depul.id = department.name + '_list';

        depli.appendChild( depul );

        newul.appendChild( depli );
        
        for ( var j = 0; j < users.length; j++ ) {
            var user = users[j];
            
            var userli = document.createElement('li');
            
            userli.id        = user.session_id;
            userli.innerHTML = user.username;
            userli.onclick   = chat.acceptRequest;
            userli.className = 'username';

            depli.className = 'req';

            depul.appendChild( userli );

            if ( user.session_id > maxsession_id ) {
                maxsession_id = user.session_id;
            }
        }
    }
    $('staff_chat_list').replaceChild( newul, oldul );

    if ( this.maxsession_id < maxsession_id) {
        if ( playSound('arrive.wav') ) {
            alert('Chat request');
        }
    }
    this.maxsession_id = maxsession_id;
}

Chat.prototype.updateUserStatus = function ( departments ) {
    var newul = document.createElement('ul');
    newul.id = 'departments';
    newul.innerHTML = 'Select Department:';

    var oldul = $('departments');

    for( var i = 0; i < departments.length; i++ ) {
        var department = departments[i];
        
        depli = document.createElement('li');

        depli.className = department.available ? 'available' : 'notavailable';
        depli.id        = department.name;
        depli.innerHTML = department.name;

        if ( ! department.available ) {
            depli.innerHTML += ' (offline)'; 
        }

        if ( department.available ) {
            depli.onclick    = chat.requestSession;
        }
        else {
            depli.onclick    = chat.openTicket;
        }

        newul.appendChild( depli );
    }
    
    $('chat_status').replaceChild( newul, oldul );
}

Chat.prototype.updateExtStatus = function ( departments ) {
    var available = 0;
    for( var i = 0; i < departments.length; i++ ) {
        var department = departments[i];
        if ( department.available ) {
            available = 1;
        }
    }

    if ( available ) {
        $('chat_extstatus_icon').src = chatOnImg;
        $('chat_extstatus').onclick = openChat;
        $('chat_extstatus').style.cursor = 'pointer';
    }
    else {
        $('chat_extstatus_icon').src = chatOffImg;
        $('chat_extstatus').onclick = noChat;
        $('chat_extstatus').style.cursor = 'pointer';
    }
}

Chat.prototype.updateStatus = function ( departments ) {

    if ( role == 'staff' ) {
        this.updateStaffStatus( departments );
    }
    if ( role == 'user' ) {
        this.updateUserStatus( departments );
    }
    if ( role == 'ext' ) {
        this.updateExtStatus( departments );
    }
};

Chat.prototype.requestSession = function ( evt ) {
    evt = (evt) ? evt : event;
    var target = (evt.target) ? evt.target : evt.srcElement;
    
    sendRequest( 'request', 'department=' + target.id );
}

Chat.prototype.requestTimeout = function ( ) {
    if ( chat.requestTimeoutSession ) {
        if ( chat.requestTimeoutSession.request ) { 
            chat.requestTimeoutSession.close('timeout');
        }
        chat.requestTimeoutSession = null;
    }
    if ( chat.requestTimeoutId != null ) {
        chat.requestTimeoutId = null;
    }
}

Chat.prototype.acceptRequest  = function ( evt ) {
    evt = (evt) ? evt : event;
    var target = (evt.target) ? evt.target : evt.srcElement;
    
    sendRequest( 'accept', 'session_id=' + target.id );
    chat.sessions[target.id] = new Session( target.id );
}

Chat.prototype.openSessions = function ( sessions ) {
    for ( var i = 0; i < sessions.length; i++ ) {
        var session = sessions[i];
        if ( this.sessions[session.id] == null && session.closing == 0) {
            this.sessions[session.id] = new Session( session.id );
        }
        if ( this.sessions[session.id] != null ) {
            this.sessions[session.id].update( session );
        }
    }
};

Chat.prototype.openTicket = function( evt ) {
    evt = (evt) ? evt : event;
    var target = (evt.target) ? evt.target : evt.srcElement;
    
    if ( chat.role == 'user' ) {
        $('chat_status').style.display    = 'none';
        $('chat_offline').style.display   = 'block';
        $('chat_top_close').style.display = 'block';

        $('chat_top_close').onclick     = chat.returnToMain;
        $('chat_offline_close').onclick = chat.returnToMain;
    }
}

Chat.prototype.returnToMain = function () {
    $('top_chat_header').style.display = 'block';
    $('chat_status').style.display = 'block';
    $('chat_offline').style.display = 'none';
    $('chat_thank').style.display = 'none';
    $('chat_top_close').style.display = 'none';
        
    if ( chat.returnToMainTimeoutId ) {
        clearTimeout( chat.returnToMainTimeoutId );
        chat.returnToMainTimeoutId = null;
    }
}

Chat.prototype.closeSession = function ( evt ) {
    evt = (evt) ? evt : event;
    var target = (evt.target) ? evt.target : evt.srcElement;

    var elementId = target.id;

    var session_id = elementId.substr(elementId.search(/[0-9]+/));

    chat.sessions[session_id].close( 'user' );
    // chat.sessions[session_id] = null;
}

Chat.prototype.toggleWindow = function ( evt ) {
    evt = (evt) ? evt : event;
    var target = (evt.target) ? evt.target : evt.srcElement;

    var elementId = target.id;

    var session_id = elementId.substr(elementId.search(/[0-9]+/));
    
    chat.sessions[session_id].toggle();
}

Chat.prototype.hideOtherWindows = function ( current ) {
    var sessions = this.sessions;
    for( var i = 0; i < sessions.length; i++ ) {
        var session = sessions[i];
        if ( session && session != current ) {
            session.hide();
        }
    }
}

Chat.prototype.sendMessage = function ( evt ) { 
    evt = (evt) ? evt : event;
    var target = (evt.target) ? evt.target : evt.srcElement;

    var charCode = (evt.charCode) ? evt.charCode :
            ((evt.which) ? evt.which : evt.keyCode);
    
    if (charCode == 13 || charCode == 3) {
        var elementId = target.id;

        var session_id = elementId.substr(elementId.search(/[0-9]+/));
        var message    = target.value;
            message = encodeURIComponent(String(message).escapeHTML());

        sendRequest( 'sendmsg', 'session_id=' + session_id + '&message=' + message );

        target.value = '';
    }
}

Chat.prototype.getLastSeens = function () {
    var lastSeens = '';
    for ( var i = 0; i < this.sessions.length; i++ ) {
        var session = this.sessions[i];
        if ( session ) {
            lastSeens += '&lastseen' + session.id + '=' + session.lastSeen;
        }
    }
    return lastSeens;
}

Chat.prototype.setTimer = function () {
    if ( this.timer == null ) {
        this.timer = setTimeout( 'sendRequest()', this.frequency );
    }
}

Chat.prototype.open_usersrequests = function ( evt ) {
    evt = (evt) ? evt : event;
    var target = (evt.target) ? evt.target : evt.srcElement;

    var elementId = target.id;

    var session_id = elementId.substr(elementId.search(/[0-9]+/));
    
    var url = 'staff.cgi?do=listbyuser&user=' + chat.sessions[session_id].username;
    var newWind = window.open( url , "subWindow", 
                  "status,menubar");
}

Chat.prototype.saveHistory = function ( evt ) {
    evt = (evt) ? evt : event;
    var target = (evt.target) ? evt.target : evt.srcElement;

    var elementId = target.id;

    var session_id = elementId.substr(elementId.search(/[0-9]+/));

    var url = 'staff.cgi?do=log';

    chat.sessions[session_id].historyWindow = window.open( url , "subWindow", "status,menubar,scrollbars");

    setTimeout(chat.writeHistory, 100);
}

Chat.prototype.writeHistory = function () {

    for ( var i = 0 ; i < chat.sessions.length; i++ ) {
        var session = chat.sessions[i];
        if ( session != null ) {
            if ( session.historyWindow && session.historyWindow.focus ) {
                var newWindow = session.historyWindow;
                var username = newWindow.document.getElementById('username');

                if ( username == null ) {
                    setTimeout(chat.writeHistory, 100);
                    continue;
                }
                username.value = session.username;
                
                var department = newWindow.document.getElementById('department');
                department.value = session.department;
                
                var subject = newWindow.document.getElementById('subject');
                subject.value = 'Chat log';

                var body = newWindow.document.getElementById('description');
                body.value = 'chat history:\n' + session.history; 

                session.historyWindow = null;
            }
            else {
                setTimeout(chat.writeHistory, 100);
            }
        }
    }
}

function Session ( session_id ) {
    this.id        = session_id;
    this.messages  = new Array;
    this.lastSeen  = 0;
    this.history   = '';

    this.request   = false;

    // open window

    var newChatWindow = $('chat_window').cloneNode( true );
    newChatWindow.id = 'session' + this.id;

    for( var i = 0; i < newChatWindow.childNodes.length; i++) {
        var child = newChatWindow.childNodes[i];
        if ( child.id ) {
            if ( child.id == 'chat_input' ) {
                child.id = 'chat_input' + this.id;
            }
            if ( child.id == 'chat_history' ) {
                child.id = 'chat_history' + this.id;
            }
            if (child.id == 'chat_header' ) {
                child.id = 'chat_header' + this.id;
                for( var j = 0; j < child.childNodes.length; j++ ) {
                    var element = child.childNodes[j];
                    if ( element.id ) {
                        if ( element.id == 'chat_close') {
                            element.id = 'chat_close' + this.id;
                            element.onclick = chat.closeSession;
                        }
                        if ( element.id == 'chat_save') {
                            element.id = 'chat_save' + this.id;
                            element.onclick = chat.saveHistory;
                        }
                        if ( element.id == 'chat_toggle') {
                            element.id = 'chat_toggle' + this.id;
                            element.onclick = chat.toggleWindow;
                        }
                        if ( element.id == 'chat_username') {
                            element.id = 'chat_username' + this.id;
                            element.onclick = chat.open_usersrequests;
                        }
                    }
                }
            }
        }
    }

    var textarea = newChatWindow.getElementsByTagName('textarea')[0];

    if ( textarea ) {
        textarea.id = 'messaage' + this.id;
        textarea.onkeyup = chat.sendMessage;
    }

    newChatWindow.style.display = 'block';

    if ( chat.role == 'staff' ) {
        chat.hideOtherWindows( this );
    }

    $('window_stack').appendChild( newChatWindow);

    
    this.window = newChatWindow;
    this.windowState = 'Shown';

    if ( chat.role == 'user' ) {
        $('chat_status').style.display = 'none';
        $('top_chat_header').style.display = 'none';
        $('chat_offline').style.display = 'none';
        $('chat_thank').style.display = 'none';

        $('chat_history' + this.id).style.display = 'block';
        $('chat_input'   + this.id).style.display = 'block';

        if ( chat.returnToMainTimeoutId ) {
            clearTimeout(chat.returnToMainTimeoutId);
            chat.returnToMainTimeoutId = null;
        }
        if ( chat.requestTimeoutId ) {
            clearTimeout(chat.requestTimeoutId);
            chat.requestTimeoutId = null;
        }
    }
}

Session.prototype.close = function ( reason ) {
    if ( reason == null ) {
        reason = 'request';
    }

    sendRequest( this.request ? 'cancel' : 'close', 'session_id=' + this.id  + '&reason=' + reason );

    this.window.style.display = 'none';
    this.window.parentNode.removeChild( this.window );
    
    if ( chat.requestTimeoutId != null )  {
        clearTimeout( chat.requestTimeoutId );
        chat.requestTimeoutId = null;
        chat.requestTimeoutSession = null;
    }
    
    if ( chat.role == 'user' ) {
        $('top_chat_header').style.display = 'block';
        if ( reason == 'timeout' && this.request ) {
            $('chat_offline').style.display = 'block';
        }
        else {
            $('chat_thank').style.display = 'block';
        }
        $('chat_top_close').style.display = 'block';
        $('chat_top_close').onclick = chat.returnToMain;

        chat.returnToMainTimeoutId = setTimeout( chat.returnToMain, 15000 );
    }
    chat.sessions[this.id] = null;
}


Session.prototype.hide = function () {
    if ( this.windowState != 'Hidden' ) {
        $('chat_history' + this.id).style.display = 'none';
        $('chat_input'   + this.id).style.display = 'none';

        $('chat_toggle'  + this.id).innerHTML = 'Show';

        this.windowState = 'Hidden';
    }
}

Session.prototype.toggle = function ( ) {
    if ( this.windowState == 'Shown' ) {
        this.hide();
    } else {
        if ( this.windowState == 'Hidden' ) {
            $('chat_history' + this.id ).style.display = 'block';
            $('chat_input' + this.id).style.display = 'block';
            $('chat_toggle' + this.id).innerHTML = 'Hide';
            this.windowState = 'Shown';
        }
    }
}

Session.prototype.update = function ( session ) {
    var messages = session.messages;
    var newMessages = false;

    for( var i = 0; i < messages.length; i++ ) {
        var msg = messages[i];

        this.messages.push( msg );
        if ( this.lastSeen < msg.id ) {
            newMessages = true;
            this.lastSeen = msg.id;
        }

    }

    var newhistory = document.createElement('div'); 
    var oldhistory = $('chat_history'+this.id);

    for  ( i = 0 ; i < this.messages.length; i++ ) {
        msg = this.messages[i];
        var newmsg = $('newmsg').cloneNode( true );

        for ( var j = 0; j < newmsg.childNodes.length ; j++ ) { 
            var child = newmsg.childNodes[j]; 
            if ( child.id ) { 
                if ( child.id == 'msgtime' ) { 
                    child.innerHTML =  msg.time;
                    this.history += '(' + msg.time + ') ';
                }
                if ( child.id == 'msgfrom' ) { 
                    child.innerHTML = msg.from;
                    this.history += msg.from + ': ';
                } 
                if ( child.id == 'msgtext' ) { 
                    // child.innerHTML = String(msg.text).escapeHTML(); 
                    child.innerHTML = msg.text; 
                    this.history += msg.text;
                } 
                child.id = null; 
                child.removeAttribute('id');
            }
        }
        newmsg.id = 'message' + msg.id;
        newmsg.style.display = 'block';

        newhistory.appendChild( newmsg );

    }
    $('session'+this.id).replaceChild( newhistory, oldhistory );

    newhistory.id = 'chat_history' + this.id;
    newhistory.className = 'chat_history';

    if ( chat.role == 'staff' ) {
        $('chat_username' + this.id).innerHTML = session.username + ' (' + session.department + ')';
        this.username = session.username;
        this.department = session.department;
    }

    if ( chat.role == 'user' ) {
        $('chat_username' + this.id).innerHTML = session.department;
        this.request = session.requesting;

        if ( session.requesting ) {
            $('chat_username' + this.id).innerHTML += ' (Waiting)';
            if ( chat.requestTimeoutId == null ) {
                chat.requestTimeoutSession = this;
                chat.requestTimeoutId = setTimeout( chat.requestTimeout, 60000);
            }
        }
        else {
            if ( chat.requestTimeoutId != null )  {
                clearTimeout( chat.requestTimeoutId );
                chat.requestTimeoutId = null;
                chat.requestTimeoutSession = null;
            }
        }
        if ( session.closing ) {
            $('chat_username' + this.id).innerHTML += ' (Closed)';
        }
    }

    if ( this.windowState == 'Shown' ) {
        $('message' + this.lastSeen).scrollIntoView( true );
    }

    if ( session.closing ) {
        $('chat_input'+this.id).style.display = 'none';
        $('chat_history'+this.id).style.height = '27ex';
    }
    if ( newMessages && chat.role == 'staff') {
        playSound('newmessage.wav');
            // alert('new message in chat.');
    }
}

function sendRequest( action, param ) {
    if ( chat.timer ) {
        clearTimeout( chat.timer );
        chat.timer = null;
    }
    var opts = chat.opts;

    opts.postBody = 'role=' + role;

    opts.postBody += chat.getLastSeens();

    if ( action ) {
        opts.postBody += '&action=' + action;
        if ( param ) {
            opts.postBody += '&' + param;
        }
    }
    chat.transport = new Ajax.Request( chat.url, opts );
}

function handleResponse ( transport ) {
    var json = transport.responseText;
    var response;

    try {
      eval( 'response = ' + json );
    } catch (e) {};
    

    if ( response.departments ) {
        chat.updateStatus( response.departments );
    }
    if ( response.sessions ) {
        chat.openSessions( response.sessions );
    }
    chat.setTimer();
}

function chat_init () {
    if ( $('usertype') == null ) {
        return;
    }
    role = $F('usertype');

    chat = new Chat( role );

    sendRequest();
}

function noChat() {
    var myWindow = window.open( baseurl + '/pdesk.cgi?do=submit_ticket', "subWind", "" );
    return false;
}

function openChat( ) {
    var myWindow = window.open( baseurl + '/pdesk.cgi?do=chat_standalone', "subWind", "width=600,height=450");
    return false;
}
