var screamUpdate = 5000;
var screamTimer = null;
var firstCheck = true;

var settings = {};

function setCookie(name, value, expiredays) {
  value = Object.toJSON(value);

  var exdate = new Date();
  exdate.setDate(exdate.getDate() + expiredays);
  document.cookie = name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString());
}

function getCookie(name) {
  if (document.cookie.length > 0) {
    var start = document.cookie.indexOf(name + "=");
    if (start != -1) {
      start = start + name.length+1;
      var end = document.cookie.indexOf(";", start);
      if (end == -1) end = document.cookie.length;
      return unescape(document.cookie.substring(start, end)).evalJSON()
    }
  }
  return "";
}

function loadSettings() {
  settings = getCookie('settings');
  if (settings == '') settings = {};
}

function saveSettings() {
  setCookie('settings', settings, 365)
}


var theBucketCam;
var screamWindow;
var bucketWindow;
var keys = {};
function init() {

  if (isIE6()) alert('IE6 is not that good and stuff will not really work as ultimate as in other browsers.');

  Object.extend(Event, {
    wheel:function (event){
      return event.detail ? (event.detail * -1) : event.wheelDelta / 40;
    }
  });

  Event.observe(document, 'keydown', function(e) {
    var code;
    if (!e) var e = window.event;
    if (e.keyCode) code = e.keyCode;
    else if (e.which) code = e.which;
    keys[code] = true;
  });

  Event.observe(document, 'keyup', function(e) {
    var code;
    if (!e) var e = window.event;
    if (e.keyCode) code = e.keyCode;
    else if (e.which) code = e.which;
    keys[code] = false;
  });

  loadSettings();

  pb.system.init();


  var fpsData = document.createElement('div');
  var paus = document.createElement('div');
  Event.observe(paus, 'click', (function() {
    if (theBucketCam.running) theBucketCam.stop();
    else theBucketCam.start();
  }));
  bucketWindow = pb.windowHandler.create('bucketWindow', 'The Purple Bucket', '<img src="/img/loading.jpg" id="theBucket">', {
    contentType: 'html',
    left: 370,
    top: 10,
    width: 320,
    height: 240,
    movable: true,
    forcePosDim: false,
    closable: false,
    minimizable: true,
    customButtons: [ { button: paus, cssClass: 'pausButton' }, { button: fpsData, cssClass: 'fpsData' } ]
  });

  screamWindow = pb.windowHandler.create('screamWindow', 'Scream', '/index.php?m=Scream', {
    contentType: 'ajax',
    left: 10,
    top: 10,
    width: 320,
    height: 240,
    movable: true,
    forcePosDim: false,
    sizable: 'v',
    closable: false,
    reloadable: true,
    minimizable: true,
    ajaxSuccess: function(win, transport) {
      var dataError = false;
      try  {
        var data = transport.responseText.evalJSON();
      } catch(err) {
        dataError = true;
      }

      if (!dataError) {
        win.setHTML(data['html']);
        eval(data['js']);
        initScreams();

        Event.observe($('screamText'), 'keypress', (function(event) {
          if ((event.ctrlKey || keys[16] == true) && event.keyCode == 13) postScream();
        }));

      } else win.setHTML(transport.responseText);
    }
  });

  theBucketCam = new WebCamClass('/index.php?m=Cam', 'theBucket', 1, '/img/loading.jpg');
  theBucketCam.started = theBucketCam.started.wrap(function(orig) {
    orig();
    Element.removeClassName(bucketWindow.nodes.container, 'camPaused');
  });
  theBucketCam.stopped = theBucketCam.stopped.wrap(function(orig) {
    orig();
    Element.addClassName(bucketWindow.nodes.container, 'camPaused');
  });
  theBucketCam.start();

  reopen();

  pb.windowHandler.goThroughOrder();

  checkForNewScreams();

  // setup fps display events
  /*
  theBucketCam.newFrame = theBucketCam.newFrame.wrap(function(orig) {
    orig();
    fpsData.innerHTML = 'fps: ' + Math.round(theBucketCam.currentFps * 100) / 100;
  });
  */
  theBucketCam.currentFpsChange = theBucketCam.currentFpsChange.wrap(function(orig, fps) {
    orig(fps);
    fpsData.innerHTML = 'fps: ' + Math.round(fps * 100) / 100;
  });

  // --
}

function reopen() {
    // reopen profile windows
    if (!!settings.profiles) {
      settings.profiles.each(function(id) { openProfile(id); });
    }

    if (!!settings.openWindows) {
      settings.openWindows.each(function(name) {
        switch (name) {
          case 'login':
            openLoginWindow();
            break;
        }
      });
    }
}

