function Registry() {}

function Cookies() {
  this.cookies = undefined;
}
Cookies.parse = function() {
  this.cookies = {}
  var cookies = document.cookie.split('; ');
  var cookie;
  for (var i = 0; i < cookies.length; i++) {
    cookie = cookies[i].split('=');
    this.cookies[cookie[0]] = decodeURIComponent(cookie[1]);
  }
}
Cookies.get = function(name) {
  if (this.cookies === undefined) {
    this.parse();
  }
  return this.cookies[name];
}
Cookies.set = function(name, value, days, path) {
  if (path == undefined) {
    path = '/';
  }
  if (this.cookies === undefined) {
    this.parse();
  }
  var expires = '';
  if (days) {
    var date = new Date();
    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
    expires = '; expires=' + date.toGMTString();
  }
  document.cookie = name + '=' + encodeURIComponent(value) + expires + '; path=' + path;
  this.cookies[name] = value;
}

function Decorator() {}
Decorator.make_page_corners = function() {
  this.make_tab_corners($('#page_header'));
  this.make_box_corners($('#page'));
  this.make_date_corners($('.section'));
  this.make_content_corners($('#page'));
}
Decorator.make_box_corners = function(content) {
  content.find('.box_label').corner('top');
  content.find('.box_body').corner('bottom');
  content.find('.no_label_box').corner();
  content.find('.help').corner('7px');
  content.find('.options_toggle').corner('3px');
}
Decorator.make_content_corners = function(content) {
  content.find('.content').corner();
  content.find('.content_header').corner('top');
  content.find('.content_footer').corner('bottom');
  content.find('.nav_button').corner('5px');
  content.find('.normal').corner('5px');
}
Decorator.make_date_corners = function(content) {
  content.find('.date').corner();
}
Decorator.make_tab_corners = function(content) {
  content.find('a.tab').corner('top');
}
Decorator.make_month_boxes_corners = function(content) {
  content.find('.month:nth-child(10) .box_body').corner('bl');
  content.find('.month:nth-child(12) .box_body').corner('br');
}
Decorator.position_popup_window = function(element) {
  var window_offset_top = $(window).scrollTop();
  var offset_top = window_offset_top > 80 ? window_offset_top + 20 : 100;
  element.css('top', offset_top + 'px');
  $('body').append(element);
}

function KeyCode() {}
KeyCode.ESC = 27;
KeyCode.ENTER = 13;

function Widget() {}
Widget.registry = {}
Widget.yield_local = function(callback) {
  callback(this);
}
Widget.yield_ajax = function(widget, url, callback) {
  if (!AjaxController.lock(url)) {
    return;
  }
  $.get(url, function(content) {
    widget.content = $(content);
    widget.yield = Widget.yield_local;
    widget.content.hide();
    $('body').append(widget.content);
    widget.init();
    callback(widget);
    AjaxController.unlock(url);
  });
}
Widget.local = function(widget_class, content, callbacks, url) {
  if (url !== undefined && this.registry[url] !== undefined) {
    return this.registry[url];
  }
  var widget = new widget_class();
  if (this.registry[url] !== undefined) {
    this.registry[url] = widget;
  }
  widget.content = content;
  widget.callbacks = callbacks;
  widget.yield = Widget.yield_local;
  widget.init();
  return widget;
}
Widget.ajax = function(widget_class, url, callbacks) {
  var self = this;
  if (self.registry[url] !== undefined) {
    return self.registry[url];
  }
  self.registry[url] = new widget_class();
  self.registry[url].callbacks = callbacks;
  self.registry[url].yield = function(callback) {
    Widget.yield_ajax(self.registry[url], url, callback);
  }
  return self.registry[url];
}

function TipBox() {}
TipBox.prototype.init = function() {
  this.content.hide();
  $('body').append(this.content);
}
TipBox.prototype.open = function(event) {  
  this.content.css('left', event.pageX - $('body').offset().left);
  this.content.css('top', event.pageY + 20);
  this.content.show();
}
TipBox.prototype.close = function() {
  this.content.hide();
}

function TipBoxController() {}
TipBoxController.init = function() {
  var self = this;
  $('.tip').each(function() {    
    self.bind_tip($(this));
  });  
}
TipBoxController.bind_tip = function(element) {
  var tip_box = Widget.local(TipBox,
    $('<div class="tip_box">' + element.attr('title') + '</div>'));
  element.removeAttr('title');
  element.hover(
    function(event) {      
      tip_box.open(event);
    },
    function() {
      tip_box.close();
    });
}

function PopupBox() {}
PopupBox.prototype.inner_content;
PopupBox.prototype.init = function() {
  var self = this;
  self.inner_content = self.content.find('.popup_content');
  self.content.find('>a').click(function(){
    self.callbacks.close();
    return false;
  });
}
PopupBox.prototype.set_content = function(content) {
  var self = this;
  var new_content = content.clone(true);
  self.inner_content.empty();
  self.inner_content.append(new_content);
  new_content.show();
}
PopupBox.prototype.open = function() {
  Decorator.position_popup_window(this.content);
  this.content.show();
}
PopupBox.prototype.close = function() {
  this.content.hide();
}

function PopupController() {}
PopupController.init = function() {
  var self = this;
  self.box = Widget.local(PopupBox,
    $('<div id="popup_box"><a class="close" href="">zamknij [X]</a><div class="popup_content"></div></div>'),
    {close: function() {self.close();}}
  );
  self.bind_help();
}
PopupController.bind_help = function() {
  var self = this;
  $('a.help').each(function() {
    var help_widget = Widget.ajax(HelpPopup, $(this).attr('href'));
    $(this).click(function() {      
      self.open(help_widget);
      return false;
    });    
    $(this).removeClass('hidden');
  });  
}
PopupController.open = function(widget) {
  this.box.yield(function(box) {
    box.close();
    widget.yield(function(widget) { 
      box.set_content(widget.content);
      box.open();
    });    
  });  
}
PopupController.close = function() {
  this.box.yield(function(box) {
    box.close();
  });  
}

