// import Nevow.Athena
// import MochiKit
// import SWFObject

var Sleevenotes = {};

Sleevenotes.ContainingWidget = Nevow.Athena.Widget.subclass('Sleevenotes.ContainerWidget');

Sleevenotes.ContainingWidget.method(
    '__init__',
    function (self, widgetNode) {
        Nevow.Athena.Widget.upcall(self, "__init__", Nevow.Athena.athenaIDFromNode(widgetNode));
        self.callRemote("bindNotifiers").addErrback(logError);
    });


Sleevenotes.FadeInWidget = Nevow.Athena.Widget.subclass('Sleevenotes.FadeInWidget');

Sleevenotes.FadeInWidget.method(
    'display',
    function(self, id, html) {
        logDebug("Received display request for id " + id + "with " + html);
        var wrapper = getElement(id);
        fade(wrapper, {from: 1.0, to: 0.2});
        setTimeout(function() { wrapper.innerHTML = html; appear(wrapper, {from: 0.2, to: 1.0});}, 1000);
    });
    
Sleevenotes.WaitingWidget = Nevow.Athena.Widget.subclass('Sleevenotes.WaitingWidget');

Sleevenotes.WaitingWidget.method(
    'clear',
    function(self) {
        replaceChildNodes('waiting-wrapper');
    });

Sleevenotes.WaitingInfoWidget = Nevow.Athena.Widget.subclass('Sleevenotes.WaitingInfoWidget');

Sleevenotes.WaitingInfoWidget.method(
    'searchBox',
    function(self) {
        hideElement("waiting-info-default");
        showElement("waiting-info-search");
    });

Sleevenotes.DiscographyWidget = Sleevenotes.FadeInWidget.subclass('Sleevenotes.DiscographyWidget');

Sleevenotes.DiscographyWidget.method(
    'overAlbum',
    function(self, elem, evt) {
        self.oldZindex = computedStyle(self.node, 'z-index');
        self.node.style.zIndex = 99;
        var gid = elem.id.substring(6, elem.id.length + 1);
        var trackDivId = 'tracks-' + gid;
        addElementClass(trackDivId, 'onAlbum');
        m = getCursorPosition(evt);
        newPos = new Coordinates(m[0]-150, m[1]-30);
        setElementPosition(trackDivId, newPos);
        var loadingSize = new Dimensions(120, 20);
        setElementDimensions(trackDivId, loadingSize);
        getElement(trackDivId).innerHTML = 'Loading...';
        links = self.node.getElementsByTagName('a');
        for (var i = 0; i < links.length; ++i) {
            if (links[i].id != '' && links[i].id != elem.id) {
                var tGid = links[i].id.substring(6, links[i].id.length + 1);
                tDivId = 'tracks-' + tGid;
                if (hasElementClass(tDivId, 'onAlbum')) {
                    removeElementClass(tDivId, 'onAlbum');
                }
                self.hideTracks(tGid)();
            }
        }
        showElement(trackDivId);
        var getTracks = function () {
            if (hasElementClass(trackDivId, 'onAlbum')) {
                self.callRemote('getTracks', gid);
            }
        }
        setTimeout(getTracks, 200);
    });
    
Sleevenotes.DiscographyWidget.method(
    'offAlbum',
    function(self, elem, evt) {
        var gid = elem.id.substring(6, elem.id.length + 1);
        var trackDivId = 'tracks-' + gid;
        removeElementClass(trackDivId, 'onAlbum');
        setTimeout(self.hideTracks(gid), 750);
    });
    
Sleevenotes.DiscographyWidget.method(
    'renderTracks',
    function(self, results, gid) {
        var newNode = DIV({'class': 'tracklisting', 'style': 'display: none;'});
        newNode.innerHTML = results;
        var farAway = new Coordinates(-1000, -1000);
        setElementPosition(newNode, farAway);
        appendChildNodes(self.node, newNode);
        showElement(newNode);
        var newSize = getElementDimensions(newNode);
        removeElement(newNode);
        var trackDivId = 'tracks-' + gid;
        var trackDiv = getElement(trackDivId);
        var mousePosition = getElementPosition(trackDiv);
        var portSize = getViewportDimensions();
        var portPosition = getViewportPosition();
        var niceX = mousePosition.x + 120 - newSize.w - 10;
        var niceY = mousePosition.y + 40 - 30;
        if (niceX < portPosition.x) {
            var realX = portPosition.x + 10;
        } else {
            var realX = niceX;
        }
        if ((niceY + newSize.h) > (portPosition.y + portSize.h)) {
            niceY = niceY - ((niceY + newSize.h) - (portPosition.y + portSize.h) + 20);
        }
        if (niceY < portPosition.y) {
            var realY = portPosition.y + 10;
        } else {
            var realY = niceY;
        }
        var newPos = new Coordinates(realX, realY);
        setElementPosition(trackDiv, newPos);
        var padding = new SNSupport.Padding(trackDiv);
        alert("We've not broken yet");
        newWidth = newSize.w - padding.width;
        newHeight = newSize.h - padding.height;
        unPadded = new Dimensions(newWidth, newHeight)
        setElementDimensions(trackDiv, unPadded);
        trackDiv.innerHTML = results;
    });
    