var screamScroller;
var screamCount = 0;
var lastScreamId = 0;
function initScreams() {
  /*
     IE6 fails to init scroll when it is not visible
     So to fix it we check what the state is and if it not
     visible wait for onStateChange event and then init it.
  */
  var state = screamWindow.getState();
  if (state.indexOf('m') > -1 || state.indexOf('r') > -1) {
    screamWindow.onStateChange = function(win, s) {
      if (s.indexOf('m') == -1 && s.indexOf('r') == -1) {
        screamWindow.onStateChange = function() {};
        initScreams();
      }
    }
    return;
  }
  setScreamHeight(screamWindow, $('screamContainer'));

  var sc = $('screamContainer');
  screamScroller = new pb.scroll(sc, { direction: 'v' });
  screamScroller.onReachBottom = function(scroller, method) { getMoreScreams(); };
  screamScroller.onVBarHide    = function(scroller) { getMoreScreams(); };

  screamWindow.onResize = function(win, direction) {
    setScreamHeight(win, $('screamContainer').parentNode.parentNode);
    screamScroller.redraw();
  };
}

function setScreamHeight(window, sc) {
  var pos = Element.positionedOffset(sc);
  var dim = Element.getDimensions(window.nodes.body);

  Element.setStyle(sc, { height: dim.height - pos[1] + 'px' });
}

var moreScreams = true;
var canGetScreams = true;
function getMoreScreams() {
  if (canGetScreams) {
    canGetScreams = false;
    new Ajax.Request('/index.php?m=Scream&cmd=more&sc=' + screamCount, {
      method: 'get',
      onSuccess: function(transport) {
        var data = transport.responseText.evalJSON();
        screamCount = data['sc'];
        $('screamContainer').innerHTML += data['html'];
        moreScreams = data['more'];
        screamScroller.redraw();
      },
      onComplete: function(transport) { canGetScreams = true; }
    });
  }
}

function toggleScreamForm(force) {
  var form = $('screamForm');
  var link = $('wantToScreamTitle');

  if ((Element.hasClassName(form, 'hidden') && force != 'hide') || force == 'show') {
    Element.removeClassName(form, 'hidden');
    link.innerHTML = 'I don\'t want to scream!';
    var from = settings['from'];
    if (from == undefined ) from = '';
    $('screamFrom').value = from;
  } else {
    Element.addClassName(form, 'hidden');
    link.innerHTML = 'I want to scream!';
  }

  setScreamHeight(screamWindow, $('screamContainer').parentNode.parentNode);
  screamScroller.redraw();
}

function postScream() {
  var from = $F('screamFrom');
  var text = $F('screamText');

  if (text.strip() == "") {
    alert('You need to write something');
  } else {
    new Ajax.Request('/index.php', {
      method: 'post',
      parameters: { m: 'Scream', cmd: 'post', from: from, text: text, lastId: lastScreamId },
      onSuccess: function(transport) {
        var data = transport.responseText.evalJSON();
        if (data.status == 'ok') {
          $('screamFrom').value = '';
          $('screamText').value = '';
          if (lastScreamId < data.lastId) {
            $('screamContainer').innerHTML = data['html'] + $('screamContainer').innerHTML;
            lastScreamId = data.lastId;

            //screamScroller.redraw(); is done in toggleScreamForm anyways
          }
          toggleScreamForm('hide');

          settings['from'] = from;
          saveSettings();
        } else if (data.status == 'notext') {
          alert('You need to write something');
        }
      },
      onFailure: function(transport) { alert('Something went wrong'); }
    });
  }
  return false;
}

// heartbeat piggyback rides here
function checkForNewScreams() {
  if (lastScreamId != 0) {
    new Ajax.Request('/index.php', {
      method: 'get',
      parameters: { m: 'Scream', cmd: 'check', lastId: lastScreamId, firstCheck: firstCheck },
      onSuccess: function(transport) {
        var data = transport.responseText.evalJSON();
        if (data.askedLastId == lastScreamId && data.lastId != lastScreamId) {
          $('screamContainer').innerHTML = data['html'] + $('screamContainer').innerHTML;
          lastScreamId = data.lastId;
          screamScroller.redraw();
          pb.sound.play('scream');
        }
        if (data.online) {
          pb.system.setOnlineUsers(data.online);
        }
        if (data.onload) {
          eval(data.onload);
        }
        if (data.unOpenChat) {
          pb.chat.checkUnOpen(data.unOpenChat);
        }
        if (data.openChat) {
          pb.chat.checkOpen(data.openChat);
        }
        if (data.n) {
          data.n.each((function(n) {
            pb.system.showPopup(n.text, false, false, false, n.titleBG, n.titleColor, n.contentBG, n.contentColor);
          }));
        }
        firstCheck = false;
      },
      onComplete: function(transport) {
        screamTimer = setTimeout(checkForNewScreams, screamUpdate);
      }
    });
  } else {
    screamTimer = setTimeout(checkForNewScreams, 1000);
  }
}

