/// <reference path="jQuery.intellisense.js" />
/// <reference name "MicrosoftAjax.js" assembly="System.Web.Extensions" />

(function($) {

	// Debug
	if ( !$.browser.safari && typeof window.console !== 'undefined' && typeof window.console.log === 'function' )
	{	// Use window.console
		$.log = window.console.log;
	}
	else
	{	// Don't use anything
		$.log = function ( ) { };
	}

  $.fn.ajaxPreloader = function(options) {
  
    var options = $.extend({}, $.fn.ajaxPreloader.defaults, options);
  
    ajaxPreloader = function(preloader, options) {
      this.preloader = preloader;
      this.options = options;
      this.init();
    };
    
    ajaxPreloader.prototype = {
    
      init : function() {
        if (this.preloader) {
          $(this.preloader).hide();
        }      
        if (Sys && Sys.WebForms) {
          Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(Function.createDelegate(this, this.show));
          Sys.WebForms.PageRequestManager.getInstance().add_endRequest(Function.createDelegate(this, this.hide));
        }
        $(this.preloader).ajaxStart(Function.createDelegate(this, this.show));
        $(this.preloader).ajaxStop(Function.createDelegate(this, this.hide));
        $(this.preloader).ajaxError(Function.createDelegate(this, this.hide));
      },
    
      show : function() {
        if (this.preloader) {
          $(this.preloader).show();
          $(this.preloader).removeClass(this.options.inactiveCssClass);
          $(this.preloader).addClass(this.options.activeCssClass);
        }
      },    
      
      hide : function() {
        if (this.preloader) {
          $(this.preloader).hide();
          $(this.preloader).removeClass(this.options.activeCssClass);
          $(this.preloader).addClass(this.options.inactiveCssClass);
        }
      }      
    };
    
    $(this).each(function() {
      new ajaxPreloader(this, options);
    });
	};			
	
	$.fn.ajaxPreloader.defaults = {
    activeCssClass : '',
    inactiveCssClass : ''	
	};

  $.fn.captcha = function(options) {
  
    options = $.extend({}, $.fn.captcha.defaults, options);
  
    captcha = function(image, options) {
      this.image = image;      
      this.imageKey;
      this.options = options;
      this.init();
    };
    
    captcha.prototype = {
      
      init : function() {
        if (this.options.reloadButton) {
          $(this.options.reloadButton).click(Function.createDelegate(this, this.reload));
        }
        this.reload();
      },      
      
      reload : function() {
        this.sendImageRequest();
      },
      
      getImageKey : function() {
        return this.imageKey;
      },
      
	    errorRequestHandler : function(response, result) {
	      $.log('WARN', response.responseText);
	    }, 
	        
      sendImageRequest : function() {
		      params = {request: this.options.generateImageRequest};
	        $.getMSJSON(this.options.serviceUrl, params, 
	                    Function.createDelegate(this, this.imageRequestCallback),
	                    Function.createDelegate(this, this.errorRequestHandler));
      },     
    
      imageRequestCallback : function(data, result) {
        this.imageKey = data;
        if (this.options.keyCodeInput)
        {
          $(this.options.keyCodeInput).val(this.imageKey);
        }
        this.loadImage();
      },
      
      loadImage : function() {
        if (this.image && this.imageKey) {
          this.image.src = String.format(this.options.imageUrlTemplate, this.options.serviceUrl, this.imageKey);
        }
      }
    };
    
    return new captcha($(this).get(0), options);
	};	
		
	$.fn.captcha.defaults = {
    serviceUrl : '',
    generateImageRequest : 'GenerateImage',
    imageUrlTemplate : '{0}?request=GetImage&key={1}',
    keyCodeInput : ''
	};			
	
	
  $.fn.collapsableBlock = function(collapsableArea, controller, controllerText, stateField, options) {
  
    options = $.extend({}, $.fn.collapsableBlock.defaults, options);
    
    $(this).each(function() {
      if (stateField) {
        state = Boolean.parse($(stateField).val());
        if (state) {
          $(collapsableArea, this).show();
          $(this).addClass(options.expandedClass);
          $(controllerText, this).text(options.expandedText);
        }
        else {
          $(collapsableArea, this).hide();
          $(this).removeClass(options.expandedClass);
          $(controllerText, this).text(options.collapsedText);
        }
      }

      $(controller, this).unbind('click').bind('click', {root : this}, function(context) {
        root = context.data.root;
        $($(collapsableArea, root).toggle().parent()).toggleClass(options.expandedClass);
        if (stateField) {
          state = !Boolean.parse($(stateField).val());
          $(stateField).val(state);
          if(state)
          {
            $(controllerText, this).text(options.expandedText);
          }
          else
          {
            $(controllerText, this).text(options.collapsedText);
          }
        }
      });
    });
  };
  
  $.fn.collapsableBlock.defaults = {
    expandedClass : 'expanded',
    expandedText : 'collapse',
    collapsedText : 'expand'
	};
  
  $.fn.mainMenu = function(options) {
  
    options = $.extend({}, $.fn.mainMenu.defaults, options);
  
    mainMenu = function(menuArea, options) {
      this.menuArea = menuArea;
      this.items;
      this.options = options;
      this.init();
    };
    
    mainMenu.prototype = {
      
      init : function() {
        $(this.menuArea).setTemplateURL(this.options.templateUrl, null, {filter_data: false});
        if (typeof Sys != undefined && Sys && Sys.WebForms) {
          Sys.WebForms.PageRequestManager.getInstance().add_endRequest(Function.createDelegate(this, this.update));
        }        
      },      
      
      update : function() {
        this.sendItemsRequest();
      },
      
	    errorRequestHandler : function(response, result) {
	      $.log('WARN', response.responseText);
	    },
	        
      sendItemsRequest : function() {
		      params = {request: this.options.getItemsRequest};
	        $.getMSJSON(this.options.serviceUrl, params, 
	                    Function.createDelegate(this, this.itemsRequestCallback),
	                    Function.createDelegate(this, this.errorRequestHandler));
      },     
    
      itemsRequestCallback : function(data, result) {
        if (data) {
          this.items = data;
          this.buildMenu();
        }
      },
      
      buildMenu : function() {
        $(this.menuArea).processTemplate(this.items);
      }
    };
    
    $(this).each(function() {
      return new mainMenu(this, options);
    });
	};	
		
	$.fn.mainMenu.defaults = {
    serviceUrl : '',
    templateUrl : '',
    getItemsRequest : 'GetMainMenu'
	};			
	
  $.fn.buyButton = function(productID, variantID, options) {
  
    buyProductButton = function(button, productID, variantID, options) {
      this.button = button;
      this.options = options;
      this.productID = productID;
      this.variantID = variantID;
      this.basketContent = null;
      this.init();
    };
    
    buyProductButton.prototype = {
    
      init : function() {
        $(this.button).click(Function.createDelegate(this, this.buttonClickHandler));
      },
      
      errorRequestHandler : function(response, result) {
	      $.log('WARN', response.responseText);
	    },
      
      buttonClickHandler : function() {
        params = {request: this.options.addProductRequest};
        if (this.productID) {
          params.productID = this.productID;
        }
        if (this.variantID) {
          params.variantID = this.variantID;
        }       
        if (this.options.quantityField) {
          params.quantity = $(this.options.quantityField).val();
        }      
        $.getMSJSON(this.options.serviceUrl, params, 
                    Function.createDelegate(this, this.buyCompleteHandler),
                    Function.createDelegate(this, this.errorRequestHandler));
      },
      
      buyCompleteHandler : function(data, result) {
        if (typeof data != undefined) {
          if (data.IsSuccess) {
            this.updateBuyEnable();
            this.updateBasketView();
            this.showSuccessMessage();
            this.getBasketContent();
          }
          else {
            this.showErrorMessage(data.Message);
          } 
        }          
      },
      
      showErrorMessage : function (message) {
        $('form').messageBox(null, {
          messageType: 'Error', 
          top: 10, 
          left: '900px',
          width: 350, 		      
          autoClose: true,
          title: "You've got some errors.",
          modal : false},
          $.generateList, {list: [message]});
      },
            
      showSuccessMessage : function () {
        this.basketContent = $.create('div', {});
        this.basketContent.setTemplateURL(this.options.basketContentTemplate, null, {filter_data: false});
      },      
      
      getBasketContent : function () {
        params = {request: this.options.getDetailedContentRequest};   
                    
        $.getMSJSON(this.options.serviceUrl, params,
                    Function.createDelegate(this, this.getBasketContentSuccess),
                    Function.createDelegate(this, this.errorRequestHandler));
      },
      
      getBasketContentSuccess : function (data, result) {
        if (typeof data != undefined) {
          this.basketContent.processTemplate(data);
          $.scrollTo(0, 0, {speed:1000, onAfter : Function.createDelegate(this, this.scrollCompletedHandler)});
				}
      },
      
      scrollCompletedHandler : function() {
        $('div.Container').messageBox(null, {
          messageType: 'Basket', 
          contentClassName: 'Product', 
          containerClassName: 'PopUpContainer Basket-Updated', 
          title: 'New product has been added',
          top: 110, 
          left: '625px', 
          width: 350, 
          autoClose: true, 
          modal : false, 
          showArrow : true}, 
          this.basketContent);
			},
      
      updateBuyEnable : function() {
        if (this.options.buyEnable) {
          params = {request: this.options.buyEnableRequest};
          if (this.productID) {
            params.productID = this.productID;
          }
          if (this.variantID) {
            params.variantID = this.variantID;
          }
          
          $.getMSJSON(this.options.serviceUrl, params, 
            Function.createDelegate(this, this.updateBuyEnableHandler), 
            Function.createDelegate(this, this.errorRequestHandler));
        }
      },
      
      updateBuyEnableHandler : function(data, result) {
        if (typeof data != undefined) {
          if (this.options.buyEnable && data === false) {
            $(this.options.buyEnable).remove();
          }
        }      
      },
      
      updateBasketView : function() {
        if (this.options.basketView || this.options.basketViewTemplate) {
          basketView = $(this.options.basketView);
          basketView.setTemplateURL(this.options.basketViewTemplate, null, {filter_data: false});
          params = {request: this.options.getContentRequest};   
          
          $.getMSJSON(this.options.serviceUrl, params, function(data, result) {
            if (typeof data != undefined) {
                basketView.processTemplate(data);
            }
          }, Function.createDelegate(this, this.errorRequestHandler));
        }
      }
    };
    
    $(this).each(function() {
      new buyProductButton(this, productID, variantID, $.extend({}, $.fn.buyButton.defaults, options));
    });    
  };
    	
	$.fn.buyButton.defaults = {
    serviceUrl : '',
    getStartedUrl : '',
    quantityField : null,
    getContentRequest : 'GetContent',
    getDetailedContentRequest : 'GetDetailedContent',
    buyEnableRequest : 'BuyEnable',
    addProductRequest : 'AddProduct',
    basketView : '#basketViewArea',
    basketViewTemplate : '',
    basketContentTemplate : '',
    buyEnable : null
	};	
	  
  $.fn.basketView = function(settings) {
  
    basketView = function(basketArea, settings) {
      this.basketArea = basketArea;
      this.settings = settings;
      this.init();
    };
    
    basketView.prototype = {
    
      init : function() {
        $(this.basketArea).setTemplateURL(this.settings.templateUrl, null, {filter_data: false});
        if (typeof Sys != undefined && Sys && Sys.WebForms) {
          Sys.WebForms.PageRequestManager.getInstance().add_endRequest(Function.createDelegate(this, this.update));
        }
        this.initializeGetStartedMessage();         
      },
      
      update : function() {
        params = {request: this.settings.getContentRequest};   

        $.getMSJSON(this.settings.serviceUrl, params, 
                      Function.createDelegate(this, this.updateComplete),
                      Function.createDelegate(this, this.errorRequestHandler));
      },
      
      updateComplete : function(data, result) {  
        if (typeof data != undefined) {
            $(this.basketArea).processTemplate(data);
        }
        this.initializeGetStartedMessage();        
      },
      
      initializeGetStartedMessage : function(){
        $(".basketGetStarted", this.basketArea).bind('click', Function.createDelegate(this, this.getGetStartedMessage));
      },
      
      getGetStartedMessage : function(){
        var content = $.create('div', {});
        content.setTemplateURL(this.settings.getStartedUrl, null, {filter_data: false});
        content.processTemplate();
        $('form').messageBox(null, {
              messageType: 'Notification', 
              top: 10, 
              width: 350,
              autoClose: false,
              title: "How do I get started?",
              modal : false}, 
              content);        
      },
            
      errorRequestHandler : function(response, result) {
	      $.log('WARN', response.responseText);
	    }            
    };
    
    $(this).each(function() {
      new basketView(this, $.extend({}, $.fn.basketView.defaults, settings));
    });
	};			
	
	$.fn.basketView.defaults = {
    serviceUrl : '',
    templateUrl: '',
    getContentRequest : 'GetContent'
	};	
	
})(jQuery);