Sleevenotes.DiscographyWidget.method(
    'hideTracks',
    function(self, gid) {
        var hider = function () {
            var trackDivId = 'tracks-' + gid;
            var albumLinkId = 'album-' + gid;
            if (typeof self.oldZindex != 'undefined') {
                self.node.style.zIndex = self.oldZindex;
            }
            if (!(hasElementClass(trackDivId, 'onAlbum') || hasElementClass(albumLinkId, 'onTracks'))) {
                hideElement(trackDivId);
            }
        };
        return hider;
    });
    
Sleevenotes.DiscographyWidget.method(
    'overTracks',
    function(self, elem, evt) {
        var gid = elem.id.substring(7, elem.id.length + 1);
        var albumLinkId = 'album-' + gid;
        addElementClass(albumLinkId, 'onTracks');
    });
    
Sleevenotes.DiscographyWidget.method(
    'offTracks',
    function(self, elem, evt) {
        var gid = elem.id.substring(7, elem.id.length + 1);
        var albumLinkId = 'album-' + gid;
        removeElementClass(albumLinkId, 'onTracks');
        setTimeout(self.hideTracks(gid), 750);
    });
    
    
Sleevenotes.DiscographyWidget.method(
    'display',
    function(self, id, html) {
        Divmod.debug("transport", "I am " + id + " and my z-index is " + computedStyle(self.node, 'z-index'));
        var wrapper = getElement(id);
        fade(wrapper, {from: 1.0, to: 0.2});
        var doFading = function() {
            wrapper.innerHTML = html;
            appear(wrapper, {from: 0.2, to: 1.0});
            self.makeEvents();
        };
        setTimeout(doFading, 1000);
    });
    
Sleevenotes.DiscographyWidget.method(
    'makeEvents',
    function(self) {
        if (self.node.getElementsByTagNameNS) {
            var events = self.node.getElementsByTagNameNS(Nevow.Athena.XMLNS_URI, 'handler');
            if (events.length == 0) {
                // Maybe namespaces aren't being handled properly, let's check
                events = self.node.getElementsByTagName('athena:handler');
            }
        } else {
            // We haven't even heard of namespaces, so do without
            // XXX:
            // I have altered this from the original code (which requested
            // self.node.getElementsByTagName('athena:handler').  Looking
            // at self.node in this specific instance shows that the namespaces
            // are not being carried through in IE.  I'm guessing that IE does
            // not like to build DOM nodes with namespaces on the fly, although
            // given that we are using innerHTML I'm amazed.
            // This is a direct rip from createEventBindings()
            var events = self.node.getElementsByTagName('handler');
            if (events.length == 0) {
                events = self.node.getElementsByTagName('athena:handler');
            }
        }
        
        function makeHandler(evtHandler) {
            return function (e) {
                Divmod.debug("widget", "Handling an event.");
                var success = false;
                var result = false;
                Nevow.Athena._rdm.pause();
                try {
                    result = self[evtHandler](this, e);
                } catch (e) {
                    success = false;
                    Divmod.err(e);
                }
                Nevow.Athena._rdm.unpause();
                Divmod.debug("widget", "Finished handling event.");
                return result;
            };
        };
        
        for (var i = 0; i < events.length; ++i) {
            var event = events[i];
            var evtName = event.getAttribute('event');
            var evtHandler = event.getAttribute('handler');
            event.parentNode[evtName] = makeHandler(evtHandler);
            Divmod.debug("Hooked " + evtName + " up to " + evtHandler + " on " + self);
        }
    });


Sleevenotes.UserAdminWidget = Nevow.Athena.Widget.subclass('Sleevenotes.UserAdminWidget');

