if (typeof(ZTM) === "undefined") {ZTM={}};

/*
 * jQuery Color Animations
 * Copyright 2007 John Resig
 * Released under the MIT and GPL licenses.
 */
(function(jQuery){

  // We override the animation for all of these color styles
  jQuery.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){
    jQuery.fx.step[attr] = function(fx){
      if ( fx.state == 0 ) {
        fx.start = getColor( fx.elem, attr );
        fx.end = getRGB( fx.end );
      }

      fx.elem.style[attr] = "rgb(" + [
        Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0),
        Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0),
        Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)
      ].join(",") + ")";
    }
  });

  // Color Conversion functions from highlightFade
  // By Blair Mitchelmore
  // http://jquery.offput.ca/highlightFade/

  // Parse strings looking for color tuples [255,255,255]
  function getRGB(color) {
    var result;

    // Check if we're already dealing with an array of colors
    if ( color && color.constructor == Array && color.length == 3 )
      return color;

    // Look for rgb(num,num,num)
    if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
      return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];

    // Look for rgb(num%,num%,num%)
    if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
      return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];

    // Look for #a0b1c2
    if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
      return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];

    // Look for #fff
    if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
      return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];

    // Otherwise, we're most likely dealing with a named color
    return colors[jQuery.trim(color).toLowerCase()];
  }
  
  function getColor(elem, attr) {
    var color;

    do {
      color = jQuery.curCSS(elem, attr);

      // Keep going until we find an element that has color, or we hit the body
      if ( color != '' && color != 'transparent' || jQuery.nodeName(elem, "body") )
        break; 

      attr = "backgroundColor";
    } while ( elem = elem.parentNode );

    return getRGB(color);
  };
  
  // Some named colors to work with
  // From Interface by Stefan Petre
  // http://interface.eyecon.ro/

  var colors = {
    aqua:[0,255,255],
    azure:[240,255,255],
    beige:[245,245,220],
    black:[0,0,0],
    blue:[0,0,255],
    brown:[165,42,42],
    cyan:[0,255,255],
    darkblue:[0,0,139],
    darkcyan:[0,139,139],
    darkgrey:[169,169,169],
    darkgreen:[0,100,0],
    darkkhaki:[189,183,107],
    darkmagenta:[139,0,139],
    darkolivegreen:[85,107,47],
    darkorange:[255,140,0],
    darkorchid:[153,50,204],
    darkred:[139,0,0],
    darksalmon:[233,150,122],
    darkviolet:[148,0,211],
    fuchsia:[255,0,255],
    gold:[255,215,0],
    green:[0,128,0],
    indigo:[75,0,130],
    khaki:[240,230,140],
    lightblue:[173,216,230],
    lightcyan:[224,255,255],
    lightgreen:[144,238,144],
    lightgrey:[211,211,211],
    lightpink:[255,182,193],
    lightyellow:[255,255,224],
    lime:[0,255,0],
    magenta:[255,0,255],
    maroon:[128,0,0],
    navy:[0,0,128],
    olive:[128,128,0],
    orange:[255,165,0],
    pink:[255,192,203],
    purple:[128,0,128],
    violet:[128,0,128],
    red:[255,0,0],
    silver:[192,192,192],
    white:[255,255,255],
    yellow:[255,255,0]
  };
  
})(jQuery);

(function ($) {
    $.fn.ztmAcceptDecline = function (options) {
        var opts = $.extend({}, $.fn.ztmAcceptDecline.defaults, options);
        return this.each(function () {
            var $this = $(this);
            function click (event, handler) {
                var $wrapper = $(this).parent();
                $wrapper.data('cache', $wrapper.html()).empty();
                $wrapper.html(opts.areyousure).append($('<a href="" class="yes">'+opts.yes+'</a>'))
                        .append(opts.separator)
                        .append($('<a href="" class="no">'+opts.no+'</a>'));
                $wrapper.find('a.yes').click(handler);
                $wrapper.find('a.no').click(revert);
                return false;
            };
            //$this.click(click);
            function clickaccept (event) {
                return click.call(this, event, accept)
            };
            function clickdecline (event) {
                return click.call(this, event, decline)
            };
            function revert (event) {
                var $wrapper= $(this).parent();
                $wrapper.html($wrapper.data('cache'));
                $wrapper.find(opts.acceptselector).click(clickaccept);
                $wrapper.find(opts.declineselector).click(clickdecline);
                return false;
            };
            function accept (event) {
                $(this).parents('li').fadeOut().remove();
                return opts.accept.call(this, event);
            };
            function decline (event) {
                $(this).parents('li').fadeOut().remove();
                return opts.decline.call(this, event);
            };
            $this.find(opts.acceptselector).click(clickaccept);
            $this.find(opts.declineselector).click(clickdecline);
        })
    };
    $.fn.ztmAcceptDecline.defaults = {
        'accept': function () {return false;},
        'decline': function () {return false;},
        'wrapperselector': '.wrapper',
        'acceptselector': '.accept',
        'declineselector': '.decline',
        'areyousure': 'Are you sure? ',
        'yes': 'Yes',
        'no': 'No',
        'separator': '/'
    };
})(jQuery);