reviewEditor = function(listing, options) {
  this.reviewID = null;
  this.listing = listing;
  this.options = $.extend({}, reviewEditor.defaults, options);
  this.popup = null;
  this.captcha = null;
  this.content = null;
  this.init();
};
    
reviewEditor.prototype = {

  init : function() {
    options = this.options;
    editor = this;
    listing = this.listing;
    $(String.format('a[rel^={0}]', options.editUrlPrefix), $(this.listing.placeHolder)).each(function() {
      reviewID = this.rel.match(options.editUrlPattern);
      if (reviewID && reviewID.length > 0) {
        reviewID = reviewID[1];
      }
      else {
        reviewID = null;
      }
      $(this).bind('click', {reviewID : reviewID}, function(e) {
        editor.showPopup(e.data.reviewID);
      });
    });
    $(String.format('a[rel^={0}]', options.deleteUrlPrefix), $(this.listing.placeHolder)).each(function() {
      reviewID = this.rel.match(options.deleteUrlPattern);
      if (reviewID && reviewID.length > 0) {
        reviewID = reviewID[1];
      }
      $(this).click(function() {
        if (confirm('Are you sure want to delete your review?')) {
          listing.deleteItem(reviewID);
        }
      });
    });
    if (this.options.addLink) {      
      $(this.options.addLink).unbind('click').click(function() {
        editor.showPopup();
      });      
    }  
  },
      
  errorRequestHandler : function(response, result) {
    $.log('WARN', response.responseText);
  },     

  loadData : function() {
    if (this.reviewID) {
      params = {request: this.options.getByIdRequest, id: this.reviewID};
    }
    else {
      params = {request: this.options.newRequest};
    }
    $.getMSJSON(this.options.serviceUrl, params, 
                Function.createDelegate(this, this.loadDataHandler),
                Function.createDelegate(this, this.errorRequestHandler));
  },

  loadDataHandler : function(data, result) {
    this.content.processTemplate(data);
    this.popup = this.createPopup();

    this.initRatingField();
    this.initCaptcha();
    
    $('#saveReview', this.content).click(Function.createDelegate(this, this.saveData));
    $('#cancelReview', this.content).click(Function.createDelegate(this, this.hidePopup));      
  },
  
  initRatingField : function() {
    $('#ratingField', this.content).numeric();
    $('#ratingField', this.content).upDownField({
      upButton: '#ratingUp', 
      downButton: '#ratingDown'}, {
      minValue: 1,
      maxValue: 5,
      defaultValue : 5
    });      
  },
  
  initCaptcha : function() {
    this.captcha = $('#reviewCaptcha', this.content).captcha({
      serviceUrl: this.options.captchaServiceUrl, 
      reloadButton: $('#reloadCaptcha', this.content)
    });
  },
  
  createPopup : function() {
    if (this.reviewID) {
      title = 'EDIT REVIEW';
    }
    else {
      title = 'ADD REVIEW';
    }      
    return $('form').messageBox(null, {
                    messageType: '',
                    contentClassName: '',
                    title: title,
                    width: 400, 
                    top: 200, 
                    modal: true, 
                    autoClose: false, 
                    innerRound: 0}, this.content);
  },
  
  showPopup : function(reviewID) {
    this.reviewID = reviewID;
    this.content = $.create('div', {});
    this.content.setTemplateURL(this.options.templateUrl, null, {filter_data: false});
    this.loadData();
  },
  
  hidePopup : function() {
    if (this.popup) {
      this.popup.hide();
    }
  },

  saveData : function() {
    params = {
      request : this.options.saveRequest,
      productID : this.options.productId,
      content : Url.encode($('#contentField', this.content).val()),
      rating : $('#ratingField', this.content).val(),
      captchaKey : this.captcha.getImageKey(),
      captchaCode : $('#captchaCode', this.content).val()
    };
    if (this.reviewID) {
      params.id = this.reviewID;
    }
    $.getMSJSON(this.options.serviceUrl, params, 
                Function.createDelegate(this, this.saveDataHandler),
                Function.createDelegate(this, this.errorRequestHandler));  
  },

  saveDataHandler : function(data, result) {
    if (data) {
      if (data.IsValid) {
        this.hidePopup();
        this.listing.retrieveData();
        $('form').messageBox(null, {
          messageType: 'Notification', 
          title: 'Success',
          width: 350, 
          top: 10, 
          modal: false, 
          autoClose: true}, 
          '<div class="SysInfo"><p>Your review has been saved successfully.</p></div>');
      }
      else {
		    $('form').messageBox(null, {
		      messageType: 'Error', 
		      top: 10, 
		      title: "You've got some errors.",
		      width: 350, 		      
		      autoClose: true,
		      modal : false}, 
          $.generateList, {list: data.ErrorMessages});
        this.captcha.reload();
      }
    }
  }      
};

reviewEditor.defaults = {
  productId : null,
  serviceUrl : '',
  templateUrl : '',
  editUrlPattern : /edit_review_(\d+)/,
  editUrlPrefix : 'edit_review_',
  deleteUrlPattern : /delete_review_(\d+)/,
  deleteUrlPrefix : 'delete_review_',  
  captchaServiceUrl : '',
  getByIdRequest : 'GetById',
  newRequest : 'New',
  saveRequest : 'Save'
};

addReviewControl = function(addReviewArea, alternativeArea, options) {
  this.addReviewArea = addReviewArea;
  this.alternativeArea = alternativeArea;
  this.options = $.extend({}, addReviewControl.defaults, options);
  this.init();
};

addReviewControl.prototype = {
  
  init : function() {
    this.switchAreas();
    if (Sys && Sys.WebForms) {
      Sys.WebForms.PageRequestManager.getInstance().add_endRequest(Function.createDelegate(this, this.switchAreas));
    }  
  },

  switchAreas : function() {
    params = {request: this.options.availabilityRequest};
    $.getMSJSON(this.options.serviceUrl, params, 
                Function.createDelegate(this, this.availabilityRequestHandler),
                Function.createDelegate(this, this.errorRequestHandler));        
  },  
      
  errorRequestHandler : function(response, result) {
    $.log('WARN', response.responseText);
  },

  availabilityRequestHandler : function(response, result) {
    if (response && response === true) {
      $(this.addReviewArea).show();
      $(this.alternativeArea).hide();
    }
    else {
      $(this.addReviewArea).hide();
      $(this.alternativeArea).show();    
    }
  }
};

addReviewControl.defaults = {
  serviceUrl : '',
  availabilityRequest : 'IsReviewAvailable'
};

buyProduct = function(productID, variantID, options) {
  this.options = $.extend({}, buyProduct.defaults, options);
  this.productID = productID;
  this.variantID = variantID;
  this.basketContent = null;
  this.buy();
};
    