function loginLogout() {
  var link = $('loginLink');
  if (link.innerHTML.toLowerCase() == 'logout') {
    doLogout();
  } else {
    openLoginWindow();
  }
  return false;
}

var loginWindow;
function openLoginWindow() {
  loginWindow = pb.windowHandler.create('loginWindow', 'Login', '/index.php?m=User', {
    contentType: 'ajax',
    left: 0,
    top: 0,
    width: 170,
    height: 80,
    movable: true,
    focePosDim: false,
    parent: 'mouse',
    corners: ['TL', 'BR']
  });
  if (settings.openWindows == undefined) settings.openWindows = [];
  if (settings.openWindows.indexOf('login') == -1) {
    settings.openWindows[settings.openWindows.length] = 'login';
    saveSettings();
  }

  loginWindow.onClose = loginWindow.onClose.wrap(function(orig, window) {
    orig(window);
    loginWindow = null;
    settings.openWindows = settings.openWindows.without('login');
    saveSettings();
  });

}

function doLogin() {
  var user = $F('loginName');
  var password = $F('loginPassword');
  var remember = $('loginRemember').checked;

  new Ajax.Request('index.php', {
    method: 'post',
    parameters: { m: 'User', cmd: 'login', userName: user, password: password, remember: remember },
    onSuccess: function(transport) {
      var data = transport.responseText.evalJSON();
      if (data.ok) {
        $('loginLink').innerHTML = 'Logout';
        $('profileLink').innerHTML = data.userName;
        $('profileLink').onclick = function() { openProfile(data.userId); return false; };
        loginWindow.close();
        clearTimeout(screamTimer);
        checkForNewScreams();
      } else {
        alert('Wrong username and/or password.');
      }
    },
    onFailure: function(transport) { alert('Something went wrong'); }
  });
}

function doLogout() {
  new Ajax.Request('index.php', {
    method: 'post',
    parameters: { m: 'User', cmd: 'logout' },
    onSuccess: function(transport) {
      var data = transport.responseText.evalJSON();
      if (data.ok) {
        $('loginLink').innerHTML = 'Login';
        $('profileLink').innerHTML = data.userName;
        $('profileLink').onclick = function() { openProfile(data.userId); return false; };
        clearTimeout(screamTimer);
        checkForNewScreams();
      }
    },
    onFailure: function(transport) { alert('Something went wrong'); }
  });
}

function doPwReset() {
  var email = $F('forgotEmail');
  if (email.strip() == '') {
    alert('You need to enter a email.');
    return;
  }

  new Ajax.Request('index.php', {
    method: 'post',
    parameters: { m: 'User', cmd: 'reset', email: email },
    onSuccess: function(transport) {
      var data = transport.responseText.evalJSON();
      alert(data.message);
      if (data.ok) {
        loginWindow.close();
      }
    },
    onFailure: function(transport) { alert('Something went wrong'); }
  });
}

function forgottenPassword() {
  if (!!loginWindow) {
    loginWindow.setContent('/index.php?m=User&cmd=forgott')
  }
}

function showBucketCapture(id) {
  bucketWindow.setTitle('Bucket Capture');
  theBucketCam.showStatic('/img/screams/' + id + '.jpg');
}

function hideBucketCapture() {
  bucketWindow.setTitle('The Purple Bucket');
  theBucketCam.removeStatic();
}

function openProfile(userId) {
  pb.windowHandler.create('profile_' + userId, 'Loading Profile...', '/index.php?m=User&cmd=profile&uid=' + userId, {
    contentType: 'ajax',
    left: 0,
    top: 0,
    corners: ['MC', 'MC'],
    width: 320,
    movable: true,
    forcePosDim: false,
    sizable: 'v',
    scroll: 'v',
    minimizable: true,
    reloadable: true,
    ajaxSuccess: function(win, transport) {
      var data = {};
      var dataOk = false;
      try  {
        data = transport.responseText.evalJSON();
        dataOk = true;
      } catch(err) {
        dataOk = false;
      }
      if (dataOk) {
        win.setTitle(data.displayName);
        win.setHTML(data.html);

        if (settings['profiles'] == undefined) settings['profiles'] = [];
        if (settings['profiles'].indexOf(userId) == -1) {
          settings['profiles'][settings['profiles'].length] = userId;
          saveSettings();
        }

        win.onClose = win.onClose.wrap(function(orig, window) {
          orig(window);
          settings['profiles'] = settings['profiles'].without(userId);
          saveSettings();
        });
      } else {
        win.setHTML(transport.responseText);
      }
    }
  });
}

function editProfile(userId) {
  var win = pb.windowHandler.findWindow('profile_' + userId);
  if (win) {
    win = win[1];
    win.setContent('/index.php?m=User&cmd=profileEdit&uid=' + userId, false, false);
  }
}