(function ($) {
    $.fn.ztmInlineConfirm = function (options) {
        var opts = $.extend({}, $.fn.ztmInlineConfirm.defaults, options);
        return this.each(function () {
            var $this = $(this);
            function click (event) {
                var $wrapper = $(this).parent();
                $wrapper.data('cache', $wrapper.html()).empty();
                $wrapper.html(opts.areyousure).append('<a href="" class="yes">'+opts.yes+'</a>')
                        .append(opts.separator)
                        .append('<a href="" class="no">'+opts.no+'</a>');
                $wrapper.find('a.yes').click(confirmed);
                $wrapper.find('a.no').click(revert);
                return false;
            };
            $this.click(click);
            function confirmed (event) {return opts.confirmed.call(this, event);};
            function revert (event) {                
                var $wrapper= $(this).parent();
                $wrapper.html($wrapper.data('cache'));
                $wrapper.find(opts.reselector).click(click)
                return false;
            };
        })
    };
    $.fn.ztmInlineConfirm.defaults = {
        'confirmed': function () {return false;},
        'areyousure': 'Are you sure? ',
        'yes': 'Yes',
        'no': 'No',
        'separator': '/',
        'reselector': '> span'
    };
    
    
    $.fn.ztmInsertAtCaret = function (myValue) {
            return this.each(function(){
                    //IE support
                    if (document.selection) {
                            this.focus();
                            sel = document.selection.createRange();
                            sel.text = myValue;
                            this.focus();
                    }
                    //MOZILLA/NETSCAPE support
                    else if (this.selectionStart || this.selectionStart == '0') {
                            var startPos = this.selectionStart;
                            var endPos = this.selectionEnd;
                            var scrollTop = this.scrollTop;
                            this.value = this.value.substring(0, startPos)
                                          + myValue
                                  + this.value.substring(endPos,
                            this.value.length);
                            this.focus();
                            this.selectionStart = startPos + myValue.length;
                            this.selectionEnd = startPos + myValue.length;
                            this.scrollTop = scrollTop;
                    } else {
                            this.value += myValue;
                            this.focus();
                    }
            });

};
    
})(jQuery)

function _ (string) {return string};