buyProduct.prototype = {
  
  errorRequestHandler : function(response, result) {
    $.log('WARN', response.responseText);
  },
  
  buy : function() {
    params = {request: this.options.addProductRequest, quantity: this.options.quantity};
    if (this.productID) {
      params.productID = this.productID;
    }
    if (this.variantID) {
      params.variantID = this.variantID;
    }       

    $.getMSJSON(this.options.serviceUrl, params, 
                Function.createDelegate(this, this.buyCompleteHandler),
                Function.createDelegate(this, this.errorRequestHandler));
  },
  
  buyCompleteHandler : function(data, result) {
    if (typeof data != undefined) {
      if (data.IsSuccess) {
        this.updateBuyEnable();
        this.updateBasketView();
        this.showSuccessMessage();
        this.getBasketContent();
      }
      else {
        this.showErrorMessage(data.Message);
      } 
    }          
  },
  
  showErrorMessage : function (message) {
    $('form').messageBox(null, {
      messageType: 'Error', 
      top: 10,
      title: "You've got some errors.",
      left: '900px',
      width: 350, 		      
      autoClose: true,
      modal : false}, 
      $.generateList, {list: [message]});
  },
        
  showSuccessMessage : function () {
    this.basketContent = $.create('div', {});
    this.basketContent.setTemplateURL(this.options.basketContentTemplate, null, {filter_data: false});
  },      
  
  getBasketContent : function () {
    params = {request: this.options.getDetailedContentRequest};   
                
    $.getMSJSON(this.options.serviceUrl, params,
                Function.createDelegate(this, this.getBasketContentSuccess),
                Function.createDelegate(this, this.errorRequestHandler));
  },
  
  getBasketContentSuccess : function (data, result) {
    if (typeof data != undefined) {
      this.basketContent.processTemplate(data);
      $.scrollTo(0, 0, {speed:1000, onAfter : Function.createDelegate(this, this.scrollCompletedHandler)});
		}
  },
      
  scrollCompletedHandler : function() {
    $('div.Container').messageBox(null, {
      messageType: 'Basket', 
      contentClassName: 'Product', 
      containerClassName: 'PopUpContainer Basket-Updated', 
      title: 'New product has been added',
      top: 110, 
      left: '625px', 
      width: 350, 
      autoClose: true, 
      modal : false, 
      showArrow : true}, 
      this.basketContent);
	},
  
  updateBuyEnable : function() {
    if (this.options.buyEnable) {
      selectorToUpdate = this.options.buyEnable;
      params = {request: this.options.buyEnableRequest};
      if (this.productID) {
        params.productID = this.productID;
      }
      if (this.variantID) {
        params.variantID = this.variantID;
      }
      
      $.getMSJSON(this.options.serviceUrl, params, function(data, result) {  
        if (typeof data != undefined && data === false) {
          $(selectorToUpdate).each(function() {
            $(this).remove();
          });
        }
      }, Function.createDelegate(this, this.errorRequestHandler));
    }
  },
  
  updateBasketView : function() {
    if (this.options.basketView || this.options.basketViewTemplate) {
      basketView = $(this.options.basketView);
      basketView.setTemplateURL(this.options.basketViewTemplate, null, {filter_data: false});
      params = {request: this.options.getContentRequest};   
      
      $.getMSJSON(this.options.serviceUrl, params, function(data, result) {
        if (typeof data != undefined) {
            basketView.processTemplate(data);
        }
      }, Function.createDelegate(this, this.errorRequestHandler));
    }
  }
};
  	
buyProduct.defaults = {
  serviceUrl : '',
  quantity : 1,
  getContentRequest : 'GetContent',
  getDetailedContentRequest : 'GetDetailedContent',
  getOrderItemRequest : 'GetOrderItem',
  buyEnableRequest : 'BuyEnable',
  addProductRequest : 'AddProduct',
  basketView : '#basketViewArea',
  basketViewTemplate : '',
  basketContentTemplate : '',
  buyEnable : null
};

function setFocus(input) {
  $(input).each(function() {
    this.focus();
    this.select();
  });
}

function setStartPage(element, url)
{

  if (document.all)
  {
    element.style.behavior='url(#default#homepage)';
    element.setHomePage(url);

  }
  else
    if(!document.layers)
    {
      netscape.security.PrivilegeManager.enablePrivilege("UniversalPreferencesWrite");
      navigator.preference("browser.startup.homepage", url); 
    }
}

function addBookmark()
{
  var url = location.href;
  var title = document.title;

  //Gecko
  if ((typeof window.sidebar == "object") && (typeof window.sidebar.addPanel == "function")) 
  {
    window.sidebar.addPanel (title, url, "");
  }
  //IE4+
  else 
  {
    if (typeof window.external == "object") 
    { 
      window.external.AddFavorite(url, title);
    }
    else 
    {
      if (window.opera && document.createElement)
      {
        var a = document.createElement('A');
        if (!a) return false; //IF Opera 6
        a.setAttribute('rel','sidebar');
        a.setAttribute('href',url);
        a.setAttribute('title',title);
        a.click();
      }
      else 
      {
        return false;
      }
    }
  }
  //Opera7+

  return true;
}

function  treeExpand(namingPrefix, id_item)
{    
    var e = document.getElementById(namingPrefix + 'r_' + id_item);
    var state = document.getElementById(namingPrefix + 'node_state_' + id_item);
    var anc = document.getElementById(namingPrefix + 'a_' + id_item);
    if (e != null) {
        if (e.style.display != 'block') {
            e.style.display = 'block';
            if (anc != null) {            
              anc.src = anc.src.replace('plus', 'minus');
            }
            if (state != null) {
              state.value = '1';
            }
        } else {
            e.style.display = 'none';
            if (anc != null) {            
              anc.src = anc.src.replace('minus', 'plus');
            }
            if (state != null) {
              state.value = '0';
            }
        }
    }
}

(function($) {

  forgotPassword = function(button, options) {
    this.button = button;
    this.content = null;
    this.popup = null;
    this.options = $.extend({}, this.defaults, options)
    this.init();
  };
    
  forgotPassword.prototype = {
    init : function() {
      $(this.button).click(Function.createDelegate(this, this.showForgotPasswordPopup));
    },
    
    
    showForgotPasswordPopup : function() {
      if(!this.content)
      {
        this.createContent();
      }
      //for some reason this handler should be added each time we create the popup
      $('#sendLogin', this.content).click(Function.createDelegate(this, this.sendPasswordClickHandler));
      this.popup = this.createForgotPasswordPopup();
      
    },
    
    createForgotPasswordPopup : function() {
      return $('form').messageBox(null, {
                      messageType: '',
                      contentClassName: '',
                      title: 'FORGOT PASSWORD',
                      width: 400, 
                      top: 200, 
                      modal: true, 
                      autoClose: false, 
                      innerRound: 0}, this.content);
    },

    createContent : function() {
      this.content = $.create('div', {});
      this.content.setTemplateURL(this.options.templateUrl, null, {filter_data: false});
      this.content.processTemplate(null);
    },
    
    sendPasswordClickHandler : function() {
      var loginText = $('#login', this.content);
      params = {request: this.options.forgotPasswordRequest, login : loginText.val()};

      $.getMSJSON(this.options.serviceUrl, params, 
                  Function.createDelegate(this, this.requestCompleteHandler),
                  Function.createDelegate(this, this.requestErrorHandler));
    },
    
    requestCompleteHandler : function(data, result) {
      if (typeof data != undefined) {
        if (data.IsSuccess) {
          this.showSuccessMessage();
        }
        else {
          this.showErrorMessage(data.Message);
        }
      }
    },
    
    requestErrorHandler : function(response, result) {
      $.log('WARN', response.responseText);
    },
    
    showErrorMessage : function (message) {
      $('form').messageBox(null, {
        messageType: 'Error', 
        top: 10, 
        width: 350,
        autoClose: true,
        title: "You've got some errors.",
        modal : false}, 
        $.generateList, {list: [message]});
    },
    
    showSuccessMessage : function () {
      $('form').messageBox(null, {
        messageType: 'Notification',
        title: 'Success',
        top: 10,
        width: 350,
        autoClose: true,
        modal : false}, 
        this.options.successHtml);
    },
    
    defaults : {
      serviceUrl : '',
      forgotPasswordRequest : 'ForgotPassword',
      templateUrl : '',
      successHtml : '<div class="SysInfo"><p>Your password has been sent to your email.</p></div>'
    }
  };

  $.fn.forgotPassword = function(options) {
    $(this).each(function() {
      new forgotPassword(this, options);
    });    
  };

})(jQuery);

(function($) {

  sendLinkToFriend = function(button, productID, variantID, options) {
    this.button = button;
    this.content = null;
    this.popup = null;
    this.captcha = null;
    this.productID = productID;
    this.variantID = variantID;
    this.options = $.extend({}, this.defaults, options)
    this.init();
  };
    
  sendLinkToFriend.prototype = {
    init : function() {
      $(this.button).click(Function.createDelegate(this, this.showSendLinkPopup));
    },
    
    
    showSendLinkPopup : function() {
      if(!this.content)
      {
        this.createContent();
      }
      
      //for some reason all handlers should be added each time we create the popup, 
      //and as some handlers are added for the captcha (reload image) (in initCaptcha), it should be initialized again.
      this.initCaptcha();
      $('#sendLink', this.content).click(Function.createDelegate(this, this.sendLinkClickHandler));
      this.popup = this.createSendLinkPopup();
    },
    
    hideSendLinkPopup : function() {
      if (this.popup) {
        this.popup.hide();
      }
    },
    
    createSendLinkPopup : function() {
      return $('form').messageBox(null, {
                      messageType: '',
                      contentClassName: '',
                      title: 'SEND LINK',
                      width: 400, 
                      top: 200, 
                      modal: true, 
                      autoClose: false, 
                      innerRound: 0}, this.content);
    },

    createContent : function() {
      this.content = $.create('div', {});
      this.content.setTemplateURL(this.options.templateUrl, null, {filter_data: false});
      this.content.processTemplate(null);
    },
    
    initCaptcha : function() {
      this.captcha = $('#sendLinkCaptcha', this.content).captcha({
        serviceUrl: this.options.captchaServiceUrl, 
        reloadButton: $('#reloadCaptcha', this.content)
      });
    },
    
    sendLinkClickHandler : function() {
      params = {
        request: this.options.sendLinkRequest,

        captchaCode : $('#captchaCode', this.content).val(),
        captchaKey : this.captcha.getImageKey(),
        friendMail : $('#friendMail', this.content).val(),
        friendName : $('#friendName', this.content).val(),
        userMessage : $('#userMessage', this.content).val(),
        userName : $('#userName', this.content).val(),

        productID : this.productID,
        variantID : this.variantID
      };

      $.getMSJSON(this.options.serviceUrl, params, 
                  Function.createDelegate(this, this.requestCompleteHandler),
                  Function.createDelegate(this, this.requestErrorHandler));
    },
    
    requestCompleteHandler : function(data, result) {
      if (typeof data != undefined) {
        if (data.IsValid) {
          this.showSuccessMessage();
          this.hideSendLinkPopup();
        }
        else {
          this.showErrorMessage(data);
        }
      }
    },
    
    requestErrorHandler : function(response, result) {
      $.log('WARN', response.responseText);
    },
    
    showErrorMessage : function (data) {
    
      this.captcha.reload();
    
      $('form').messageBox(null, {
        messageType: 'Error', 
        top: 10, 
        width: 350,
        autoClose: true,
        title: "You've got some errors.",
        modal : false}, 
        $.generateList, {list: data.ErrorMessages});
    },
    
    showSuccessMessage : function () {
    
      //this.captcha.reload(); instead we hide the initial popup in requestCompleteHandler
    
      $('form').messageBox(null, {
        messageType: 'Success',
        title: 'Success',
        top: 10,
        width: 350,
        autoClose: true,
        modal : false}, 
        this.options.successHtml);
    },
    
    defaults : {
      serviceUrl : '',
      sendLinkRequest : 'sendLink',
      templateUrl : '',
      captchaServiceUrl : '',
      successHtml : '<div class="SysInfo"><p>A message has been sent to your friend\'s email.</p></div>'
    }
  };

  $.fn.sendLinkToFriend = function(productID, variantID, options) {
    $(this).each(function() {
      new sendLinkToFriend(this, productID, variantID, options);
    });    
  };

})(jQuery);﻿/// <reference path="interface.js" />
/// <reference name "MicrosoftAjax.js" assembly="System.Web.Extensions" />