function cancelProfileEdit() {
  var userId = $F('puid');
  var win = pb.windowHandler.findWindow('profile_' + userId);
  if (win) {
    win = win[1];
    win.reload();
  }
}

function saveProfile(register) {
  var pre = '';
  if (register) pre = 'r_';
  var description = $F(pre+'description');
  var displayName = $F(pre+'dName');
  var loginName   = $F(pre+'lName');
  var homepage    = $F(pre+'homepage');
  var nPass       = $F(pre+'nPass');
  var rPass       = $F(pre+'rPass');
  var email       = $F(pre+'profileEmail');

  if (!register) {
    var userId = $F('puid');
  }

  if (nPass != rPass) {
    alert('The passwords do not match');
    return;
  }

  if (loginName.strip() == '') {
    alert('Login name can not be empty');
    return;
  }

  if (email.strip() == '') {
    if (!confirm('The email will only be used for password reset. It will not be seen by anyone. Continue without?')) {
      return;
    }
  }

  var parameters = {
    m: 'User',
    description: description,
    displayName: displayName,
    loginName: loginName,
    homepage: homepage,
    userId: userId,
    nPass: nPass,
    rPass: rPass,
    email: email
  };

  if (register) {
    parameters.cmd = 'profileCreate';
  } else {
    parameters.cmd = 'profileSave';
    parameters.uid = userId;
  }

  new Ajax.Request('/index.php', {
    method: 'post',
    parameters: parameters,
    onSuccess: function(transport) {
      var data = transport.responseText.evalJSON();
      alert(data.message);
      if (data.ok) {
        if (register) {
          var win = pb.windowHandler.findWindow('registerWindow');
          if (win) {
            win = win[1];
            win.close();
          }
        } else {
          var win = pb.windowHandler.findWindow('profile_' + userId);
          if (win) {
            win = win[1];
            win.reload();
          }
        }
      }
    },
    onFailure: function(transport) { alert('Something went wrong'); }
  });
}

function register() {
  pb.windowHandler.create('registerWindow', 'Register', '/index.php?m=User&cmd=register', {
    contentType: 'ajax',
    left: 10,
    top: 10,
    corners: ['TL', 'BR'],
    parent: 'mouse',
    width: 320,
    movable: true,
    forcePosDim: false,
    sizable: 'v',
    scroll: 'v',
    closable: true,
    reloadable: false
  });
}

function debug(text) {
  var div = $('debug');
  div.innerHTML = text + '<br />----------<br />' + div.innerHTML;
}

if (!window.pb) {
  window.pb = {};
}