function HelpPopup() {}
HelpPopup.prototype.init = function() {
  Decorator.make_box_corners(this.content);
}

function AjaxProgressBox() {}
AjaxProgressBox.prototype.init = function() {}
AjaxProgressBox.prototype.open = function() {
  Decorator.position_popup_window(this.content);
  this.content.show();
}
AjaxProgressBox.prototype.close = function() {
  this.content.hide();
}

function AddItemForm() {}
AddItemForm.prototype.init = function() {
  this.action = this.content.attr('action');
  this.bind_form();
  this.bind_validation();
  this.bind_close();
  this.bind_submit();
  this.bind_submit_link();
}
AddItemForm.prototype.bind_form = function() {
  this.title_field = this.content.find('.title_field');
  this.submit_link = this.content.find('a.submit');
  this.cancel_link = this.content.find('a.cancel');
}
AddItemForm.prototype.bind_validation = function() {
  var self = this;  
  self.title_field.keyup(function() {
    self.validate();
  });   
  self.title_field.change(function() {
    self.validate();
  });  
}
AddItemForm.prototype.bind_close = function() {
  var self = this;  
  self.content.keyup(function(event) {
    if (event.which == KeyCode.ESC) {
      self.callbacks.cancel(self);
    }
  });
  self.cancel_link.click(function() {
    self.callbacks.cancel(self);
    return false;
  });
}
AddItemForm.prototype.bind_submit = function() {
  var self = this;  
  self.content.submit(function() {
    if (!self.validate()) {
      return false;
    }
    return self.callbacks.submit(self);
  });
}
AddItemForm.prototype.bind_submit_link = function() {
  var self = this;  
  self.submit_link.click(function() {    
    self.content.submit();
    return false;
  });    
}
AddItemForm.prototype.reset = function() {
  this.title_field.val('');
  this.content.find('textarea').val('');
}
AddItemForm.prototype.open = function() {
  this.reset();
  this.validate();
  this.content.show();
  this.title_field.focus();
}
AddItemForm.prototype.close = function() {
  this.content.hide();
}
AddItemForm.prototype.validate = function() {
  var valid = $.trim(this.title_field.val()) != '' ? true : false;
  valid ? this.submit_link.removeClass('inactive') : this.submit_link.addClass('inactive');
  return valid;
}
AddItemForm.prototype.serialize = function() {
  return this.content.serialize();
}

function LoginBox() {}
LoginBox.prototype.init = function() {
  this.form = this.content.find('form');
  this.bind_form_enter_submit();
  this.content.removeClass('hidden');
}
LoginBox.prototype.bind_form_enter_submit = function() {
  var self = this;
  self.form.keyup(function(event) {
    if (event.which == KeyCode.ENTER) {
      self.form.submit();
      return false;
    }
  });
}

function MenuBoxSection() {}
MenuBoxSection.prototype.init = function() {
  this.links_box = this.content.find('ul');
  this.title = this.content.find('.expand');
  this.close();
  this.bind_expand();
}
MenuBoxSection.prototype.bind_expand = function() {
  var self = this;
  self.title.click(function() {
    if (self.opened) {
      self.close();
    } else {
      self.open();
    }
  });
  self.title.css('cursor', 'pointer');
}
MenuBoxSection.prototype.open = function() {
  this.opened = true;
  this.links_box.show();
}
MenuBoxSection.prototype.close = function() {
  this.opened = false;
  this.links_box.hide();
}

function LeftMenuController() {}
LeftMenuController.init = function() {
  this.bind_login_box();
  this.bind_menu_sections();
}
LeftMenuController.bind_login_box = function() {
  Widget.local(LoginBox, $('#logged_in_box'));
}
LeftMenuController.bind_menu_sections = function() {
  $('#country_calendars_box .box_body>ul>li').each(function() {
    if (!$(this).find('a.selected').length > 0) {
      Widget.local(MenuBoxSection, $(this));
    }    
  });
}

function AjaxController() {}
AjaxController.locks = {};
AjaxController.init = function() {
  this.progress_box = Widget.local(AjaxProgressBox,
    $('<div id="ajax_progress">Trwa wysyłanie danych... Jeszcze tylko chwileczkę...</div>'));
  this.bind_start();
  this.bind_stop();
  this.bind_error();  
}
AjaxController.bind_start = function() {
  var self = this;
  $(document).ajaxStart(function() {
    self.progress_box.open();
  });
}
AjaxController.bind_stop = function() {
  var self = this;
  $(document).ajaxStop(function() {
    self.progress_box.close();
  });
}
AjaxController.bind_error = function() {
  var self = this;
  $(document).ajaxError(function(event, request, options) {
    self.unlock(options.url);
    if (request.responseText != '') {
      alert(request.responseText);
    } else {
      alert("Błąd połączenia.\n\nSpróbuj ponownie za chwilę.");
    }
  });
}
AjaxController.lock = function(url) {
  if (this.locks[url] === undefined) {
    this.locks[url] = true;
    return true;
  }
  return false;
}
AjaxController.unlock = function(url) {
  this.locks[url] = undefined;
}

$(function() {  
  LeftMenuController.init();
  TipBoxController.init();
  AjaxController.init();
  PopupController.init();  
  if (typeof CalendarController == 'function') {
    CalendarController.init();
  }    
  if (typeof SignupController == 'function') {
    SignupController.init();
  }  
  if (typeof CommentController == 'function') {
    CommentController.init();
  }
  Decorator.make_page_corners();
});