Type.registerNamespace('Core.Web');

Core.Web.fillInput = function(inputID, newValue) { 
  inputElement = $get(inputID);
  if (inputElement) {
    inputElement.value = newValue; 
  }
}

Type.registerNamespace('Core.Web.DashBoard');

Core.Web.DashBoard.HideLink = function(hidePanelID, hideLinkID, hideImageID, imagePath, readCookie){
    
    this.hidePanelID = hidePanelID;
    
    this.hidePanel = $get(hidePanelID);
    
    this.hideLinkID = hideLinkID;
    
    this.hideLink = $get(hideLinkID);
    
    this.hideImageID = hideImageID;
    
    this.hideImage = $get(hideImageID);
    
    this.imagePath = imagePath;
    
    this.showHide(true);
}

Core.Web.DashBoard.HideLink.visible = 'block';

Core.Web.DashBoard.HideLink.invisible = 'none';

Core.Web.DashBoard.HideLink.showText = 'Show these hints';

Core.Web.DashBoard.HideLink.hideText = 'Hide these hints';

Core.Web.DashBoard.HideLink.showIconName = 'show.gif';

Core.Web.DashBoard.HideLink.hideIconName = 'hide.gif';

Core.Web.DashBoard.HideLink.prototype = {

  showHide : function(readCookie) {
    if(readCookie) {
      cookieValue = getCookie(this.hidePanelID);
      if(cookieValue != null) {
        if(cookieValue == Core.Web.DashBoard.HideLink.invisible) {
          this.setShowButton();
        }
        else {
          this.setHideButton();
        }
      }
      else {
        this.setHideButton();
      }
    }
    else {
      if(this.hidePanel != null) {
        if(this.hidePanel.style.display == Core.Web.DashBoard.HideLink.invisible) {
          this.setHideButton();
        }
        else {          
          this.setShowButton();
        }
      }
    }
  }, 
   
  setShowButton : function() {
    this.setBlockDetails(Core.Web.DashBoard.HideLink.invisible, 
                          Core.Web.DashBoard.HideLink.showText, 
                          this.imagePath + Core.Web.DashBoard.HideLink.showIconName);
  },  

  setHideButton : function() {
    this.setBlockDetails(Core.Web.DashBoard.HideLink.visible, 
                          Core.Web.DashBoard.HideLink.hideText, 
                          this.imagePath + Core.Web.DashBoard.HideLink.hideIconName);
  },

  setBlockDetails : function(hidePanelDisplay, hideText, imageSrc) {
       this.hidePanel.style.display = hidePanelDisplay;
       this.hideLink.innerHTML = hideText;
       this.hideImage.src = imageSrc;
       this.hideImage.alt = hideText;
       time = new Date();
       time.setTime(new Date().getTime() + 30*24*60*60*1000);
       setCookie(this.hidePanelID, hidePanelDisplay , time, '/', null, null);
  } 
}

Core.Web.DashBoard.HideLink.registerClass('Core.Web.DashBoard.HideLink');

Core.Web.setFieldValue = function(fieldID, newValue) {
  fieldElement = $get(fieldID);
  if (fieldElement) {
    fieldElement.value = newValue;
  }
}

var savedValues = {};

Core.Web.clearField = function() {
  savedValues[this.id] = this.value;
  this.value = '';
}

Core.Web.restoreField = function() {
  if (this.value == '' && savedValues[this.id]) {
    this.value = savedValues[this.id];
  }
}

Core.Web.addClearOnFocus = function(fieldID) {
  fieldElement = $get(fieldID);
  if (fieldElement) {
    $addHandler(fieldElement, 'focus', Function.createDelegate(fieldElement, Core.Web.clearField));
    $addHandler(fieldElement, 'blur', Function.createDelegate(fieldElement, Core.Web.restoreField));
  }
}

Core.Web.showBasketPopup = function(basketPopupID) {
  new Effect.ScrollTo(basketPopupID, {duration: 1.0});
  if (Effect) {
    new Effect.Opacity(basketPopupID, { from: 0, to: 1, duration: 1.0 }); 
  }   
}

Core.Web.hideBasketPopup = function(basketPopupID) {
  if (Effect) {
    new Effect.Opacity(basketPopupID, { from: 1, to: 0, duration: 2.0  }); 
  }
  basketPopup = $get(basketPopupID);
  if (basketPopup) {
    window.setTimeout( function() {basketPopup.style.display = 'none';}, 2000);
  }  
}

Core.Web.SwitchTextMode = function(textAreaID, wysiwygID, isPlainText)
{
  if (isPlainText)
  {
    //new Effect.Appear(textAreaID);
    //new Effect.Fade(wysiwygID);
    $('#' + textAreaID).show();
    $('#' + wysiwygID).hide();
  }
  else
  {
    //new Effect.Fade(textAreaID);
    //new Effect.Appear(wysiwygID);
    $('#' + textAreaID).hide();
    $('#' + wysiwygID).show();
  }
};﻿/// <reference path="jcore.js" />

(function($) {
			
	  $.fn.upDownField = function(elements, options) {
	    var options = $.extend({}, $.fn.upDownField.defaults, options);
		    
	    upDownField = function(field, elements, options) {
	      this.options = options;

        this.field = field;
        this.upButton = elements.upButton;        
	      this.downButton = elements.downButton;        
	      
	      this.init();		      
	    }
	    
		  upDownField.prototype = {
			
		    init : function() {
		      if (this.field && $(this.field).val() == '') {
		        $(this.field).val(this.options.defaultValue);
		      }

          this.bindButtons();			                
		    },
			  
		    getValue : function() {
		      fieldValue = $(this.field).val();
		      if (fieldValue) {
		        return parseInt($(this.field).val());
		      }
		      else {
		        return 1;
		      }
		    },
			  
		    bindButtons : function() {
          $(this.upButton).bind('click', Function.createDelegate(this, this.upButtonHandler));
          $(this.downButton).bind('click', Function.createDelegate(this, this.downButtonHandler));
		    },
			  	  			  
		    upButtonHandler : function() {
		      if (this.field) {		   
            currentValue = this.getValue();
            if (currentValue < this.options.minValue) {
              currentValue = this.options.minValue - 1;
            }
            if (currentValue < this.options.maxValue) {
              $(this.field).val(currentValue + 1);
            }
          }
		    },			  
			  		  
		    downButtonHandler : function() {
		      if (this.field) {		    
            currentValue = this.getValue();
            if (currentValue > this.options.maxValue) {
              currentValue = this.options.maxValue + 1;
            }            
            if (currentValue > this.options.minValue) {
              $(this.field).val(currentValue - 1);
            }
          }
        }
		  };
		    
	    $(this).each(function() {											
        return new upDownField(this, elements, options);
      });
		};			
		    
    $.fn.upDownField.defaults = {
      defaultValue : 1, 
      minValue : 1, 
      maxValue : 100, 
      step: 1
    };				
	
})(jQuery);﻿(function($) {
			
	  $.fn.galery = function(elements, options) {
	    var options = $.extend({}, $.fn.galery.defaults, options);
		    
	    imageGalery = function(imagesArea, elements, options) {
	      this.options = options;
	      this.links = new Array();
	      this.imagesArea = imagesArea;	  

        this.prevButton = elements.prevButton;
	      this.nextButton = elements.nextButton;
	      this.indicator = elements.indicator;
        this.zoomLink = elements.zoomLink;
        this.titleDisplay = elements.titleDisplay;
                  
	      this.position = options.startPosition;    
	      
	      this.prevDelegate = Function.createDelegate(this, this.goPrev);      
	      this.nextDelegate = Function.createDelegate(this, this.goNext);      
	      
	      this.init();		      
	    }
	    
		  imageGalery.prototype = {
			
		    init : function() {
          this.bindButtons();			      
          if (this.imagesArea) {
            this.collectLinks(this.imagesArea, this.links);
		      }
		      if (this.zoomLink) {
		        $(this.zoomLink).bind('click', Function.createDelegate(this, this.zoomCurrent));
		      }
		      this.updateIndicator();
		      this.updateTitle();
          this.updateIcons();
		    },
			  
		    getCount : function() {
		      if (this.links) {
		        return this.links.length;
		      }
		      else {
		        return 0;
		      }
		    },
			  
		    bindButtons : function() {
          this.bindPrevEvent();
          this.bindNextEvent();
		    },
			  
		    unbindButtons : function() {
          this.unbindPrevEvent();
          this.unbindNextEvent();
		    },
			  			  
		    bindPrevEvent : function() {
		      if (this.prevButton) {
		        $(this.prevButton).bind('click', this.prevDelegate);
		      }
		    },			  
			  
		    unbindPrevEvent : function() {
		      if (this.prevButton) {
		        $(this.prevButton).unbind('click', this.prevDelegate);
		      }
		    },		  
			  
		    bindNextEvent : function() {
		      if (this.nextButton) {
		        $(this.nextButton).bind('click', this.nextDelegate);
		      }			  
		    },
			  
		    unbindNextEvent : function() {
		      if (this.nextButton) {
		        $(this.nextButton).unbind('click', this.nextDelegate);
		      }
		    },			  
			  			  
		    collectLinks : function(node, links) {
		      if (node) {
		        if (node.tagName == 'A') {
		          links[links.length] = node;
		        }
		        else {
		          galery = this;
		          $(node).children().each(function() {
		            galery.collectLinks(this, links);
		          });
		        }
		      }
		    },
				  			
		    goPrev : function() {
		      this.unbindButtons();
		      if (this.position > 1) {
		        this.position--;
		        this.updateIndicator();
		        this.updateTitle();
            this.updateIcons();
		      }
		      $(this).oneTime(this.options.speed, this.options.blockButtonsTimerLabel, Function.createDelegate(this, this.bindButtons)); 
		    },		
			  
		    goNext : function() {
		      this.unbindButtons();
		      if (this.position < this.getCount()) {
		        this.position++;
		        this.updateIndicator();
		        this.updateTitle();
	          this.updateIcons();
		      }
		      $(this).oneTime(this.options.speed, this.options.blockButtonsTimerLabel, Function.createDelegate(this, this.bindButtons)); 
		    },

		    updateIndicator : function() {
		      if (this.indicator) {
		        $(this.indicator).html(this.position + '/' + this.getCount());
		      }
		    },
		    
		    updateTitle : function() {
          if (this.titleDisplay && this.links.length >= this.position) {
            $(this.titleDisplay).html(String.shrink(this.links[this.position - 1].title, 20));
          }
		    },
			  
		    zoomCurrent : function() {
		      if (this.links && this.links.length >= this.position) {
		        $(this.links[this.position - 1]).click();
		      }
		    },
		    
		    updateNextIcon : function() {
		      if (this.position < this.getCount()) {
		        $(this.nextButton).attr({'src' : this.options.nextIcon});
		      }
		      else {
		        $(this.nextButton).attr({'src' : this.options.nextDisabledIcon});
		      }
		    },
		    		    
		    updatePrevIcon : function() {
		      if (this.position > 1) {
		        $(this.prevButton).attr({'src' : this.options.prevIcon});
		      }
		      else {
		        $(this.prevButton).attr({'src' : this.options.prevDisabledIcon});
		      }
		    },
		    
		    updateIcons : function() {
		      this.updatePrevIcon();
		      this.updateNextIcon();
		    }
		  };
		    
	    $(this).each(function() {											
        return new imageGalery(this, elements, options);
      });
		};	
				    
    $.fn.galery.defaults = {
      startPosition : 1, 
      blockButtonsTimerLabel: 'blockButtons',
      speed: 500,
      nextIcon: 'next.gif',
      nextDisabledIcon: 'next-dis.gif',
      prevIcon: 'prev.gif',
      prevDisabledIcon: 'prev-dis.gif'
    };				
	
})(jQuery);function unhighlightElement(element) {
  if (element && element.parentNode) {
    $(element.parentNode).removeClassName('inputs-line-selected');
  }
}