pb.system = {
  init: function() {
    this.createRightSide();

    settings['openChat'] = {};
    saveSettings();

  },

  linkIn: function(id, link) {
    bucketWindow.setTitle('Link capture');
    theBucketCam.showStatic('/img/links/' + id + '.jpg', '/img/links/error.png');
  },

  linkOut: function() {
    bucketWindow.setTitle('The Purple Bucket');
    theBucketCam.removeStatic();
  },

  createRightSide: function() {
    this.rightSide = document.createElement('div');
    this.rightSide.id = 'rightSide';
    document.body.appendChild(this.rightSide);

    this.popupHolder = document.createElement('div');
    this.popupHolder.id = 'popups';
    this.rightSide.appendChild(this.popupHolder);


    this.onlineDisplay = document.createElement('div');
    this.onlineDisplay.id = 'onlineDisplay';
    this.onlineDisplayS = document.createElement('div');
    this.onlineDisplay.appendChild(this.onlineDisplayS);
    this.chatNotifyer = document.createElement('div');
    this.chatNotifyer.id = 'chatNotifyer';
    this.onlineDisplay.appendChild(this.chatNotifyer);
    this.chatNotifyer.innerHTML = '&nbsp;';
    this.soundVolume = document.createElement('div');
    this.soundVolume.id = 'soundVolume';
    Element.addClassName(this.soundVolume, 'mute');
    Event.observe(this.soundVolume, 'click', pb.sound.toggle);
    this.onlineDisplay.appendChild(this.soundVolume);

    Event.observe(this.chatNotifyer, 'click', function() { pb.chat.openNext(); });

    this.rightSide.appendChild(this.onlineDisplay);
    this.createOnlineList();

  },

  setOnlineUsers: function(users) {
    this.onlineDisplayS.innerHTML = 'Online: ' + users.onlineCount;
    this.updateOnlineList(users);
    this.goThroughComeAndGo(users);
  },

  onlineList: null,
  createOnlineList: function() {
    if (this.onlineList == null) {
      this.onlineList = document.createElement('div');
      this.onlineList.id = 'onlineList';
      this.onlineDisplay.appendChild(this.onlineList);
    }
  },

  updateOnlineList: function(users) {
    this.onlineList.innerHTML = '';
    $H(users.list).each((function(user) {
      this.onlineList.appendChild(this.createOnlineUser(user[1]));
    }).bind(this));
  },

  createOnlineUser: function(user) {
    var id = user.id + '_' + user.visitId;
    var a = document.createElement('a');
    a.href = '#';
    var cssClass = 'onlineBullet';
    if (!!pb.chat.unRead) {
      if (pb.chat.unRead.get(id) != undefined) {
        cssClass = cssClass + ' notify';
      }
    }
    a.innerHTML = '<div id="bullet_' + id + '" class="' + cssClass + '" style="background-color: #' + user.ipColor + ';"><div></div></div> ' + user.displayName + ' <span style="font-size: 9px;">' + user.online + '</span>';
    Event.observe(a, 'click', function(event) {
      if (keys[17] == true) openProfile(user.id);
      else pb.chat.open(user.id, user.visitId, user.displayName);
      Event.stop(event);
    });
    return a;
  },

  hideOnlineList: function(event) {
    if (Event.element(event).id != 'onlineList') return;
    document.body.removeChild(this.onlineList);
  },

  goThroughComeAndGo: function(users) {

    users.login.each((function(user) {
      this.showPopup(user.displayName + ' logged in', false, false, (function(popup) {
        this.userPopupClick(popup, user);
      }).bind(this));
      pb.sound.play('login');
    }).bind(this));

    users.logout.each((function(user) {
      this.showPopup(user.displayName + ' logged out', false, false, (function(popup) {
        this.userPopupClick(popup, user);
      }).bind(this));
      pb.sound.play('logout');
    }).bind(this));


    users.online.each((function(user) {
      this.showPopup(user.displayName + ' is now online', false, false, (function(popup) {
        this.userPopupClick(popup, user);
      }).bind(this));
      pb.sound.play('online');
    }).bind(this));


    users.offline.each((function(user) {
      this.showPopup(user.displayName + ' is now offline', false, false, (function(popup) {
        this.userPopupClick(popup, user);
      }).bind(this));
      pb.sound.play('offline');
    }).bind(this));

  },

  userPopupClick: function(popup, user) {
    if (keys[17] == true) { // ctrl
      openProfile(user.id);
    } else {
      // userId, visitId, displayName
      pb.chat.open(user.id, user.visitId, user.displayName);
    }
  },

  popupList: [],
  addPopup: function(popup) {
    this.popupList[this.popupList.length] = popup;
  },

  removePopup: function(popup) {
    this.popupList = this.popupList.without(popup);
  },

  showPopup: function(theContent, timeout, theTitle, clickHandler, titleBG, titleColor, contentBG, contentColor) {
    if (!timeout) timeout = 60000;
    if (!theTitle) theTitle = this.formatTime();
    var container = document.createElement('div');
    var title     = document.createElement('div');
    var content   = document.createElement('div');
    var close     = document.createElement('div');

    Element.addClassName(container, 'popupContainer');
    Element.addClassName(title,     'popupTitle');
    Element.addClassName(content,   'popupContent');
    Element.addClassName(close,     'popupClose');

    if (!!clickHandler) {
      Event.observe(content, 'click', (function() { clickHandler(container); }));
    }

    container.appendChild(title);
    container.appendChild(content);

    title.innerHTML = theTitle;
    content.innerHTML = theContent;

    title.appendChild(close);

    if (!!titleBG)      Element.setStyle(title,   { backgroundColor: titleBG      });
    if (!!titleColor)   Element.setStyle(title,   { color:           titleColor   });
    if (!!contentBG)    Element.setStyle(content, { backgroundColor: contentBG    });
    if (!!contentColor) Element.setStyle(content, { color:           contentColor });

    Element.setOpacity(container, 0);
    Element.insert(this.popupHolder, {top: container});

    var fi = new pb.animate.fadein(container);
    fi.start();
    Event.observe(close, 'click', (function() { this.closePopup(container); } ).bind(this));
    container.timerId = setTimeout((function() { this.closePopup2(container); }).bind(this), timeout);

    this.addPopup(container);
  },

  closePopup: function(popup) {
    this.closePopup2(popup);
    if (keys[17] == true) {
      this.closeAllPopups();
    }
  },

  closeAllPopups: function() {
    this.popupList.each((function(popup) {
      this.closePopup2(popup);
    }).bind(this));
  },

  closePopup2: function(popup) {
    if (popup.timerId) clearTimeout(popup.timerId);

    var fade   = new pb.animate.fadeout(popup);
    //div, steps, delay, toWidth, toHeight
    var shrink = new pb.animate.size(popup, 10, 1, false, 0);
    shrink.onFinished = (function(animation) {
      var parent = popup.parentNode;
      if (parent) popup.parentNode.removeChild(popup);
      this.removePopup(popup);
    }).bind(this);
    fade.onFinished = (function(animation) {
      shrink.start();
    }).bind(this);
    fade.start();
  },

  getDateObject: function() {
    var d = new Date();
    var offset = d.getTimezoneOffset();
    d.setTime(d.getTime() + (offset * 60) + 3600);
    return d;
  },

  formatTime: function() {
    var d = this.getDateObject();
    var h = parseInt(d.getHours());
    var m = parseInt(d.getMinutes());
    var s = parseInt(d.getSeconds());

    if (h < 10) h = '0'+h;
    if (m < 10) m = '0'+m;
    if (s < 10) s = '0'+s;

    return h+':'+m+':'+s;
  },

  profileImages: null,
  showProfileImage: function(userId, imageUrl, thumb) {
    if (this.profileImages == null) this.profileImages = {};
    if ($('profileImage_'+userId)) return;
    var img = document.createElement('img');
    img.id = 'profileImage_'+userId;
    Element.addClassName(img, 'hidden');
    document.body.appendChild(img);
    this.profileImages[userId] = img;

    Event.observe(img, 'load', (function() {
      this.profileImageLoaded(userId, thumb);
    }).bind(this));

    img.src = imageUrl;

  },

  profileImageLoaded: function(userId, thumb) {
    var img = this.profileImages[userId];
    if (!!img) {
      var win = pb.windowHandler.findWindow('profile_' + userId);
      if (!win) return;
      win = win[1];

      img.parentNode.removeChild(img);
      win.nodes.body.appendChild(img);

      var imgDim     = Element.getDimensions(img);
      var winDim     = Element.getDimensions(win.nodes.body.parentNode);
      var thumbDim   = Element.getDimensions(thumb);
      var thumbPos   = Element.positionedOffset(thumb);
      var contentDim = Element.getDimensions(win.nodes.body);

      Element.setStyle(img, { position: 'absolute', top: thumbPos[1]+'px', left: thumbPos[0]+'px', zIndex: 9999, width: thumbDim.width+'px', height: thumbDim.height+'px' });
      Element.removeClassName(img, 'hidden');

      Event.observe(img, 'mouseout', (function() { this.hideProfileImage(userId); } ).bind(this));
      var maxWidth = winDim.width - (thumbPos[0] * 2);
      var maxHeight = 400; //winDim.height - thumbPos[1] - thumbPos[0];
      var toWidth = maxWidth;
      var toHeight = maxHeight;

      var ratio = imgDim.width / imgDim.height;
      if (maxWidth / ratio >  maxHeight) toWidth = maxHeight * ratio;
      else toHeight = toWidth / ratio;

      var anim = new pb.animate.size(img, 10, 30, toWidth, toHeight);
      anim.onFinished = (function(animation) {
        if (toHeight > contentDim.height) {
          Element.setStyle(win.nodes.body, { height: toHeight+'px' });
          win.scroller.redraw();
        }
      }).bind(this);
      anim.start();

    }
  },

  hideProfileImage: function(userId) {
    var img = this.profileImages[userId];
    if (!!img) {
      var fo = new pb.animate.fadeout(img, 20);
      fo.onFinished = (function(animation) {
        if (img.parentNode) img.parentNode.removeChild(img);
        delete this.profileImages[userId];
        var win = pb.windowHandler.findWindow('profile_' + userId)[1];
        Element.setStyle(win.nodes.body, { height: 'auto' });
        win.scroller.redraw();
      }).bind(this);
      fo.start();
    }
  },

  youtube: function(yId) {
    pb.windowHandler.create('youtube_' + yId, 'Youtube video', '/index.php?m=Link&cmd=youtube&id=' + yId , {
      contentType: 'ajax',
      left: 10,
      top: 10,
      corners: ['TL', 'BR'],
      parent: 'mouse',
      width: 426,
      height: 280,
      movable: true,
      forcePosDim: false,
      closable: true,
      minimizable: true,
      sizable: Prototype.Browser.IE ? '' : 'vh',
      ajaxSuccess: (function(win, transport) {
        win.setHTML(transport.responseText);
        var obj = Element.select(win.nodes.body, 'object')[0];
        var embed = Element.select(win.nodes.body, 'embed')[0];
        var div = Element.select(win.nodes.body, 'div')[0];
        var divDim = Element.getDimensions(div);

        if (!Prototype.Browser.IE) {
          var resizer = function() {
            var dim = Element.getDimensions(win.nodes.body);
            var width = dim.width;
            var height = dim.height - divDim.height - 5;
            obj.width = width;
            obj.height = height;
            embed.width = width;
            embed.height = height;
            obj.setAttribute('width', width);
            obj.setAttribute('height', height);
            embed.setAttribute('width', width);
            embed.setAttribute('height', height);
          }

          resizer();

          win.onResize = (function() {
            resizer();
          });
        }
      })
    });
  }

}