jQuery.ztm_ajaxhandler = function (options) {
    options._error = options.error
    options.error = function (result) {
        //TODO: Handle other HTTP error codes like redirect.
        if (result.readyState === 0) {
            // Timeout
            message = _("The server took to long to respond. Your request may complete at a later time. Please wait a while and reload the page before trying again.");
            if (!options.timeoutError===undefined)
                options.timeoutError(result, options.context, message);
            else if (options._error)
                options._error(result, options.context, message);
        } else if (result.status === 0) {
            // The server did not respond
            message = _("The server did not respond. Please check your internet connection or the state of the server.");
            if (options.noreplyError)
                options.noreplyError(result, options.context, message);
            else if (options._error)
                options._error(result, options.context, message);
        } else if (options[result.status+'']) {
            options[result.status+''](result, options.context)
        } else if (result.status === 200) {
            options.success(result, options.context)
        } else if (result.status === 404) {
            // The path was not recognised.
            message = _("The server did not understand the request. Please reload page and try again.");
            if (options.notfoundError)
                options.notfoundError(result, options.context, message);
            else if (options._error)
                options._error(result, options.context, message);
        } else if (result.status >= 500) {
            message = _("An error occurred on the server. Please reload page and try again.");
            if (options._error!==undefined)
                options._error(result, options.context, message);
        }
        delete options.context
        delete options.error
        delete options.success
        return false;
    };
    options._success = options.success
    options.success = function (event) {
        if (options._success!==undefined)
            options._success(event, options.context)
        delete options.context
        delete options.error
        delete options.success
    }
    jQuery.ajax(options);
}
jQuery.jsonGET = function (options) {
    options = jQuery.extend( { 'type': 'GET'
                             , 'timeout': 10000
                             , 'dataType': 'json'
                             }
                           , options);
    $.ztm_ajaxhandler(options);
}
jQuery.jsonPOST = function (options) {
    options = jQuery.extend( options
                           , { 'type': 'POST'
                             , 'contentType': 'application/json'
                             , 'processData': false
                             , 'timeout': 10000
                             , 'dataType': 'json'
                             });
    options.data = JSON.stringify(options.data)
    $.ztm_ajaxhandler(options);
}
jQuery.jsonDELETE = function (options) {
    options = jQuery.extend( {}
                           , { 'type': 'POST'
                             , 'timeout': 10000
                             , processData: true
                             //XXX: Temporarily tunnel through POST. Problem is
                             // default handling of deletes in Zope.
                             , beforeSend: function (xhr) { xhr.setRequestHeader('X-METHOD-OVERRIDE', 'DELETE');
                                                          }
                             }
                           , options
                           );
    $.ztm_ajaxhandler(options);
}
jQuery.jsonPUT = function (options) {
    //TODO: Handle request data.
    options = jQuery.extend( options
                           , { 'type': 'POST'
                             , 'dataType' : 'json'
                             , 'processData' : false
                             , 'contentType': 'application/json'
                             , 'processData': false
                             , 'timeout': 10000
                             , 'dataType': 'json'
                             , beforeSend: function (xhr) { xhr.setRequestHeader('X-METHOD-OVERRIDE', 'PUT');
                                                          }
                             });
    options.data = JSON.stringify(options.data)
    $.ztm_ajaxhandler(options);
}