function highlightElement(element) {
  if (element && element.parentNode) {
    $(element.parentNode).addClassName('inputs-line-selected');
  }
}

function highlightWrapper(wrapperID) {
  wrapperElement = $(wrapperID);
  if (wrapperElement) {
    wrapperElement.addClassName('inputs-line-selected');
  }
}

function unhighlightWrapper(wrapperID) {
  wrapperElement = $(wrapperID);
  if (wrapperElement) {
    wrapperElement.removeClassName('inputs-line-selected');
  }
}

function hideHighlight(element)
{
  unhighlightElement(element);
  if (element.childNodes != null) {
    for (var i = 0; i < element.childNodes.length; i++) {
      hideHighlight(element.childNodes[i]);
    }
  }
}

function addFCKOnFocusEvent(textAreaId, containerID, wrapperID)
{
  window.setTimeout(function() {
    try {
      if (FCKeditorAPI != null)
      {  
        var editorInstance = FCKeditorAPI.GetInstance(textAreaId) ; 
        if (editorInstance != null) {
          editorInstance.Events.AttachEvent( 'OnFocus', function() { highlightWrapper(wrapperID); } ) ;
          editorInstance.Events.AttachEvent( 'OnBlur', function() { unhighlightWrapper(wrapperID); } ) ;
        }
      }          
    }
    catch (exc) {
      textAreaElement = document.getElementById(textAreaId);
      if (textAreaElement != null) {
        textAreaElement.onfocus = function () {highlight(textAreaElement)};
      }
    }
  }, 1000);
};/**
  *  Extends javascript basic objects (Function, String, Boolean).
  *
  *  Copyright (c) 2008 Roman Zaharenkov
  *  Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
  *  and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
  */
	
/**	
  * 	Replaces each format item in a specified String with the text equivalent of a corresponding object's value.
  * 	
  * 	Paramaters:
  *		  template - A composite format string.
  *	    args - An Object array containing zero or more objects to format. 
  *
  *   Examples:
  *		  String.format('Format {0} example with {1} arguments.', 'string', 2); => 'Format string example with 2 arguments.'
  */	
String.format = function(template, args) {

	result = arguments[0];
	
	for (i = 1; i < arguments.length; i++) {      
		result = result.replace(new RegExp('\\{' + (i - 1) + '\\}', 'gm'), arguments[i]);
	}

	return result;
};

/**	
  * 	Shring string if it's length > maxLength.
  * 	
  * 	Paramaters:
  *		  maxLength - maximum length of output string.
  *	    endWith - end of string (if it's length exceed maxLength). '...' - default.
  *
  *   Examples:
  *		  String.shrink('Lorem ipsum dolor sit amet, consectetuer volutpat.', 10); => 'Lorem ipsu...'
  *		  String.shrink('Lorem ipsum dolor sit amet, consectetuer volutpat.', 10, '...the end); => 'Lorem ipsu...the end'
  */	
String.shrink = function(inputString, maxLength, endWith) {

  if (!endWith) {
    endWith = '...';
  }

  if (inputString.length <= maxLength) {
    return inputString;
  }
  else {
    return inputString.substring(0, maxLength - 1) + endWith;
  }
};

/**	
  * 	Replaces each format item in a specified String with the text equivalent of a corresponding object's value.
  * 	
  * 	Paramaters:
  *		  template - A composite format string.
  *	    args - An Object array containing zero or more objects to format. 
  *
  *   Examples:
  *		  'Format {0} example with {1} arguments.'.format('string', 2); => 'Format string example with 2 arguments.'
  */	
String.prototype.format = function(args) {

	result = this;
	
	for (i = 0; i < arguments.length; i++) {      
		result = result.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
	}

	return result;
};

/**	
  * 	Shring string if it's length > maxLength.
  * 	
  * 	Paramaters:
  *		  maxLength - maximum length of output string.
  *	    endWith - end of string (if it's length exceed maxLength). '...' - default.
  *
  *   Examples:
  *		  'Lorem ipsum dolor sit amet, consectetuer volutpat.'.shrink(10); => 'Lorem ipsu...'
  *		  'Lorem ipsum dolor sit amet, consectetuer volutpat.'.shrink(10, '...the end); => 'Lorem ipsu...the end'
  */	
String.prototype.shrink = function(maxLength, endWith) {

  if (!endWith) {
    endWith = '...';
  }

  if (this.length <= maxLength) {
    return this;
  }
  else {
    return this.substring(0, maxLength - 1) + endWith;
  }
};

/**	
  *  	CSharp like string builder. This class represents a string-like object whose value is a mutable sequence of characters.
  *	  
  *	  Examples:
  *		  style = new StringBuilder();
  *		  style.appendFormat('width:{0}px;', 100);				
  *		  style.appendFormat('margin-left:-{0}px;', '20');
  *		  style.appendFormat('top:{0}px;', 10 / 2);
  *		  style.appendFormat('left:{0};', '50%');
  *		  return style.toString(); => 'width:100px;margin-left:20px;top:5px;left:50%;'
  */
StringBuilder = function(value) {
	this.strings = new Array();
	this.append(value);
};

StringBuilder.prototype = {
	
	/**
	*   Appends the string representation of a specified object to the end of this instance.
	* 	
	*   Paramaters:
	*		  value - The object to append. 
	*/	
	append : function (value) {
		if (value) { 
			this.strings.push(value); 
		}
	},	
	
	/**
	*	Appends a formatted string, which contains zero or more format specifications, to this instance. Each format specification is replaced by the string representation of a corresponding object argument.
	* 	
	* Paramaters:
	*		template - A composite format string.
	*	  args - An Object array containing zero or more objects to format. 
	*/
	appendFormat : function (template, args) {
		this.append(String.format(arguments));
	},

	/**
	*	Clears the instance.
	*/
	clear : function () {
		this.strings.length = 0;
	},
	
	/**
	*	 Converts the value of a StringBuilder to a String.
	*/
	toString : function () {
		return this.strings.join('');
	}
};

/**
  *  Creates function delegate.
  *   
	* Paramaters:
	*		instance - Instance for using as 'this'.
	*	  instanceMethod - Method for calling.
  *   
	* Examples:
	*		$('a').bind('click', Function.createDelegate(this, this.clickHandler));
  */		
Function.createDelegate = function(instance, instanceMethod) {
	return function() {
		instanceMethod.apply(instance, arguments);
	}
};

/**
  *  Creates function callback.
  *   
	* Paramaters:
	*		instance - Instance for using as 'this'.
	*	  context - Method for calling.
  *   
	* Examples:
	*		$('a').bind('click', Function.createDelegate(this, this.clickHandler));
  */	
Function.createCallback = function(instanceMethod, context) {
	return function() {
		var argcount = arguments.length;
		if (argcount > 0) {
			var args = new Array(argcount + 1);
			for (var i = 0; i < argcount; i++) {
				args[i] = arguments[i];
			}
			args[argcount] = context;
			return instanceMethod.apply(this, args);
		}
		return instanceMethod.call(this, context);	
	}
};

/**
  *  Parses boolean value from it's string representation.
  *   
	* Paramaters:
	*		stringValue - string representation of boolean value.
  *   
	* Examples:
	*		Boolean.parse('true') => true
	*		Boolean.parse('false') => false
	*		Boolean.parse('True') => true
	*		Boolean.parse('False') => false	
  */	
Boolean.parse = function(stringValue) {
  return stringValue && stringValue.toLowerCase() == 'true';
};

/*
 * Date Format 1.2.2
 * (c) 2007-2008 Steven Levithan <stevenlevithan.com>
 * MIT license
 * Includes enhancements by Scott Trenda <scott.trenda.net> and Kris Kowal <cixar.com/~kris.kowal/>
 *
 * Accepts a date, a mask, or a date and a mask.
 * Returns a formatted version of the given date.
 * The date defaults to the current date/time.
 * The mask defaults to dateFormat.masks.default.
 */