pb.chat = {
  chatWindows: {},
  unRead: null,

  checkUnOpen: function(messages) {
    // {"text":"sadfsafd","time":"2009-02-03 13:42:42","fromUserId":"2","fromVisitId":"621","fromName":"Timo"}
    messages.each((function(message) {
      var id = message.fromUserId + '_' + message.fromVisitId;
      if (this.unRead == null) this.unRead = new Hash();
      this.unRead.set(id, [message.fromUserId, message.fromVisitId, message.fromName]);
      Element.addClassName(pb.system.chatNotifyer, 'on');
      pb.system.showPopup(message.fromName + ':<br />' + message.text, false, false, (function(popup) {
        this.open(message.fromUserId, message.fromVisitId, message.fromName);
      }).bind(this));

      var bullet = $('bullet_' + id);
      if (bullet) {
        Element.addClassName(bullet, 'notify');
      }
      pb.sound.play('chat');

    }).bind(this));
  },

  checkOpen: function(messages, opening) {
    if (!!messages) {
      messages.each((function(message) {
        this.addMessage(message);
        if (!opening)
        pb.sound.play('chat');
      }).bind(this));
    }
  },

  create: function(userId, visitId, displayName) {
    var id = userId + '_' + visitId;
    pb.windowHandler.create('chat_' + userId + '_' + visitId, 'Chat ' + displayName, '/index.php?m=Chat&id='+id , {
      contentType: 'ajax',
      left: 0,
      top: 0,
      corners: ['MC', 'MC'],
      movable: true,
      forcePosDim: false,
      closable: true,
      minimizable: true,
      ajaxSuccess: (function(win, transport) {
        var data = transport.responseText.evalJSON();
        win.setHTML(data.html);
        var log = Element.getElementsBySelector(win.nodes.body, '.chatLog')[0];
        var scroll = new pb.scroll(log, { direction: 'v' });
        var send = Element.getElementsBySelector(win.nodes.body, 'input[type="button"]')[0];
        var text = Element.getElementsBySelector(win.nodes.body, 'textarea')[0];

        win.log = log;
        win.scroll = scroll;

        this.chatWindows[userId + '_' + visitId] = win;

        this.checkOpen(data.messages, true);

        Event.observe(send, 'click', (function() {
          this.send(userId, visitId, text);
        }).bind(this));

        Event.observe(text, 'keypress', (function(event) {
          if (event.keyCode == 13) {
            if (!(keys[16] == true || event.ctrlKey)) {
              Event.stop(event);
              this.send(userId, visitId, text);
            }
          }
        }).bind(this));

        win.onClose = win.onClose.wrap((function(orig, window) { orig(window); this.close(userId, visitId); }).bind(this));
      }).bind(this)
    });
  },

  openNext: function() {
    if (this.unRead == null) return;
    var keys = this.unRead.keys();
    if (keys.length == 0) return;
    var d = this.unRead.get(keys[0]);
    this.open(d[0], d[1], d[2]);
  },

  open: function(userId, visitId, displayName) {
    var id = userId + '_' + visitId;
    if (!this.chatWindows[id]) {
      this.create(userId, visitId, displayName);
    } else {

    }

    if (settings['openChat'] == undefined) settings['openChat'] = {};
    settings['openChat'][id] = true;
    if (this.unRead != null) {
      this.unRead.unset(id);
      if (this.unRead.keys().length == 0) Element.removeClassName(pb.system.chatNotifyer, 'on');
    }
    var bullet = $('bullet_' + id);
    if (bullet) {
      Element.removeClassName(bullet, 'notify');
    }
    saveSettings();
  },

  addMessage: function(message, direction) {
    if (direction == undefined) direction = 'in';
    var id = direction == 'in' ?  message.fromUserId + '_' + message.fromVisitId : message.toUserId + '_' + message.toVisitId;
    var win = this.chatWindows[id];

    var container = document.createElement('div');
    var title = document.createElement('div');
    var content = document.createElement('div');

    Element.addClassName(container, 'chatItem');
    if (direction == 'in') Element.addClassName(container, 'in');
    else Element.addClassName(container, 'out');
    Element.addClassName(title, 'chatFrom');
    Element.addClassName(content, 'chatContent');

    Element.setStyle(title, { backgroundColor: '#'+message.ipColor });

    container.appendChild(title);
    container.appendChild(content);

    content.innerHTML = message.text;

    var name = direction == 'in' ? '<a href="#" onclick="openProfile('+ message.fromUserId +')">' + message.fromName + '</a>' : '<a href="#" onclick="openProfile('+ message.fromUserId +')">You</a>';
    title.innerHTML = name + ' - ' + message.time;

    win.scroll.nodes.content.appendChild(container);
    win.scroll.scrollToEnd();
  },

  send: function(userId, visitId, textField) {
    if ($F(textField).strip() == '') return;
    new Ajax.Request('/index.php', {
      method: 'post',
      parameters: {m: 'Chat', cmd: 'send', userId: userId, visitId: visitId, message: textField.value},
      onSuccess: (function(transport) {
        textField.value = '';
        textField.focus();
        var message = transport.responseText.evalJSON();
        this.addMessage(message, 'out');
      }).bind(this)
    });
  },

  close: function(userId, visitId) {
    var id = userId + '_' + visitId;
    delete this.chatWindows[id];
    if (settings['openChat'][id] == true) {
      delete settings['openChat'][id];
      saveSettings();
    }
  }
}