ZTM.COLLABROOM = {
    role_options: {
        select: function (element, key, value) {
            //TODO: show timer.
            jQuery.jsonPOST({ url: element.parents('li').find('> a').attr('href')
                            , data: {'role': key, 'mail': element.parents('li').find('.email').text()}
                            , success: function (element, context) { context.find('.inner').text(value); }
                            , error: function (element, context, message) {alert(message);}
                            , context: element
                            })
        }
    },

    remove_member_options: {
        confirmed: function (event) {
            var url = $(this.parentNode.parentNode).find('>a').attr('href');
            $.jsonDELETE({ url: url
                         , context: $(this).parents('li')
                         , success: function (result, context) {context.animate({'opacity':0, 'height':0}); return false;}
                         })
            return false;
        }
    },
    
    initialize: function () {
        $('.create').ztmDropForm();
        $('.firstfocus').focus();
        $('.biglinks li').ztmBigLink();
        $('.entries .entry .preview').ztmBigLink({containerSelector:'.entry'});
        
        $('#ztm-collabroom-members-list li .role').ztmSimpleSelector(ZTM.COLLABROOM.role_options);
        $('#ztm-collabroom-members-list .remover').ztmInlineConfirm(ZTM.COLLABROOM.remove_member_options);
        
        var formatEmailAutoCompleteItem = function (row) {
            return row[0] ;//+ "<br><i>" + row[1] + "</i>";
        }


        var memberInviteEmailField = $("#ztm-collabroom-invite-member-form input#email");
        if( memberInviteEmailField.length > 0 ) {
            var autocompleteSearchURL = memberInviteEmailField.siblings(".emailAutocompleteSearchURL").text();
            memberInviteEmailField.autocomplete(autocompleteSearchURL,
                                       { minChars:2, 
                                         matchSubset:0, 
                                         matchContains:0,
                                         autoFill:true,
                                         maxItemsToShow:10,
                                         selectOnly:1 });
        }
        


        
        
        $('#ztm-collabroom-create-room-form #title').keyup(ZTM.COLLABROOM.identityupdate);
        $('#ztm-collabroom-create-room-form #identity').keydown(ZTM.COLLABROOM.identityKeydown);
        
        if ($('#ztm-collabroom-accept-invitation').length) {
            ZTM.COLLABROOM.ACCEPTINVITATION.initialize();
        }
        if ($('#ztm-collabroom-invitation-adminview').length) {
            ZTM.COLLABROOM.INVITATIONADMINVIEW.initialize();
        }
        if ($('#ztm-collabroom-password-change').length) {
            ZTM.COLLABROOM.PASSWORDCHANGEVIEW.initialize();
        }
        if ($('#ztm-collabroom-create-user-account').length) {
            ZTM.COLLABROOM.CREATEUSERACCOUNTVIEW.initialize();
        }
        
        
        //$('#ztm-collabroom-create-room-form #identity').before($("<span>"+location.protocol+"//"+location.host+"/"+"</span>"))
        $('#ztm-collabroom-unanswered-invitations li.invitation').ztmAcceptDecline(
            {'accept':  function(event) {
                            var eventtarget = $(this),
                                inviteLI = eventtarget.parents("li.invitation"),
                                sentinel = inviteLI.children("input.sentinel").val(),
                                url = $("input.inviteurl").val();
                            ZTM.COLLABROOM.ACCEPTINVITATION.acceptJoin.call(this, url, sentinel);
                            return false;
                        },
             'decline': function(event) {
                            var eventtarget = $(this),
                                inviteLI = eventtarget.parents("li.invitation"),
                                sentinel = inviteLI.children("input.sentinel").val(),
                                url = $("input.inviteurl").val() + "/decline";
                            ZTM.COLLABROOM.ACCEPTINVITATION.declineJoin.call(this, url, sentinel);
                            return false;
                        }
            }
        );
        
        var documentstable = $("form.filearchive table");
        if( documentstable.length > 0 ) {
            $.tablesorter.addParser({
                id: "collabroomdate",
                is: function(s) {
                    return s.match(ZTM.COLLABROOM.dateRegExp);
                },
                format: function(s) {
                    var m = ZTM.COLLABROOM.dateRegExp.exec(s);
                    if(m) {
                        var year    = parseInt(m[ZTM.COLLABROOM.dateRegExp.group_Year],10),
                            month   = parseInt(m[ZTM.COLLABROOM.dateRegExp.group_Month],10),
                            day     = parseInt(m[ZTM.COLLABROOM.dateRegExp.group_Day],10),
                            hours   = parseInt(m[ZTM.COLLABROOM.dateRegExp.group_Hour],10),
                            minutes = parseInt(m[ZTM.COLLABROOM.dateRegExp.group_Minute],10),
                            seconds = 0,
                            milliseconds = 0;                    
                        return $.tablesorter.formatFloat(new Date(year, month, day, hours, minutes, seconds, milliseconds).getTime());
                    } else {
                        return 0;
                    }
                },
                type: "numeric"
            });
            
            $.tablesorter.addParser({
                id: "collabroomsize",
                is: function(s) {
                    return s.match(ZTM.COLLABROOM.sizeRegExp);
                },
                format: function(s) {
                    var m = ZTM.COLLABROOM.sizeRegExp.exec(s);
                    if(m) {
                        var size = parseInt(m[1],10);
                        return size;
                    } else {
                        return 0;
                    }
                },
                type: "numeric"
            });
          
            // Define a custom textextractor for tablesorter, so that we can store
            // a sortvalue in a hidden field.
            var myTextExtraction = function(node)  
            {  
                var sortvalueNode = $(".sortvalue",node);
                if( sortvalueNode.length != 0) {
                    node = sortvalueNode.get(0);
                }
                
                if(node.childNodes[0] && node.childNodes[0].hasChildNodes()) {
                    t = node.childNodes[0].innerHTML;
                } else {
                    t = node.innerHTML;
                }
                return t;
            };            
            documentstable.tablesorter(
                                    
                                    {   sortList: [ [2,0] ], // initially sort on the title column
                                        textExtraction: myTextExtraction,
                                        headers : {
                                                0: {sorter: false }, 
                                                1: {sorter: false },
                                                2: {sorter: "text"}, // title 
                                                3: {sorter:"collabroomsize"}, // size
                                                4: {sorter:"collabroomdate"}, // uploaded datetime 
                                                5: {sorter:"text"}, // version
                                                6: {sorter:false} // comment. no sorting on the "comments" column
                                            }
                                    }                                    
                                    ); 
        }
    },
    identityupdate: function (event) {
        /* This function is called when the user has edited the "Name"-field. We want the
           identifyfield to be automatically updated with a safe version of the name.
        */
        var val = $(event.target).val()
        val = ZTM.COLLABROOM.calcSafeRoomIdentity(val);
        $('#ztm-collabroom-create-room-form #identity').val(val);
    },
    
    
    
    identityKeydown: function (event) {
        /* This function is called when the user tries to enter an identity directly
        */        
        if( (event.keyCode >= 48) || (event.keyCode == 32)) { // everything below 48 is control-keys (arrow-keys, etc)
            // TODO: figure out a way to get the unicode character that would result for
            //       this keydown event. We only get the keycode, and this isn't enough to
            //       retrieve the unicode charactervalue for non-ascii characters (for 
            //       instance the special norwegian  characters: "\u00E6","\u00F8" and "\u00E5"
            
            var keycode = event.charCode || event.keyCode
            var rawval = String.fromCharCode(keycode);
            if( keycode == 222 ) {
                rawval = "\u00E6";
            } else if( keycode == 192) {
                rawval = "\u00F8";
            } else if( keycode == 221) {
                rawval = "\u00E5";
            }
            

            
            val = ZTM.COLLABROOM.calcSafeRoomIdentity(rawval);
            if( val == '' ) {
                // this looks like an illegal character, so skip it.
                return false;
            } 
            if( val != rawval ) {
                // it looks like this character was translated into some other 
                // character, so we must insert the translated character
                $(event.target).ztmInsertAtCaret(val);
                return false;
            }
        }
    },
    
    
    calcSafeRoomIdentity : function(roomname) {
        /* utility-function for making a safe room-identity (the one that shows
           up in the url), based on the room's name. */
        var val = roomname.toLowerCase();
        val = val.replace(/\s/g, '-');

        // Replace some norwegian characters
        val = val.replace(/\u00E6/g,'ae');
        val = val.replace(/\u00F8/g,'o');
        val = val.replace(/\u00E5/g,'aa');

        val = val.replace(/[^a-z,0-9,_,-]/g, '');
        return val
    },
    
    // The dateformat used by the ztm.collabrom package uses this format.
    //   DD.MM.YY HH.MM
    // This regexp is used by code that needs to parse the datetimes. (like
    // for instance the jquery.tablesorter)
    dateRegExp : new RegExp(/^([0-9]{2})\.([0-9]{2})\.([0-9]{2}) ([0-9]{2})\.([0-9]{2})$/),
    
    sizeRegExp : new RegExp(/^([0-9]+).*$/)
};
// javascript doesn't support named regexp groups, so we must store the 
// groupnumber instead.
ZTM.COLLABROOM.dateRegExp.group_Day   = 1;
ZTM.COLLABROOM.dateRegExp.group_Month = 2;
ZTM.COLLABROOM.dateRegExp.group_Year  = 3;
ZTM.COLLABROOM.dateRegExp.group_Hour  = 4;
ZTM.COLLABROOM.dateRegExp.group_Minute = 5;