var dateFormat = function () {
	var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		timezoneClip = /[^-+\dA-Z]/g,
		pad = function (val, len) {
			val = String(val);
			len = len || 2;
			while (val.length < len) val = "0" + val;
			return val;
		};

	// Regexes and supporting functions are cached through closure
	return function (date, mask, utc) {
		var dF = dateFormat;

		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
		if (arguments.length == 1 && (typeof date == 'string' || date instanceof String) && !/\d/.test(date)) {
			mask = date;
			date = undefined;
		}

		// Passing date through Date applies Date.parse, if necessary
		date = date ? new Date(date) : new Date();
		if (isNaN(date)) throw new SyntaxError("invalid date");

		mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		// Allow setting the utc argument via the mask
		if (mask.slice(0, 4) == "UTC:") {
			mask = mask.slice(4);
			utc = true;
		}

		var	_ = utc ? "getUTC" : "get",
			d = date[_ + "Date"](),
			D = date[_ + "Day"](),
			m = date[_ + "Month"](),
			y = date[_ + "FullYear"](),
			H = date[_ + "Hours"](),
			M = date[_ + "Minutes"](),
			s = date[_ + "Seconds"](),
			L = date[_ + "Milliseconds"](),
			o = utc ? 0 : date.getTimezoneOffset(),
			flags = {
				d:    d,
				dd:   pad(d),
				ddd:  dF.i18n.dayNames[D],
				dddd: dF.i18n.dayNames[D + 7],
				m:    m + 1,
				mm:   pad(m + 1),
				mmm:  dF.i18n.monthNames[m],
				mmmm: dF.i18n.monthNames[m + 12],
				yy:   String(y).slice(2),
				yyyy: y,
				h:    H % 12 || 12,
				hh:   pad(H % 12 || 12),
				H:    H,
				HH:   pad(H),
				M:    M,
				MM:   pad(M),
				s:    s,
				ss:   pad(s),
				l:    pad(L, 3),
				L:    pad(L > 99 ? Math.round(L / 10) : L),
				t:    H < 12 ? "a"  : "p",
				tt:   H < 12 ? "am" : "pm",
				T:    H < 12 ? "A"  : "P",
				TT:   H < 12 ? "AM" : "PM",
				Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
				o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
				S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
			};

		return mask.replace(token, function ($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});
	};
}();

// Some common format strings
dateFormat.masks = {
	"default":      "ddd mmm dd yyyy HH:MM:ss",
	shortDate:      "m/d/yy",
	mediumDate:     "mmm d, yyyy",
	longDate:       "mmmm d, yyyy",
	fullDate:       "dddd, mmmm d, yyyy",
	shortTime:      "h:MM TT",
	mediumTime:     "h:MM:ss TT",
	longTime:       "h:MM:ss TT Z",
	isoDate:        "yyyy-mm-dd",
	isoTime:        "HH:MM:ss",
	isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
	dayNames: [
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
	],
	monthNames: [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
	]
};

// For convenience...
Date.prototype.advancedFormat = function (mask, utc) {
	return dateFormat(this, mask, utc);
};

/**
*
*  URL encode / decode
*  http://www.webtoolkit.info/
*
**/

Url = {

    // public method for url encoding
    encode : function (string) {
        return escape(this._utf8_encode(string));
    },

    // public method for url decoding
    decode : function (string) {
        return this._utf8_decode(unescape(string));
    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        if (string) {
          string = string.replace(/\r\n/g,"\n");
          var utftext = "";

          for (var n = 0; n < string.length; n++) {

              var c = string.charCodeAt(n);

              if (c < 128) {
                  utftext += String.fromCharCode(c);
              }
              else if((c > 127) && (c < 2048)) {
                  utftext += String.fromCharCode((c >> 6) | 192);
                  utftext += String.fromCharCode((c & 63) | 128);
              }
              else {
                  utftext += String.fromCharCode((c >> 12) | 224);
                  utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                  utftext += String.fromCharCode((c & 63) | 128);
              }

          }
          
          return utftext;
        }
        else {
          return '';
        }
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        if (utftext) {
          var string = '';
          var i = 0;
          var c = c1 = c2 = 0;

          while ( i < utftext.length ) {

              c = utftext.charCodeAt(i);

              if (c < 128) {
                  string += String.fromCharCode(c);
                  i++;
              }
              else if((c > 191) && (c < 224)) {
                  c2 = utftext.charCodeAt(i+1);
                  string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                  i += 2;
              }
              else {
                  c2 = utftext.charCodeAt(i+1);
                  c3 = utftext.charCodeAt(i+2);
                  string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                  i += 3;
              }

          }

          return string;
       }
       else {
        return '';
       }
    }    

};﻿(function($) {
			
    $.fn.extend({  
      databind: function (callback) {  
        if (callback) {  
          return jQuery.event.add(this[0], 'databind', callback, null);  
        } 
        else {  
          var triggers = jQuery.event.trigger('databind', null, this[0], false, null);  
         
          // if there was no return value then the even validated correctly  
          if (triggers === undefined) {
            return true;  
          }
          else {
            return triggers;
          }
        }  
       }                
    }); 
    
    $.extend({      
      msDataFilter : function(data, type) {
        return eval('(' + data.replace(new RegExp('(^|[^\\\\])\\"\\\\/Date\\((-?[0-9]+)\\)\\\\/\\"', 'g'), "$1new Date($2)") + ')');
      },
           
      getMSJSON : function(url, data, successCallback, errorCallback) {
      	if ( jQuery.isFunction( data ) ) {
			    callback = data;
			    data = null;
		    }		
		    	    
		    return jQuery.ajax({
			    type: 'GET',
			    url: url,
			    data: data,
			    dataFilter: $.msDataFilter,
			    success: successCallback,
			    error: errorCallback
		    });    
      }
    });
			
	  $.fn.listing = function(options, context) {
	    var options = $.extend({}, $.fn.listing.defaults, options);
		    
	    listingControl = function(placeHolder, options, context) {
        this.placeHolder = placeHolder;
        this.options = options;
        this.context = context;
        this.pageSize = this.options.defaultPageSize;
        this.currentPage = 0;
        this.totalCount;
        this.itemsPerPage;
        this.items;
	      this.init();		      
	    }
	    
		  listingControl.prototype = {
		    
		    init : function() {
		      if (this.placeHolder) {
		        $(this.placeHolder).setTemplateURL(this.options.templateUrl, null, {filter_data: false});
		      }
          if (typeof Sys != undefined && Sys && Sys.WebForms) {
            Sys.WebForms.PageRequestManager.getInstance().add_endRequest(Function.createDelegate(this, this.retrieveData));
          }
		    },
		    
		    retrieveData : function() {
		      this.clear();
		      this.updateContent();
		    },
		    
		    getPageSize : function() {
		      return this.pageSize;
		    },			    
		    
		    setPageSize : function(value) {
		      this.pageSize = value;
		      this.currentPage = 0;
		      this.clear();
		      this.updateContent();
		    },
		    		    		   
		    getCurrentPage : function() {  
		      return this.currentPage;
		    },		
		    		   		    		    		   
		    setCurrentPage : function(value) {  
		      this.currentPage = value;
		      this.clear();
		      this.updateContent();		      
		    },		
		    		   
		    getTotalCount : function() {  
		      return this.totalCount;
		    },		
		    
		    getPageCount : function() {
		      count = this.getTotalCount();
		      pageSize = this.getPageSize();
          pageCount = Math.floor(count / pageSize);
          if (count % pageSize > 0)
          {
              pageCount++;
          }
          return pageCount;
		    },    
		    
		    getItems : function() {
		      return this.items;
		    },
		    
		    clear : function() {
		      this.items = null;
		      this.totalCount = null;
		    },
		    		    
		    updateContent : function() {		    
		      if (!this.items && !this.totalCount) {		        		        
		        if (this.options.preloader) {
		          blockOptions = {message: this.options.preloader};
		          if (this.options.preloader.jquery) {
		            blockOptions.css = {
							    background: 'transparent',
							    border: '0',
							    width: $(this.options.preloader).width()		            
		            };
		          }
		          $(this.placeHolder).block(blockOptions);		          
		        }		        
		        this.sendItemsRequest();
		        this.sendTotalCountRequest();
		      }		    		      
		      if (this.items != null && this.totalCount != null) {
		        if (this.items.length > 0) {
		          $(this.options.emptyMessage).hide();
              $(this.placeHolder).processTemplate(this.items);
            }
            else {
              $(this.options.emptyMessage).show();
            }
          }
		    },
		    
		    sendItemsRequest : function() {
		      params = {request: this.options.getItemsRequest,
		                pageNumber: this.getCurrentPage(),
		                pageSize: this.getPageSize()};
		      params = $.extend({}, this.context, params);
	        $.getMSJSON(this.options.serviceUrl, params, 
	                    Function.createDelegate(this, this.updateContentHandler),
	                    Function.createDelegate(this, this.errorRequestHandler));
		    },
		    
		    sendTotalCountRequest : function() {
		      params = {request: this.options.getTotalCountRequest};
		      params = $.extend({}, this.context, params);		    
          $.getMSJSON(this.options.serviceUrl, params,
	                    Function.createDelegate(this, this.updateTotalCountHandler),
	                    Function.createDelegate(this, this.errorRequestHandler));
		    },
		    
		    errorRequestHandler : function(response, result) {
	           $.log('WARN', response.responseText);
		    },
		    
		    updateContentHandler : function(data, result) {
		      if (result == 'success') {
		        if (typeof data != 'undefined' && data != null) {
              this.items = data;
		          this.updateContent();
		          if (this.options.preloader) {
		            $(this.placeHolder).unblock();
		          }
              this.fireDatabindEvent();
            }
		      }
		    },		   
		     
		    updateTotalCountHandler : function(data, result) {
		      if (result == 'success') {
		        if (typeof data != 'undefined' && data != null) {
              this.totalCount = data;
		          this.updateContent();
              this.fireDatabindEvent();
            }
		      }
		    },
		    
		    deleteItem : function(id) {		    
		      params = {request: this.options.deleteItemRequest, id : id};
		      params = $.extend({}, this.context, params);		    
          $.getMSJSON(this.options.serviceUrl, params,
	                    Function.createDelegate(this, this.deleteItemHandler),
	                    Function.createDelegate(this, this.errorRequestHandler));		    
		    },
		    
		    deleteItemHandler: function(data, result) {
		      if (result == 'success' && data) {
		        if (data.IsSuccess) {
		          if (this.items.length <= 1 && this.getCurrentPage() > 0) {
		            this.setCurrentPage(this.getCurrentPage() - 1);
		          }
		          this.retrieveData();
		          messageType = "Notification";
		          title = "Success";
		        }
		        else {
		          messageType = "Error";
		          title = "You've got some errors.";
		        }	            
            $('form').messageBox(null, {
              messageType: messageType, 
              title: title,               
              width: 350, 
              top: 10, 
              modal: false, 
              autoClose: true}, 
              '<div class="SysInfo"><p>' + data.Message + '</p></div>');
		      }		    
		    },
		    
		    fireDatabindEvent : function() {
	        if (this.items != null && this.totalCount != null) {
	          this.databind();
	        }		    
		    },
		    
		    databind : function(callback) {
		      if (callback && typeof callback == 'function') {
		        return $(this.placeHolder).databind(callback);
		      }
		      else {
		        return $(this.placeHolder).databind();
		      }
		    }		    	    		     
		  };
		    
	    return new listingControl($(this).get(0), options, context);
		};	
				    
    $.fn.listing.defaults = {
      templateUrl : '', 
      serviceUrl: '',
      getItemsRequest: 'GetItems',
      getTotalCountRequest: 'GetTotalCount',
      deleteItemRequest: 'Delete',
      defaultPageSize: 5,
      preloader : 'Please wait ...',
      emptyMessage : '#emptyMessage'
    };				
    
		$.fn.paginator = function(listing, options) {
	    var options = $.extend({}, $.fn.paginator.defaults, options);
		    
	    paginatorControl = function(placeHolder, listing, options) {
        this.placeHolder = placeHolder;
        this.listing = listing;
        this.options = options;

	      this.init();		      
	    }
	    
		  paginatorControl.prototype = {
		    
		    init : function() {
		      if (this.placeHolder) {
		        $(this.placeHolder).setTemplateURL(this.options.templateUrl, null, {filter_data: true});
		        if (this.listing) {
		          this.listing.databind(Function.createDelegate(this, this.databindHandler));
		        }
		      }
		    },
		    
		    updateContent : function() {
		      currentPage = this.listing.getCurrentPage();
		      pageSize = this.listing.getPageSize();
		      pageCount = this.listing.getPageCount();
		      startIndex = Math.max(currentPage - this.options.visiblePagesRange, 0);
		      endIndex = Math.min(currentPage + this.options.visiblePagesRange, pageCount - 1);
		      showBackLink = currentPage > 0;
		      showNextLink = currentPage < pageCount - 1;
		      
		      $(this.placeHolder).processTemplate({
		        showBackLink: showBackLink, 
		        showNextLink: showNextLink, 
		        currentPage: currentPage,
		        startIndex: startIndex,
		        endIndex: endIndex
		      });
		      
		      currentPaginator = this;
		      $('a', this.placeHolder).each(function() {
		        link = $(this);
		        if (link.html().indexOf('Next') > 0) {
		          link.click(Function.createDelegate(currentPaginator, currentPaginator.goToNextPageHandler));
		        }
		        if (link.html().indexOf('Back') > 0) {
		          link.click(Function.createDelegate(currentPaginator, currentPaginator.goToPrevPageHandler));
		        }
		        if (/\d+/.test(link.html())) {
		          link.click(Function.createCallback(currentPaginator.setPageHandler, {listing: currentPaginator.listing, pageNumber : parseInt(link.html()) - 1}));
		        }
		      });
		    },
		    
		    databindHandler : function() {
		      this.updateContent();
		    },
		    
		    setPageHandler : function(e, context) {
		      context.listing.setCurrentPage(context.pageNumber);
		    },
		    		    
		    goToNextPageHandler : function() {
		      this.listing.setCurrentPage(this.listing.getCurrentPage() + 1);
		    },
		    		    		    
		    goToPrevPageHandler : function() {
		      this.listing.setCurrentPage(this.listing.getCurrentPage() - 1);
		    }
		  };
		    
	    $(this).each(function() {											
        return new paginatorControl(this, listing, options);
      });
		};	
				    
    $.fn.paginator.defaults = {
      templateUrl : '', 
      visiblePagesRange: 2
    };			
    
    $.fn.pageSize = function(listing, options) {	
      var options = $.extend({}, $.fn.pageSize.defaults, options);
      
	    pageSizeControl = function(placeHolder, listing, options) {
        this.placeHolder = placeHolder;
        this.listing = listing;
        this.options = options;
        this.sizesList;

	      this.init();		      
	    }
	    
		  pageSizeControl.prototype = {    
		    
		    init : function() {
		      if (this.placeHolder) {
		        this.buildSizesList();
		        if (this.sizesList) {
		          $(this.sizesList).bind('change', Function.createDelegate(this, this.pageSizeChangedHandler));
		        }
		      }
		    },
		    
		    buildSizesList : function() {
		      this.sizesList = $.create('select').appendTo($(this.placeHolder));
          for (var i in this.options.availableSizes) {
            size = this.options.availableSizes[i];
            newOption = $.create('option', {text: String.format(this.options.textTemplate, size), value: size});
            $(this.sizesList).each(function() {
              if ($.browser.msie) {
                this.options.add(newOption[0]);
              }
              else {
                this.appendChild(newOption[0]);
              }            
            });
          } 		      
		    },
		    
		    pageSizeChangedHandler: function() {
		      if (this.listing) {
		        newPageSize = parseInt();
		        this.listing.setPageSize($(this.sizesList).val());
		      }
		    }
		  };
		    
	    $(this).each(function() {											
        return new pageSizeControl(this, listing, options);
      });      
		};	
				    
    $.fn.pageSize.defaults = {
      availableSizes : [5, 10, 15, 20],
      textTemplate : '{0} items/page'
    };	    
	
})(jQuery);/**
 * jQuery messageBox plugin. Shows popup messages.
 *
 * Copyright (c) 2008 Roman Zaharenkov
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
  *
  *	 Example:
  *		$('#mainForm').messageBox({messageType: 'Error'}, $.generateList, {messages: ['Please enter a name.', 
  *																												  'Please enter email in correct format.', 
  *																												  'Please select a date of birth.']});
  *																												  
  *		$('form').messageBox({messageType: 'Notification', width: 400, top: 500, autoClose: false}, 'Success');;	
  *	
  *	 Requirements:
  *		jquery.js
  *		jquery.domec.js -  jQuery DOMEC (DOM Elements Creator) 0.3.1
  *		jquery.timers.js - jQuery plug-in produces a friendlier and more intuitive timed event system.
  *		ui.core.js - jQuery ui core.
  *		ui.draggable.js - jQuery ui draggable plug-in.
  *		core.js - String and Function extension methods.
  *		
 */