pb.comment = {
  commentWindow: null,

  show: function(itemId, callback) {
    new Ajax.Request('/index.php', {
      method: 'get',
      parameters: {m: 'Comment', cmd: 'get', iid: itemId },
      onSuccess: function(transport) {
        var data = transport.responseText.evalJSON();

        var div = $('c_'+itemId);
        div.innerHTML = data.html;
        Element.show(div);
        //$('ct_'+itemId).focus();
        if (callback) callback();
      }
    });
  },

  hide: function(itemId, callback) {
    var div = $('c_'+itemId);
    Element.hide(div);
    if (callback) callback();
  },

  toggle: function(itemId, callback) {
    var div = $('c_'+itemId);
    if (Element.visible(div)) this.hide(itemId, callback);
    else this.show(itemId, callback);
  },

  submit: function(iid, callback) {
    var text = $F('ct_'+iid);
    var div = 'c_'+iid;

    if (text.strip() == '') {
      alert('You need to write something.');
      return;
    }

    new Ajax.Request('/index.php', {
      method: 'post',
      parameters: { m: 'Comment', ct: text, iid: iid },
      onSuccess: function(transport) {
        var data = transport.responseText.evalJSON();
        if (data.count > 0) {
          div = $(div);
          div.innerHTML = data.html;
          Element.show(div);
          //$('ct_'+iid).focus();
          if (callback) callback();
        } else {
          alert('Something went wrong');
        }
      }
    });
  },

  remove: function(id, callback) {
    new Ajax.Request('/index.php', {
      method: 'post',
      parameters: { m: 'Comment', cmd: 'remove', cid: id },
      onSuccess: function(transport) {
        var data = transport.responseText.evalJSON();
        if (data.ok) {
          div = $('c_'+data.iid);
          div.innerHTML = data.html;
          Element.show(div);
          //$('ct_'+iid).focus();
          if (callback) callback();
        }
      }
    });
  },

  showSubmit: function(id) {
    if (!Element.visible(id)) {
      Element.show(id);
    }
    Element.setOpacity(id, 0);
    var fi = new pb.animate.fadein(id);
    fi.start();
  },

  hideSubmit: function(id, fromTimer) {
    if (!!fromTimer) {
      if (Element.visible(id)) {
        Element.setOpacity(id, 1);
        var fo = new pb.animate.fadeout(id);
        fo.start();
      }
    } else {
      setTimeout(function() { pb.comment.hideSubmit(id, 1); }, 1000);
    }
  }
}