ZTM.COLLABROOM.ACCEPTINVITATION = {
    initialize: function () {
        $('#password').keyup(ZTM.COLLABROOM.ACCEPTINVITATION.checkPassword);
        $('#confirmpwd').keyup(ZTM.COLLABROOM.ACCEPTINVITATION.checkPassword);
        // disable the submit-button until a valid password has been entered
        $('input[type=submit]').attr("disabled","disabled");
    },
    checkPassword: function (event) {
        if ( ($('#password').val().length >= 6) && ($('#password').val()===$('#confirmpwd').val())) {
            $('label[for=password]').removeClass('incorrect');
            $('label[for=password]').addClass('matching');
            $('label[for=confirmpwd]').removeClass('incorrect');
            $('label[for=confirmpwd]').addClass('matching');
            
            // enable the submit-button, since the password looks valid
            $('input[type=submit]').removeAttr("disabled");

        } else {
            // disable the submit-button until a valid password has been entered
            $('input[type=submit]').attr("disabled","disabled");

            if ($('#password').val().length>$('#confirmpwd').val().length) {
                $('label[for=password]').removeClass('matching');
                $('label[for=password]').removeClass('incorrect');
                $('label[for=confirmpwd]').removeClass('matching');
                $('label[for=confirmpwd]').addClass('incorrect');
            } else {
                $('label[for=password]').removeClass('matching');
                $('label[for=password]').addClass('incorrect');
                $('label[for=confirmpwd]').removeClass('matching');
                $('label[for=confirmpwd]').removeClass('incorrect');
            }
        }
    },
    declineJoin: function (url, sentinel) {
        jQuery.jsonPOST({ url: url
                        , data: { 'sentinel': sentinel }
                        , success: function (element, context) {document.location.href = document.location.href;}
                        , error: function (element, context, message) {alert(message);}
                        });
    },
    acceptJoin: function (url, sentinel) {
        jQuery.jsonPOST({ url: url
                        , data: {'sentinel': sentinel }
                        , success: function (element, context) {
                            // TODO: Use javascript to update the GUI with the
                            // newly joined room. For now we just reload the
                            // page.
                            document.location.href = document.location.href;
                            }
                            , error: function (element, context, message) {alert(message);}
                        });
    }
};