(function($) {
	
	/**
	  *  Generates DOM list by array of objects.
	  *	
	  *  Example:
	  *  	generateList(['a', 'b', 'c'])
	  *	
	  *	 Output:	
	  *  	<ul>		
	  *  		<li>a</li>		
	  *  		<li>b</li>		
	  *  		<li>c/li>		
	  *  	</ul>		
	  */
	$.extend({
		generateList : function(data) {
			errorsList = $.create('ul', {});
			for (i in data.list) {
				errorsList.append($.create('li', {}, data.list[i]));
			}
			return errorsList;		
		}
	});	
	
	$.extend({
		getScrollPosition : function(data) {
      if( typeof( window.pageYOffset ) == 'number' ) {
        //Netscape compliant
        return {left : window.pageXOffset, top : window.pageYOffset};
      } 
      else {
        if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
          //DOM compliant
          return {left : document.body.scrollLeft, top : document.body.scrollTop};
        } 
        else {
          if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
            //IE6 standards compliant mode
            return {left : document.documentElement.scrollLeft, top : document.documentElement.scrollTop};
          }
        }
      }
  	}
	});

	/**
	  *	Message Box jQuery plug-in. Shows popup message boxes.
	  *
	  *	Parameters:
	  *   topPositionElement - DOM element used for top alignment.
	  *		settings - message box settings:		
	  *			title - message box title
	  *			messageType - type of message - {Error, Notification}
	  *			autoClose - indicates whether message box will be closed automaticaly.
	  *			autoCloseInterval - specifies time interval for auto closing.
	  *			showCloseLink - indicates whether close link will be displayed.
	  *			showKeptLink - indicates whether kept link will be displayed.
	  *			showCloseLink - indicates whether close link will be displayed.
	  *			hideEffect - specofies effect that be applied before message will be hided {'none', 'fadeOut'}
	  *			width - specofies width of message box (content width by default).
	  *			top - specofies top position of message box (0 by default).
	  *		messageContent - content of the box. Can be string, DOM element or callback function passed.
	  *		data - used with callback function for content building.
	  */
	$.fn.messageBox = function(topPositionElement, settings, messageContent, data) {
	
    settings = $.extend({}, $.fn.messageBox.defaults, settings);
			
		messageBox = function(parent, topPositionElement, settings, messageContent, data) {		  
		  this.settings = settings;
			this.parent = $(parent);
			if (topPositionElement) {
			  this.topPositionElement = $(topPositionElement);
			}																			
			this.messageContent = messageContent;
			this.data = data;																
			this.body;
			this.title;			
			this.keptLink;
			this.closeBox;
			this.timeRemaining = 0;
			this.listBox;
			this.isAutoclosingActive = false;
			this.fader;			
			this.ie6 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 6.0") != -1);
		};
		
		messageBox.defaultWidth = 350;
		
		messageBox.maximumWidth = 600;
		
		messageBox.updateInterval = 1000;
		
		messageBox.autoCloseTimerLabel = 'autoClose';
		
		messageBox.updateTimerLabel = 'update';
		
		messageBox.prototype = {
			
			appendTitle : function(content) {
				content.prepend(
					this.title = $.create('div', {className : 'Caption'}, [
						$.create('h2', {'className' : settings.messageType}, [
						  settings.title,
						  this.closeBox = $.create('div', {'className' : 'close'})
						])
					])
				);
				this.closeBox.bind('click', {errorWindow : this}, function(e){
					e.data.errorWindow.hide();
				});				
			},			
			
			appendKeptLink : function() {
			  this.timeRemaining = this.settings.autoCloseInterval / 1000;
				this.listBox.append(				  
					this.keptLink = $.create('p', {'className' : 'CountNote'}, [
																		String.format('Window will be closed automatically in <strong class="Integer">{0}</strong> seconds. Click here to  ', this.timeRemaining),
																		link = $.create('a', {href: 'javascript:void(0)'}, 'keep'), ' this window.'
																	])
				);
				link.bind('click', {errorWindow : this}, function(e){
					e.data.errorWindow.cancelAutoClose();
				});
			},			
			
			appendCloseLink : function() {
			  /*   // This close links is not needed. A closing red closs is already present at upper-right corner of message box
				  this.listBox.append($.create('p', {'className' : 'CountNote', 'style' : 'text-align:right'}, [
															  closeLink = $.create('a', {href: 'javascript:void(0)'}, 'Close')
														  ]));
				  closeLink.bind('click', {errorWindow : this}, function(e){
					  e.data.errorWindow.hide();
				  });
				*/
			},
			
			buildWindowStyle : function() {
				style = {};
				width = this.settings.width;				
				if (!width) {
				  if (!$.browser.msie) {				  
					  width = this.body.width();
					}
					else {
            width = messageBox.defaultWidth;					
					}
				}				
				if (width > messageBox.maximumWidth) {
				  width = messageBox.maximumWidth;
				}
				style.width = String.format('{0}px', width);
				style.marginLeft = String.format('-{0}px', width / 2);
				if (this.topPositionElement && this.topPositionElement.length > 0) {
				  topPosition = this.topPositionElement.position().top;
				}
				else {
				  topPosition = this.settings.top;
				}	
				if (!this.settings.blockScroll) {
				  scrollPosition = $.getScrollPosition();
				  if (scrollPosition) {
				    topPosition = scrollPosition.top + topPosition;
				  }
				}
				style.top = String.format('{0}px', topPosition);
				style.left = this.settings.left;
				return style;
			},
		
			buildWindow : function() {		
				content = $.create('div', {'className' : 'PopUpContent'}, [
															this.listBox = $.create('div', {'className' : this.settings.contentClassName})
													]);	
													
				if (messageContent) {					
					if (typeof messageContent == 'function') {
						this.listBox.append(messageContent.call(this, data));
					}
					else {
						this.listBox.append(messageContent);
					}									
				}
				
				settings = this.settings;
				if (settings.showTitle) {
					this.appendTitle(content);
				}
				if (settings.autoClose) {
					if (settings.showKeptLink) {
						this.appendKeptLink();		
					}					
				}
				else {
					this.appendCloseLink();
				}				
				
				this.body = $.create('div', {'className': settings.containerClassName}, [
															popup = $.create('div', {'className': 'PopUpBox ' + settings.className + settings.outerRound + '-' + settings.innerRound}, [
																topLeftElement = $.create('b', {'className': 'top'}, [
																	topElement = $.create('i', {}, [
																		topRightElement = $.create('ins', {})
																	])
																]),
																	middleElement = $.create('div', {'className': 'middle'}, [
																		wrapperElement = $.create('div', {'className': 'wrapper'}, [
																			$.create('div', {'className': 'bg'}, [content])																	
																		])
																]),
																bottomLeftElement = $.create('b', {'className': 'bottom'}, [
																	bottomElement = $.create('i', {}, [
																		bottomRightElement = $.create('ins', {})
																	])
																])																
															])				
														]).prependTo(this.parent);
        
        if (settings.minWidth) {
          this.body.css({minWidth: settings.minWidth});
          this.body.minSize({width: settings.minWidth});
        }
														
        this.applySize(topLeftElement, topElement, topRightElement, middleElement, wrapperElement, bottomLeftElement, bottomElement, bottomRightElement);														
				this.body.css(this.buildWindowStyle());				
				this.body.draggable({
				  handle: this.title,
				  cursor:'move', 
				  start: Function.createDelegate(this, this.cancelAutoClose)
				});
				
				if (settings.modal) {
					this.parent.prepend(this.fader = $.create('div', {className: settings.faderClass, style: String.format('height:{0}px;', $(document).height())}, ''));
					this.fader.bind('click', Function.createDelegate(this, this.hide));
					this.lockScroll();
				}
				
				arrowAreaElement = null;
				arrowElement = null;
				if (settings.showArrow) {
				  arrowAreaElement = $.create('b', {'className' : 'arrow'}, [
				   arrowElement = $.create('i', {})
				  ]);
				  popup.prepend(arrowAreaElement);
				}
				
        this.fixIE(topLeftElement,
                    topElement,
                    topRightElement,
                    middleElement,
                    wrapperElement,
                    bottomLeftElement,
                    bottomElement,
                    bottomRightElement,
                    arrowAreaElement,
                    arrowElement);
			},
			
			applySize : function(topLeftElement, topElement, topRightElement, middleElement, wrapperElement, bottomLeftElement, bottomElement, bottomRightElement) {
			  settings = this.settings;
			  round = String.format('{0}px', settings.outerRound);
			  topLeftElement.css({height: round});
			  topLeftElement.find('*').css({height: round});
			  topElement.css({marginLeft: round, marginRight: round});
			  topRightElement.css({width: round, right: '-' + round});
			  wrapperElement.css({margin: String.format('0 {0}px', settings.innerRound)});
			  bottomLeftElement.css({height: String.format('{0}px', settings.outerRound + 2)});
			  bottomLeftElement.find('*').css({height: String.format('{0}px', settings.outerRound + 2)});			  
			  bottomElement.css({marginLeft: round, marginRight: round});
			  bottomRightElement.css({width: round, right: '-' + round});
			},			
			
			fixIE : function(topLeftElement, topElement, topRightElement, middleElement, 
			                  wrapperElement, bottomLeftElement, bottomElement, bottomRightElement,
			                  arrowAreaElement, arrowElement) {
        if (this.ie6) {
          settings = this.settings;
				  this.closeBox.pngFix({sizingMethod: 'scale'});
				  topLeftElement.pngFix({sizingMethod: 'crop'});
				  topElement.pngFix({sizingMethod: 'scale'});
				  topRightElement.pngFix({sizingMethod: 'crop'});
				  bottomLeftElement.pngFix({sizingMethod: 'crop'});
				  bottomElement.pngFix({sizingMethod: 'scale'});
				  bottomRightElement.pngFix({sizingMethod: 'crop'});
				  middleElement.pngFix({sizingMethod: 'crop'});
          if (settings.modal) {
            this.fader.append($.create('iframe', {height: this.fader.height(), width: this.fader.width(), src: 'javascript:false', frameBorder: 0, scroll: 'none'}));
						this.fader.pngFix({sizingMethod: 'scale'});
          }
          else {
						this.body.append(helpFrame = $.create('iframe', {height: this.body.height(), width: this.body.width(), src: 'javascript:false', frameBorder: 0, scroll: 'none'}));
						helpFrame.css({marginTop: -this.body.height() + 'px'})
          }
          
          if(settings.showArrow) {
            arrowAreaElement.pngFix({sizingMethod: 'crop'});
            arrowElement.pngFix({sizingMethod: 'scale'});
          }
				}
			},
			
			scrollHandler : function(e) {
				window.scrollTo(e.data.pos[0], e.data.pos[1]);
				return false;				
			},
			
			lockScroll: function() {
				var a = [self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
								 self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop];
        if ($.browser.msie) {
          // Bad solution for IE
          //if (this.settings.blockScroll) {
				  //  $(window).bind('scroll', {pos: a}, Function.createDelegate(this, this.scrollHandler));
				  //}
				}
				else {
				  if (this.settings.blockScroll) {
				    $('body').css({overflow: 'hidden'});
				  }
				}
			},
			
			unlockScroll: function() {
			  if ($.browser.msie) {
			    // Bad solution for IE
			    //if (this.settings.blockScroll) {
				  //  $(window).unbind('scroll', Function.createDelegate(this, this.scrollHandler));
				  //}
				}
				else {
				  if (this.settings.blockScroll) {
				    $('body').css({overflow: 'scroll'});
				  }
				}
			},
			
			show  : function() {
				if (!this.body) {
					this.buildWindow();
				}
				this.body.show();
				settings = this.settings;
				this.activateAutoClosing();
			},
			
			hide : function() {						
				if (this.body) {
					settings = this.settings;
					if ($.browser.msie) {
						this.destroy();
					}
					else {
						if (settings.hideEffect == 'none') {
							this.destroy();
						}
						if (settings.hideEffect == 'fadeOut') {
							this.body.fadeOut("slow", Function.createDelegate(this, this.destroy));
						}						
					}		
				}			
			},
			
			destroy : function() {			
				this.body.remove();
				if (this.settings.modal && this.fader) {
				  this.fader.remove();
				  this.unlockScroll();
				}				
			},
			
			activateAutoClosing : function() {
				if (settings.autoClose) {
					this.isAutoclosingActive = true;
					$(this).oneTime(settings.autoCloseInterval, messageBox.autoCloseTimerLabel, function () {
						this.hide();
					});
					$(this).everyTime(messageBox.updateInterval, messageBox.updateTimerLabel, Function.createDelegate(this, this.updateLeptLink), this.timeRemaining);
				}			
			},
			
			cancelAutoClose : function() {
				if (this.isAutoclosingActive) {
					$(this).stopTime(messageBox.autoCloseTimerLabel);
					this.keptLink.remove();
					this.appendCloseLink();		
					this.isAutoclosingActive = false;
				}
			},
			
			updateLeptLink : function() {
			  this.timeRemaining--;
			  if (this.timeRemaining >= 0) {
			    this.keptLink.html(String.format('Window will be closed automatically in <strong class="Integer">{0}</strong> seconds. Click here to ', this.timeRemaining));
			    link = $.create('a', {href: 'javascript:void(0)'}, 'keep');
				  link.bind('click', {errorWindow : this}, function(e){
					  e.data.errorWindow.cancelAutoClose();
				  });
				  this.keptLink.append(link);
				  this.keptLink.append(' this window.');
			  }
			}
		};		
	
		popupWindow = new messageBox($(this).get(0), topPositionElement, settings, messageContent, data);
		popupWindow.show();
		return popupWindow;
	};
	
	$.fn.messageBox.defaults = {showTitle : true,
																minWidth: 300,
																title: 'Message Box',
																messageType : 'Error',
																autoClose : true,
																autoCloseInterval : 5000,
																showCloseLink : true,
																showKeptLink : true,
																hideEffect : 'fadeOut',
																width : null,
																top : 0,
																left : '50%',
																modal : false,
																faderClass : 'Fader',
																className : 'Popup',
																containerClassName : 'PopUpContainer',
																contentClassName : 'ListMode ListModeA',
																outerRound : 23,
																innerRound : 9,
																showArrow : false,
																arrowClass : 'arrow',
																blockScroll : false};
	
})(jQuery);