pb.sound = {
  volume: 0,

  setVolume: function(vol) {
    if (vol < 0) vol = 0;
    if (vol > 100) vol = 100;
    pb.sound.volume = vol;

    if (pb.sound.volume == 0) Element.addClassName('soundVolume', 'mute');
    else Element.removeClassName('soundVolume', 'mute');
  },

  toggle: function() {
    if (pb.sound.volume > 0) pb.sound.setVolume(0);
    else pb.sound.setVolume(100);
  },

  play: function(sound) {
    if (pb.sound.volume > 0) {
      var file = '/sounds/' + sound + '.mp3';
      pb.sound._play(sound, file);
    }
  },

  customPlay: function(path, id) {
    if (pb.sound.volume > 0) {
      pb.sound._play(path, id);
    }
  },

  _play: function(id, file) {
    var snd = soundManager.createSound({
      id: id,
      url: file,
      volume: pb.sound.volume
    });
    snd.play();
  }
}

function isIE6() {
  return (Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE") + 5)) == 6);
}



function windowTest() {
  var tmp = pb.windowHandler.create('test', 'Test', 'test window <br> is what this is', {
    contentType: 'html',
    left: 0,
    top: 0,
    movable: true,
    forcePosDim: true,
    closable: true,
    minimizable: true,
    corner: 'TL',
    parentCorner: 'MC',
    corners: ['BR','TL'],
    parent: 'viewport',
    keepInside: true
  });
}