ZTM.COLLABROOM.INVITATIONADMINVIEW = {
    initialize: function () {
        // Set the initial submit-button state (enabled/disabled)
        ZTM.COLLABROOM.INVITATIONADMINVIEW.updateSubmitControls();
        
        // Register an eventhandler on the invite-selection checkboxes, so that the
        // submit-buttons gets enabled/disabled when the user selects/unselects
        // invitations.
        $('#ztm-collabroom-invitation-adminview').click(ZTM.COLLABROOM.INVITATIONADMINVIEW.updateSubmitControls);
    },
    updateSubmitControls : function () {
        /*This function is called when the user has selected or unselected a invitation
          in the "@@invitation-adminview" view. If no invitations are selected, the
          submit-buttons ("Delete", "Resend", etc) need to be disabled.*/
        var submitButtons   = $('#ztm-collabroom-invitation-adminview input[type=submit]');
        var textInputFields = $('#ztm-collabroom-invitation-adminview textarea');
        var selectedInvitations = $('#ztm-collabroom-invitation-adminview input[type=checkbox]:checked');
        if( selectedInvitations.length > 0 ) {
            // at least one invitation has been selected, so enable the buttons.
            submitButtons.removeAttr("disabled");
            textInputFields.removeAttr("disabled");
        } else {
            // no invitations have been selected, so disable the buttons.
            submitButtons.attr("disabled","disabled");
            textInputFields.attr("disabled","disabled");
        }
        return true;
    }
        
};


ZTM.COLLABROOM.PASSWORDCHANGEVIEW = {
    initialize: function () {
        // we use the same password-check code as the "accept-invitation"-view.
        $('#currentpassword').keyup(ZTM.COLLABROOM.ACCEPTINVITATION.checkPassword);
        $('#password').keyup(ZTM.COLLABROOM.ACCEPTINVITATION.checkPassword);
        $('#confirmpwd').keyup(ZTM.COLLABROOM.ACCEPTINVITATION.checkPassword);
        // disable the submit-button until a valid password has been entered
        $('input[type=submit]').attr("disabled","disabled");
    }
};

ZTM.COLLABROOM.CREATEUSERACCOUNTVIEW = {
    initialize: function () {
        // we use the same password-check code as the "accept-invitation"-view.
        $('#password').keyup(ZTM.COLLABROOM.ACCEPTINVITATION.checkPassword);
        $('#confirmpwd').keyup(ZTM.COLLABROOM.ACCEPTINVITATION.checkPassword);
        
        // Call checkPassword() to disable the submit-button if valid password hasn't been entered
        ZTM.COLLABROOM.ACCEPTINVITATION.checkPassword();
    }
};