Sleevenotes.UserAdminWidget.method(
    'renderUsers',
    function(self, users) {
        var checkbox = function (name, checked, onchange) {
            if(checked) {
                return INPUT({type: 'checkbox', checked: true, id: name, onchange: onchange});
            } else {
                return INPUT({type: 'checkbox', id: name, onchange: onchange});
            }
        };
        var row = function (d) {
            return TR(null, TD(null, d['username']),
                            TD(null, d['email']),
                            TD(null, d['lastfm']),
                            TD(null, d['registered']),
                            TD(null, checkbox('foo', d['banned'], 'Nevow.Athena.Widget.get(this).callRemote("banUser", "' + d['username'] + '", this.checked)')),
                            TD(null, INPUT({type: 'submit', value: 'Resend password'}))
                     );
        };
        rows = map(row, users);
        if(rows.length > 0) {
            replaceChildNodes('user-admin-output', 
                TABLE(null,
                    THEAD(null,
                        TH(null, 'Username'),
                        TH(null, 'Email Address'),
                        TH(null, 'Last FM Username'),
                        TH(null, 'Registered'),
                        TH(null, 'Banned'),
                        TH(null, '')
                    ),
                    TBODY(null, rows)
                ));
        } else {
            replaceChildNodes('user-admin-output',
                SPAN({'class': 'none-found'}, 'No users found'));
        }
    });
    
Sleevenotes.UserAdminWidget.method(
    'filter',
    function(self, elem, evt) {
        var val = getElement('user-admin-filter').value;
        if(val) {
            self.callRemote("filter", val);
        } else {
            replaceChildNodes('user-admin-output',
                SPAN({'class': 'no-search'}, 'Please enter a search string'));
        }
    });
    
Sleevenotes.LostPasswordWidget = Nevow.Athena.Widget.subclass('Sleevenotes.LostPasswordWidget');

Sleevenotes.LostPasswordWidget.method(
    'showLostPassword',
    function(self, elem, evt) {
        mousePosition = getCursorPosition(evt);
        replaceChildNodes('lostPasswordForm', [
            IMG({'id': "closeButton", 'src': "/static/images/close.gif", 'onclick': "Nevow.Athena.Widget.get(getElement('lost-password-link')).hideLostPassword()"}),
            P({'id': 'lostPasswordForm-headline'}, STRONG({}, "Forgotten password")),
            P({}, "Forgotten your username / password? Enter the email address " +
                  "you registered with in the form below and we'll send your " +
                  "login details to that address."),
            DIV({'class': 'inputs'}, INPUT({'name': 'email', 'type': 'text', 'id': 'lostPasswordForm-email'})),
            DIV({'class': 'actions'}, INPUT({'name': 'submit', 'type': 'submit', 'value': 'Send', 
                                             'onclick': 'Nevow.Athena.Widget.get(getElement("lost-password-link")).sendEmail()'})),
            DIV({'id': 'lostPasswordForm-message'})]);
        newpos = new Coordinates(mousePosition[0] - 140, mousePosition[1] - 150);
        setElementPosition('lostPasswordForm', newpos);
        showElement('lostPasswordForm');
        getElement('lostPasswordForm-email').focus();
        elem.preventDefault();
    });
    
Sleevenotes.LostPasswordWidget.method(
    'hideLostPassword',
    function() {
        hideElement('lostPasswordForm');
    });

Sleevenotes.LostPasswordWidget.method(
    'sendEmail',
    function(self, elem, evt) {
        replaceChildNodes('lostPasswordForm-message');
        var val = getElement('lostPasswordForm-email').value;
        if (val) {
            self.callRemote('sendEmail', val);
        } else {
            appendChildNodes('lostPasswordForm-message', [
                IMG({'src': '/static/images/unsmiley_button.gif'}),
                SPAN({}, 'Can\'t do anything without an email address...')]);
        };
    });
    
Sleevenotes.LostPasswordWidget.method(
    'renderMessage',
    function(self, found) {
        if (found) {
            appendChildNodes('lostPasswordForm-message', [
                IMG({'src': '/static/images/smiley_button.gif'}),
                SPAN({}, 'We\'ve sent you an email, go get it')]);
        } else {
            appendChildNodes('lostPasswordForm-message', [
                IMG({'src': '/static/images/unsmiley_button.gif'}),
                SPAN({}, 'We couldn\'t find that address, did you enter it right?')]);
            var email = getElement('lostPasswordForm-email');
            email.select();
        };
    });
    
Sleevenotes.UsernameWidget = Nevow.Athena.Widget.subclass('Sleevenotes.UsernameWidget')

Sleevenotes.UsernameWidget.method(
    'changeHandler',
    function(self, field, event) {
        var field = field.getElementsByTagName('input')[0];
        if(!self.oldvalue || field.value != self.oldvalue) {
            // self.callRemote("checkUsername", field.value);
            self.oldvalue = field.value;
        }
    });