(function ($) {
    $.fn.ztmDropForm = function (options) {
        var opts = $.extend({}, $.fn.ztmDropForm.defaults, options);
        return this.each(function () {
            var $this = $(this),
                $header = $(opts.headerselector, $this).css({'cursor':'pointer'}),
                $statusIcon = $('<span class="collapsed"></span>').prependTo($header),
                $inner = $(opts.innerselector, $this);
            function close(e) {
                $inner.slideUp();
                $statusIcon.removeClass("expanded")
                return false;
            }
            function open(e){
                $inner.slideDown();
                $statusIcon.addClass("expanded")
                return false;
            }
            function cancel(e) {
                $header.click();
                return false;
            }
            $header.toggle(open, close);
            $(opts.closeselector, $this).bind('click', cancel);
            if (window.location.hash && $(window.location.hash).length) {                                
                $(window.location.hash+' '+opts.headerselector).trigger('click');
            }
        });
    };
    jQuery.fn.ztmDropForm.defaults = {
        innerselector: "> .inner",
        closeselector: ".cancel",
        headerselector: "> h2"
    };
    
    /* make an container element hoverable and clickable. When clicked it will
     * bring the user to the url defined by the element adressed by the
     * triggerSelector example:
     *
     * <ul class="biglinks">
     *   <li>
     *     <p>some nice text</p>
     *     <a class="" href="http://ztmproject.org">click me</a>
     *    </li>
     * </ul>
     * $('.biglinks li').biglinks()
     *
     */
    $.fn.ztmBigLink = function (options) {
        var opts = $.extend({}, $.fn.ztmBigLink.defaults, options);
        return this.each(function () {
            var $this = $(this);
            $this
              .hover(function(){$(this).addClass('hover')}, function(){$(this).removeClass('hover')})
              .bind('click', function() {
                  $container = $this;
                  if (opts.containerSelector != "this"){
                      $container = $this.parents(opts.containerSelector)
                  }
                  href = $(opts.triggerSelector+":first", $container).attr('href')
                  if (href != ""){
                      window.location.href = href;
                  }
              });
        });
    };
    $.fn.ztmBigLink.defaults = {
        containerSelector: "this",
        triggerSelector: ".biglink-trigger"
    };
})(jQuery);


function commentData(element) {
    if (element && element.firstChild && element.firstChild.nodeType===8) {
        var t = null;
        eval('t='+element.firstChild.data);
        return t
    }
};

(function ($) {
    $.fn.ztmSimpleSelector = function (options) {
        var opts = $.extend({}, $.fn.ztmSimpleSelector.defaults, options);
        return this.each(function () {
            // Retrieve the selector data and override opts.
            var selectelement = $(this).data('opts', commentData(this) || opts.values).click(click);
            function click(event) {
                // Don't propagate click to avoid triggering the click handler
                // on the body element that clears the selector.
                event.stopPropagation();
                
                // Highlight the existing selector-div if the element is
                // clicked more than once.
                if (selectelement.attr('for') && $('#'+selectelement.attr('for')).length) {
                    $('#'+selectelement.attr('for')).css({'background-color':'yellow'})
                                                    .animate({backgroundColor:'#ffffff'});
                    return;
                }
                
                // Create an absolutely positioned div and fill it with the
                // selections. The for attribute of the selectelement matches
                // the id of the div making it easy to refer to an already 
                // opened div later.
                var id = Math.floor(Math.random()*10000),
                    $body = $('body').bind('click', clear),
                    selector = $('<div></div>').addClass('ztm-collabroom-simple-selector')
                                               .css({ 'border':'thin solid black'
                                                    , 'background-color':'white'
                                                    , 'padding': '0.5em'
                                                    , 'width': '15em'
                                                    , 'position':'absolute'
                                                    , 'left': selectelement.offset().left
                                                    , 'top': selectelement.offset().top + selectelement.height()
                                                    })
                                               .append('<ul></ul>')
                                               .attr('id', 's'+id)
                                               .appendTo('body'),
                    list = selector.find('ul').css({'list-style-type': 'none'});
                selectelement.attr('for', 's'+id);
                var localopts = selectelement.data('opts');
                for (var name in localopts.values) {
                    $('<li></li>').text(localopts.values[name])
                                  .css({'cursor':'pointer'})
                                  .attr({'title': name})
                                  .appendTo(list)
                                  .click(select);
                }
            };
            function select (event) {
                //TODO: Verify that this is actually new value.
                event.stopPropagation()
                var div = $(event.target.parentNode.parentNode);
                    body = $('body').unbind('click')
                    selected = $(event.target).attr('title');
                div.fadeOut(function () {div.remove(); selectelement.removeAttr('for');});
                return opts.select(selectelement, selected, selectelement.data('opts').values[selected]);
            };
            function clear (event) {
                var selectors = $('.ztm-collabroom-simple-selector');
                selectors.fadeOut(function () {selectors.remove()})
                $('body').unbind('click');
            };
        });
    };
    jQuery.fn.ztmSimpleSelector.defaults = {
        innerselector: "> .inner",
        values: {"contributor":"Contributor", "administrator":"Administrator"},
        select: function (element, selected, text) {element.find('.inner').text(text);}
    };
})(jQuery);



/* initialization */
$(document).ready(function () {
    ZTM.COLLABROOM.initialize();
});

