if (typeof(Application) == 'undefined') {
	Application = Class.create();
}

/*Application.openLoginForm = function(senderObj) {
    var effect = new PopupEffect(senderObj, {className: "popup_effect"});
    var win = new Window({className:"alphacube", width: 250, height:null, showEffect:effect.show.bind(effect), hideEffect:effect.hide.bind(effect)})
    var position = Position.cumulativeOffset(senderObj);
    var size = senderObj.getDimensions();

    win.setLocation(position[1] + size.height, position[0] - 200);
    //win.setHTMLContent($('login').innerHTML)
    win.getContent().update($('login').innerHTML);

    win.show();
};*/

Application.addToBookmarks = function(title, url) {
    if(window.sidebar) {
        window.sidebar.addPanel(title, url, '');
    } else {
        if((window.opera)&&(window.print)) {
            lnk = document.createElement('a');
            lnk.setAttribute('href', url);
            lnk.setAttribute('title', title);
            lnk.setAttribute('rel', 'sidebar');
            lnk.click();
        } else {
            window.external.AddFavorite(url, title);
        }
    }
};

Application.setCookie = function (name, value, expires, path, domain, secure) {
	document.cookie = name + "=" + escape(value) +
        ((expires) ? "; expires=" + expires : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
	//document.cookie = name + "=" + escape( value ) + "; expires=Thu, 01-Jan-2200 00:00:01 GMT; path=/";
};

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

/*Application.onPageLoaded = function() {
    Application.LoginForm = new LoginForm();
}*/


UpdateExtender = Class.create();
UpdateExtender.prototype = {
    initialize: function (options) {
        this.setOptions(options);
        this.initIndicator();
    },

    setOptions: function(options) {
        // default options
        this.options = {
            indicatorSrc: baseUrl + 'resources/images/loader 32x32.gif', // image url which should be displayed on async updation
            panelId: null, // panel which should bu async updated
            containerId: null // container in center of which indicator should be displayed
        }
        Object.extend(this.options, options || {});
    },

    initIndicator: function() {
        if (this.options.panelId) {
            this.indicator = new Image();
            this.indicator.src = this.options.indicatorSrc
            this.indicator.style.display = 'none';
            this.indicator.style.position = 'absolute';
            this.indicator.style.zIndex = '9999';
            $(this.options.panelId).appendChild(this.indicator);
        } else {
            throw 'Async panel indicator initialization failed, panel Id is undefined.';
        }
    },

    show: function(senderObj) {
        this._setIndicatorPosition();
        Element.show(this.indicator);
    },

    hide: function(senderObj) {
        Element.hide(this.indicator);
    },

    _setIndicatorPosition: function() {
        //var position = Position.cumulativeOffset(this.options.containerId);
        try {
        if (this.options.panelId && $(this.options.panelId))
            Position.relativize(this.options.panelId);
        } catch (e) {
            //alert($(this.options.panelId) + " Position.relativize: " + e.message);
        }

        var element = this.options.containerId ? this.options.containerId : this.options.panelId;
        var dim = $(element).getDimensions();

        var x = dim.height / 2
        var y = dim.width / 2;

        this.indicator.style.left = y + 'px';
        this.indicator.style.top = x + 'px';
    }
};

/*
 * Abstract class for ajax forms
 */
 AjaxForm = Class.create();
 AjaxForm.prototype = {
     initialize: function (options) {
         this.onInitialize(options);
     },

     setOptions: function(options) {
         // default options
         this.options = {
             submitParams:{isAsyncPostBack: '1'},
             formId: "",
             messageId: "",
             botProtection: false,
             cssClassError: "errorMessage",
             cssClassSuccess: "successMessage",
             cssClassInvalidField: "invalid"
         }
         Object.extend(this.options, options || {});
     },

     initEventHandlers: function() {
         this.onSuccessHandler = this.onSuccess.bindAsEventListener(this);
         this.onFailedHandler = this.onFailed.bindAsEventListener(this);
         this.onSubmitHandler = this.onSubmit.bindAsEventListener(this);
         this.onChangeHandler = this.onChange.bindAsEventListener(this);
         this.onShowInvalidFieldHandler = this.onShowInvalidField.bindAsEventListener(this);
         this.onHideInvalidFieldHandler = this.onHideInvalidField.bindAsEventListener(this);
     },

     initEvents: function() {
         var form = this.getForm();
         if (form) {
             // var elements = form.getInputs('submit');
             // if (elements && elements.length > 0) {
             //     elements[0].onclick = '';
             //     elements[0].click = '';
             // } 
             Event.observe(form, 'submit', this.onSubmitHandler); 
         }
     },

     initUpdateIndicator: function() {
         var container;
         if (this.options
             && this.options.indicatorPlaceholderId
             && this.options.indicatorPlaceholderId != "auto")
         {
             container = this.options.indicatorPlaceholderId;
         } else if (this.options.formId){
             var elements = $(this.options.formId).getElementsBySelector('textarea');
             if (elements && elements[0]) {
                 if (elements[0].id != "")
                     container = elements[0].id;
                 else
                     container = elements[0];
             }
         }

 		if (container && this.asyncRequestIndicator == null) {
 	        this.asyncRequestIndicator = new UpdateExtender({
 	            panelId: this.options.formId,
 	            containerId: container
 	            });
 		}
     },

     initElements: function() {
         var ajaxForm = this.getForm();
         if (ajaxForm) {
             var elements = ajaxForm.getElements();
             if (elements && elements.length > 0) {
                 for(var i = 0; i < elements.length; i++) {
                     var element = $(elements[i]);

                     if ((element.tagName.toLowerCase() == 'input' && this.editableTagTypes.indexOf(element.type.toLowerCase()))
                         || this.editableTags.indexOf(element.tagName.toLowerCase()) >= 0) {
                         Event.observe(element, 'change', this.onChangeHandler);
                         if (element.id == '' && element.name != '') {
                            element.id = ajaxForm.id + '_' + element.name;
                         }

                         //if (element.alt && element.alt.length > 0 && $F(element) == '') {
                         //    element.text = element.alt;
                         //    Event.observe(elements[i], 'focus', this.onFocusHandler);
                         //}
                     }
                 }
             }
         }
     },

     show: function(senderObj) {
         var form = this.getForm();
         if (form) {
             form.show();
         }
     },

     hide: function(senderObj) {
         var form = this.getForm();
         if (form) {
             form.hide();
         }
     },

     toggle: function(senderObj, evtObj) {
         if (Element.visible(this.options.formId)) {
             this.hide();
             if (this.options.messageId) {
                 var msgLabel = $(this.options.messageId);
                 if (msgLabel) {
                     msgLabel.update('');
                 }
             }
         } else {
             if (this.onBeforeShow && typeof(this.onBeforeShow) == 'function')
                 this.onBeforeShow();
             this.show();
         }
     },

     enable: function() {
         var form = this.getForm();
         if (form) {
             Form.enable(form);
         }
     },

     disable: function() {
         var form = this.getForm();
         if (form)
             Form.disable(form);
     },

     reset: function() {
         var form = this.getForm();
         if (form) {
             Form.reset(form);
             form.changed = true;
         }
     },

     onInitialize: function(options) {
         this.setOptions(options);
         this.asyncRequestIndicator = null;
         this.editableTags = ['select', 'textarea'];
         this.editableTagTypes = ['checkbox','date','datetime','datetime-local','email','file','month','number','password','radio','range','text','time','url'];

         this.initEventHandlers();
         this.initEvents();
         this.initElements();  
     },
     
     onChange: function(eventObj) {
         var ajaxForm = this.getForm();
         ajaxForm.changed = true;
         this.resetFieldState(eventObj.target);
     },

     onSubmit: function() {
         try {
             if (arguments.length == 2) {
                 var senderObj = arguments[0];
                 var eventObj = arguments[1];
             } else {
                 var eventObj = arguments[0];
             }
             
             // stop submit event
             if (eventObj.preventDefault)
                 Event.stop(eventObj);

            var ajaxForm = this.getForm();
 			if (typeof(ajaxForm.changed) != 'undefined' && ajaxForm.changed == false) {
 				return false;
 			} else {
 			    ajaxForm.changed = false;
 		    }

             var options = {
                 parameters: this.options.submitParams,
                 onException: this.onFailedHandler,
                 onFailure: this.onFailedHandler,
                 onSuccess: this.onSuccessHandler
             };

             var word = null;
             if (this.options.botProtection) {
                 word = this.prepareActionUrl();
             }

             if (typeof(this.onBeforeSubmit) == 'function')
                 this.onBeforeSubmit(options);
             
             this.resetFieldsldsState();
             ajaxForm.request(options);

             if (this.options.botProtection && word) {
                 this.restoreActionUrl(word);
             }

             this.disable();
         } catch(e) {
             alert("Error: " + e.message);
             this.enable();
         } finally {
             return false;
         }
     },

     onSuccess: function(transport, json) {
         throw("Method is not implemented");
     },

     onFailed: function(transport, exObj) {
         throw("Method is not implemented");
     },

     onShowInvalidField: function(senderObj, tmp) {
         senderObj.element.style.backgroundColor = '';
         senderObj.element.addClassName(this.options.cssClassInvalidField);
     },

     onHideInvalidField: function(senderObj, tmp) {
         senderObj.element.style.backgroundColor = '';
         senderObj.element.removeClassName(this.options.cssClassInvalidField);
     },

     showInvalidFeilds: function(fields) {
         var ajaxForm = this.getForm();
         for (var fieldId in fields) {
             var element = $(fieldId) || $(ajaxForm.id + '_' + fieldId);

             if (element && !element.hasClassName(this.options.cssClassInvalidField)) {
                 element.title = fields[fieldId];

                 new Effect.Morph(element, {
                   style: 'background:#FFEEEE;',
                   duration: 0.5,
                   afterFinish: this.onShowInvalidFieldHandler
                 });
             }
         }
     },

     showMessage: function(message, isError) {
         var msgPanel = $(this.options.messageId);
         if (msgPanel) {
             if (typeof(message) == 'object')
                 message = this.convertMessageToList(message);
             msgPanel.update(message);
             msgPanel.removeClassName(this.options.cssClassError);
             msgPanel.removeClassName(this.options.cssClassSuccess);
             if (isError) {
                 msgPanel.addClassName(this.options.cssClassError);
             } else {
                 msgPanel.addClassName(this.options.cssClassSuccess);
             }
             msgPanel.show();
         }
     },

     resetFieldsldsState: function() {
         var form = this.getForm();
         var inputs = form.getInputs('text');
         if(inputs) {
             for(var i = 0; i < inputs.length; i++) {
                 this.resetFieldState(inputs[i]);
             }
         }
     },

     resetFieldState: function(element) {
         if (element) {
             element.title = '';

             if (element.hasClassName(this.options.cssClassInvalidField)) {
                 new Effect.Morph(element, {
                   style: 'background:#FFFFFF;',
                   duration: 0.5,
                   afterFinish: this.onHideInvalidFieldHandler
                 });
             }
         }
     },

     getForm: function() {
         return $(this.options.formId);
     },

     prepareActionUrl: function() {
         var form = this.getForm();
         var word = null;

         if (form) {
             var index = form.action.lastIndexOf('-');
             if (index > 0) {
                 word = parseInt(form.action.substring(index + 1));
                 if (word > 0) {
                     form.action = form.action.substring(0, index) + '/';
                 }
             }
         }
 	    return word;
     },

     restoreActionUrl: function(word) {
         var form = this.getForm();

         if (form && word.length > 0) {
             var index = form.action.lastIndexOf('/');
             if (index == form.action.length - 1) {
                 var actionUrl = form.action.substring(0, index);
                 if (actionUrl.length > 0) {
                     form.action = actionUrl + '-' + word;
                 }
             }
         }
     },
     
     convertMessageToList: function(messages) {
         var list = '<ul class="validationMessages">';
         for(var key in messages) {
             list += '<li>' + messages[key] + '</li>';
         }
         list += '</ul>';
         return list;
     }
 };

BreedInfoForm = Class.create();
BreedInfoForm.prototype = Object.extend(new AjaxForm(), {
    initialize: function (options) {
        // default options
        var options = Object.extend({
            formId: "appearanceForm",
            indicatorPlaceholderId: "auto",
            messageId: "appearanceMessages",
            botProtection: true
        }, options || {});

        this.onInitialize(options);
    },

    hideMessage: function() {
        var msgLabel = $(this.options.messageId);
        if (msgLabel) {
            msgLabel.update("");
            msgLabel.hide();
        }
    },

    onBeforeSubmit: function(options) {
        //this.hideMessage();
        this.initUpdateIndicator();
        this.asyncRequestIndicator.show();
		//parseFormAction(this.options.formId);
    },
    // Occure when async responce received
    // {(bool) success, (string) message, (string) error}
    onSuccess: function(transport, json) {
        var dataObj;
        // before postback form was disabled

        try {
            dataObj = transport.responseText.evalJSON();

            if (dataObj.error) {
                this.showMessage(dataObj.error, !dataObj.success)
            } else if (dataObj.message) {
                this.showMessage(dataObj.message, !dataObj.success);
            }
        } catch(e) {
            alert("Error:" + e.message);
        } finally {
            this.enable();
            this.asyncRequestIndicator.hide();
            if (dataObj.success)
                this.hide();
        }
    },

    // failed async postback
    onFailed: function(transport, exObj) {
        this.enable();
        this.asyncRequestIndicator.hide();
        this.showMessage(exObj.message, true);
    },

    onBeforeShow: function() {
        this.hideMessage();
    }
});

MailForm = Class.create();
MailForm.prototype = Object.extend(new BreedInfoForm(), {
    onSuccess: function(transport, json) {
        var dataObj;
        // before postback form was disabled
        this.enable();
        try {
            dataObj = transport.responseText.evalJSON();

            if (dataObj.error) {
                if (typeof(dataObj.error) == 'object') {
                    this.showInvalidFeilds(dataObj.error);
                }
                this.showMessage(dataObj.error, !dataObj.success)
            } else if (dataObj.message) {
                this.showMessage(dataObj.message, !dataObj.success);
            }
        } catch(e) {
            alert("Error:" + e.message);
        } finally {
            this.enable();
            this.asyncRequestIndicator.hide();
        }
    }
});

AjaxWindowForm = Class.create();
AjaxWindowForm.prototype = Object.extend(new AjaxForm(), {
    initialize: function (options) {
        // default options
        var options = Object.extend({
            formId: null,
            indicatorPlaceholderId: "auto",
            messageId: "resultMessages",     // content for messages displaying
            theme: "alphacube",              //"alphacube" "mac_os_x"
            openEffect: "popup_effect",
            contentId: null,                 // content which will display in window
            cssClassError: "errorMessage",
            cssClassSuccess: "successMessage",
            width: "auto",
            height:null,
            minimizable:false,
            maximizable:false
        }, options || {});

        this.onInitialize(options);
        this.initUpdateIndicator();
    },

    initWindow: function(elementOwner, options) {
        var effect = new PopupEffect(elementOwner, {className: this.options.openEffect});

        this.windowOptions = {
            className:this.options.theme,
            width: this.options.width,
            height:this.options.height,
            showEffect:effect.show.bind(effect),
            hideEffect:effect.hide.bind(effect),
            minimizable:this.options.minimizable,
            maximizable:this.options.maximizable
            };
        this.effect = effect;
        this.window = new Window(this.windowOptions);
    },

    updateContent: function(options) {
        this.window.getContent().update($(this.options.contentId).innerHTML);
        if (options) {
            if (options.fields) {
                var form = $(this.options.formId)
                for(var field in options.fields) {
                    var elements = form.getInputs('hidden', field);
                    if (elements && elements.length > 0) {
                        $(elements[0]).value = options.fields[field];
                    }
                }
            }
        }
        this.window.setSize(this.options.width, this.options.height);
    },

    show: function(senderObj, options) {
        try {
            if (this.window == null)
                this.initWindow(senderObj, options);
            else {
                delete(this.effect.div);
                this.effect.html = senderObj;
            }

            this.updateContent(options);
            this.hideMessage();
            this.enable();
            this.initElements();
            
            if (this.options.position == 'center')
                this.window.showCenter();
            else {
                var position = this._getLocation(senderObj);
                this.window.setLocation(position.x, position.y);
                this.window.show();
            }

            if (typeof(this.onShowHandler) == 'function') {
                this.showOptions = options;
                window.setTimeout(this.onShowHandler, 600);
            }
        } catch (e) {
            alert(e.message);
        }
    },

    hideMessage: function() {
        var msgLabel = $(this.options.messageId);
        if (msgLabel) {
            msgLabel.update("");
            msgLabel.hide();
        }
    },

    reloadCapche: function() {
        var form = this.getForm();
        if (form) {
            var elements = form.select('img.capche');
            if (elements && elements.length > 0) {
                var imgCapche = elements[0];
                var src = imgCapche.src;
                var pos = src.indexOf('?');
                if (pos >= 0) {
                   src = src.substr(0, pos);
                }
                var date = new Date();
                imgCapche.src = src + '?v=' + date.getTime();
            }
        }
    },
    
    // Occure when async responce received
    // {(bool) success, (string) message, (string) error}
    onSuccess: function(transport, json) {
        var dataObj;
        // before postback form was disabled
        this.enable();

        try {
            dataObj = transport.responseText.evalJSON();

            if (dataObj.error) {
                this.reloadCapche();
                this.showMessage(dataObj.error, !dataObj.success);
                this.window.updateHeight();
            } else if (dataObj.message) {
                this.hide();
                this.showMessage(dataObj.message, !dataObj.success);
                this.window.setSize(this.options.width, 50);
            }
        } catch(e) {
            alert("Error:" + e.message);
        } finally {
            this.asyncRequestIndicator.hide();
        }
    },

    // failed async postback
    onFailed: function(transport, exObj) {
        this.enable();
        this.asyncRequestIndicator.hide();
        this.showMessage(exObj.message, true);
    },

    _getLocation: function(senderObj) {
        var position = Position.cumulativeOffset(senderObj);
        var size = senderObj.getDimensions();

        switch(this.options.position) {
            case "topleft":
                return {x:position[1] - this.options.height , y:position[0] - (this.options.width - size.width)};
                break;
            case "topright":
                return {x:position[1] - this.options.height, y:position[0]};
                break;
            case "bottomright":
                return {x:position[1] + size.height , y:position[0]};
                break;
            case "bottomleft":
            default:
                return {x:position[1] + size.height, y:position[0] - (this.options.width - size.width)};
        }
    },

    _toHTMLString: function(message) {
        if (typeof(message) == 'object') {
            var text = '';
            for(var key in message) {
                text += message[key] + '<br/>'
            }
            return text;
        }
        else
            return message;
    }
});

ViewPhotos = Class.create();
ViewPhotos.prototype = Object.extend(new AjaxForm(), {
    initialize: function (options) {
        // default options
        var options = Object.extend({
            formId: null,
            indicatorPlaceholderId: "auto",
            contentId: null,                 // content which will display in window
            photoImageId: null,
            nextId: '',
            prevId: '',
            theme: "alphacube",              //"alphacube" "mac_os_x"
            openEffect: "popup_effect",
            contentId: null,                 // content which will display in window
            cssClassError: "errorMessage",
            cssClassSuccess: "successMessage",
            width: "auto",
            height:null,
            minimizable:false,
            maximizable:false
        }, options || {});

        this.onInitialize(options);
        this.initUpdateIndicator();

        this.photos = new Array();
        this.currentPhotoIndex = 0;

        this.onShowHandler = this.onPhotoShow.bindAsEventListener(this);

        $("breedName").innerHtml = this.options.breedName;
    },
    initWindow: function(elementOwner, options) {
        var effect = new PopupEffect(elementOwner, {className: this.options.openEffect});

        this.windowOptions = {
            className:this.options.theme,
            width: this.options.width,
            height:this.options.height,
            showEffect:effect.show.bind(effect),
            hideEffect:effect.hide.bind(effect),
            minimizable:this.options.minimizable,
            maximizable:this.options.maximizable
            };
        this.effect = effect;
        this.window = new Window(this.windowOptions);
    },
    updateContent: function(options) {
        this.window.getContent().update($(this.options.contentId).innerHTML);
        if (options) {
            if (options.fields) {
                var form = $(this.options.formId)
                for(var field in options.fields) {
                    var elements = form.getInputs('hidden', field);
                    if (elements && elements.length > 0) {
                        $(elements[0]).value = options.fields[field];
                    }
                }
            }
        }
        this.window.setSize(this.options.width, this.options.height);
    },
	show: function(senderObj, options) {
        try {
            if (this.window == null)
                this.initWindow(senderObj, options);
            else {
                delete(this.effect.div);
                this.effect.html = senderObj;
            }

			this.updateContent();
            this.enable();
            this.initElements();
            
            if (this.options.position == 'center')
                this.window.showCenter();
            else {
                var position = this._getLocation(senderObj);
                this.window.setLocation(position.x, position.y);
                this.window.show();
            }

            if (typeof(this.onShowHandler) == 'function') {
                this.showOptions = options;
                window.setTimeout(this.onShowHandler, 600);
            }
        } catch (e) {
            alert(e.message);
        }
    },
	showPreviousPhoto: function () {
        if (this.currentPhotoIndex > 0) {
            this.currentPhotoIndex--;
        } else
			Form.Element.disable(this.options.prevId);
			this.updateBreedInfo(this.currentPhotoIndex);
    },
    showNextPhoto: function () {
        if (this.currentPhotoIndex <  this.photos.length - 1) {
            this.currentPhotoIndex++;
			this.updateBreedInfo(this.currentPhotoIndex);
        }
    },
    addPhotoInfo: function(src, name, age, color, description) {
        this.photos[this.photos.length] = {
            'src': src,
            'name': name,
            'age': age,
            'color': color,
            'desc': description };
    },
    updateBreedInfo: function(index) {
        if (index >= 0) {
            $(this.options.photoImageId).src = this.photos[this.currentPhotoIndex].src;
            $("breedAge").innerHtml = this.photos[index].age;
            $("breedColor").innerHtml = this.photos[index].color;
            $("breedDogName").innerHtml = this.photos[index].name;
            $("breedDesc").innerHtml = this.photos[index].description;
            if (this.currentPhotoIndex == this.photos.length - 2)
                Form.Element.enable(this.options.nextId);
            if (this.currentPhotoIndex == 1)
                Form.Element.enable(this.options.prevId);
        }
    },

    onPhotoShow: function() {
        this.currentPhotoIndex = this.showOptions;

        this.updateBreedInfo(this.currentPhotoIndex);
        if (this.photos.length < 2) {
            Form.Element.disable(this.options.prevId);
            Form.Element.disable(this.options.nextId);
        }
    },

    _getLocation: function(senderObj) {
        var position = Position.cumulativeOffset(senderObj);
        var size = senderObj.getDimensions();
		var sizeDoc = $('wrapper').getDimensions();
		var sizeWindow = $(this.options.contentId).getDimensions();

        switch(this.options.position) {
            case "topleft":
                return {x:position[1] - this.options.height , y:position[0] - (this.options.width - size.width)};
                break;
            case "topright":
                return {x:position[1] - this.options.height, y:position[0]};
                break;
            case "bottomright":
                return {x:position[1] + size.height , y:position[0]};
                break;
            case "center":
                return {x: (sizeDoc.height / 2  -  sizeWindow.height / 2) , y:(sizeDoc.width / 2  -  sizeWindow.width / 2)};
                break;
            case "bottomleft":
            default:
                return {x:position[1] + size.height, y:position[0] - (this.options.width - size.width)};
        }
    }
});

ImagePreloder = Class.create();
ImagePreloder.prototype = {
    initialize: function (options) {
        // default options
        this.options = Object.extend({
            indicatorPlaceholderId: "auto",
            indicatorSrc: baseUrl + 'resources/images/loader 32x32.gif',
            imageId: null,                 // content which will display in window
            panelId: null
        }, options || {});

        this.initIndicator();
        this.images = new Array();
        this.image = document.createElement('img');
        this.onSuccessHandler = this.onImageLoaded.bindAsEventListener(this);
        this.onFialedHandler = this.onImageFialed.bindAsEventListener(this);
        Event.observe(this.image, 'load', this.onSuccessHandler);
    },
    initIndicator: function() {
        if (this.options.panelId) {
            this.indicator = new Image();
            this.indicator.src = this.options.indicatorSrc
            this.indicator.style.display = 'none';
            this.indicator.style.position = 'absolute';
            this.indicator.style.zIndex = '9999';
            $(this.options.panelId).appendChild(this.indicator);
        } else {
            throw 'Async panel indicator initialization failed, panel Id is undefined.';
        }
    },

    show: function(imgUrl, index) {
        var imageObj = $(this.options.imageId);
        if (imageObj.index == index)
            return;

        imageObj.index = index;
        if (this.images[index]) {
            imageObj.src = imgUrl;
        } else if (imgUrl && imgUrl != '' && index >= 0) {
            this.image.loaded = false;
            this.image.src = imgUrl;
            this.image.index = index;

            if (!this.image.loaded) {
                this._setIndicatorPosition();
                Element.show(this.indicator);
                this.timeoutHandler = window.setTimeout(this.onFialedHandler, 10000);
            }
        }
    },

    onImageLoaded: function(eventObj) {
        var imageObj = $(this.options.imageId);
        imageObj.src = this.image.src;
        this.images[this.image.index] = true;
        this.image.loaded = true;

        if (Element.visible(this.indicator)) {
            Element.hide(this.indicator);
            if (this.timeoutHandler) {
                window.clearTimeout(this.timeoutHandler);
                this.timeoutHandler = null;
            }
        }
    },

    onImageFialed: function(eventObj) {
        Element.hide(this.indicator);
    },

    _setIndicatorPosition: function() {
        //var position = Position.cumulativeOffset(this.options.containerId);
        Position.absolutize(this.options.panelId);
        Position.relativize(this.options.panelId);

        var element = this.options.containerId ? this.options.containerId : this.options.panelId;
        var dim = $(element).getDimensions();
        var dimImage = $(this.indicator).getDimensions();

        var x = dim.height / 2 - dimImage.height / 2;
        var y = dim.width / 2 - dimImage.width / 2;

        this.indicator.style.left = y + 'px';
        this.indicator.style.top = x + 'px';
    }
}

ContentUpdater = Class.create();
ContentUpdater.prototype = {
    initialize: function (options) {
        this.setOptions(options);
        this.initEventHandlers();
        
        Event.observe(this.options.formId, 'submit', this.onSubmitHandler);
    },

    setOptions: function(options) {
        // default options
        this.options = {
            formId: null,
            targetSuccessId: null,
            targetFailureId: null
        }
        Object.extend(this.options, options || {});
        
        if (this.options.formId == null || $(this.options.formId) == null) {
            throw('Property formId should be set.');
        }
        if (this.options.targetSuccessId == null || typeof(this.options.targetSuccessId) != 'string') {
            throw('Property targetSuccessId should be set.');
        }
        if (this.options.targetFailureId == null || typeof(this.options.targetFailureId) != 'string') {
            this.options.targetFailureId = this.options.targetSuccessId;
        }
    },
    
    initEventHandlers: function() {
        this.onSubmitHandler = this.onSubmit.bindAsEventListener(this);
        this.onSuccessHandler = this.onSuccess.bindAsEventListener(this);
        this.onFailureHandler = this.onFailure.bindAsEventListener(this);
        this.onCompleteHandler = this.onComplete.bindAsEventListener(this);
    },
    
    onSubmit: function(sender, eventObj) {
        // stop submit event
        if (eventObj && eventObj.preventDefault)
            Event.stop(eventObj);
        var form = $(this.options.formId);
        
        form.disable();
        var paramsObj = this._getFormParams();
        new Ajax.Updater(
            { success: this.options.targetSuccessId, failure: this.options.targetFailureId }, 
            form.action, 
            { 
                parameters: paramsObj,
                onException: this.onFailureHandler,
                onFailure: this.onFailureHandler,
                onSuccess: this.onSuccessHandler,
                onComplete: this.onCompleteHandler
            }
        );
        return false;
    },
    
    onSuccess: function(transport, json) {

    },
    
    onFailure: function(transport, exObj) {

    },
    
    onComplete: function() {
        Form.enable(this.options.formId);
    },
    
    _getFormParams: function() {
        var params = {isAsyncPostBack: '1'};
        var elements = Form.getElements(this.options.formId);
        
        for(var i = 0; i < elements.length; i++) {
            if (typeof(elements[i]) == 'object') {
                var value = elements[i].getValue();
                if (value != null) {
                    params[elements[i].name] = value;
                }
            }
        }
        
        return params;
    }
};

DropDownUpdater = Class.create();
DropDownUpdater.prototype = {
    initialize: function (options) {
        this.setOptions(options);
        this.initEventHandlers();
    },

    setOptions: function(options) {
        // default options
        this.options = {
            targetSuccessId: null,
            targetFailureId: null,
            serviceUrl: null
        }
        Object.extend(this.options, options || {});

        if (this.options.serviceUrl == null || typeof(this.options.serviceUrl) != 'string') {
            throw('Updating Service URL should be set.');
        }
        
        if (this.options.targetSuccessId == null) {
            throw('Property targetSuccessId should be set.');
        }
        
        if ((this.options.targetFailureId == null || typeof(this.options.targetFailureId) != 'string') && typeof(this.options.targetSuccessId) == 'string') {
            this.options.targetFailureId = this.options.targetSuccessId;
        }
        
        if (typeof(this.options.targetSuccessId) == 'string') {
            this.options.targetSuccessId = [this.options.targetSuccessId];
        }
    },
    
    initEventHandlers: function() {
        this.onSuccessHandler = this.onSuccess.bindAsEventListener(this);
        this.onFailureHandler = this.onFailure.bindAsEventListener(this);
        this.onCompleteHandler = this.onComplete.bindAsEventListener(this);
    },
    
    update: function(sender, params) {
        params['isAsyncPostBack'] = true;
        if (!sender.name) {
            throw("Sender object don't have name property");
        } else {
            params[sender.name] = sender.value;
        }
        
        this._disableControls(this.options.targetSuccessId);
        /*new Ajax.Updater(
            { success: targetId, failure: this.options.targetFailureId }, 
            this.options.serviceUrl, 
            { 
                parameters: params,
                onException: this.onFailureHandler,
                onFailure: this.onFailureHandler,
                onSuccess: this.onSuccessHandler,
                onComplete: this.onCompleteHandler
            }
        );*/
        new Ajax.Request(this.options.serviceUrl,
            { 
                method: 'post',
                parameters: params,
                onException: this.onFailureHandler,
                onFailure: this.onFailureHandler,
                onSuccess: this.onSuccessHandler,
                onComplete: this.onCompleteHandler
            });
        return false;
    },
    
    onSuccess: function(transport, json) {
        if (transport.status == 200) {
            if (transport.responseXML && transport.responseXML.documentElement.childNodes.length > 0) {
                
                // clear dropdowns
                for(var i = 0; i < this.options.targetSuccessId.length; i++) {
                    var element = $(this.options.targetSuccessId[i]);
                    if (element) {
            			element.innerHTML = '';

                		// create Option objects
                        var options = transport.responseXML.documentElement.childNodes;
            			for(var j = 0; j < options.length; j++) {
            			    var newOption = this._createOption(options[j].attributes[0].value, options[j].attributes[1].value, options[j].attributes[2]);
        			        // add option to destination dropdown
        			        if(Prototype.Browser.IE) {
                                element.options.add(newOption);
                            } else {
                                element.add(newOption, null);
                            }
                        }
                    }
        		}
            }
            /*
            if (typeof(this.options.targetSuccessId) == 'object') {
                for(var i = 1; i < this.options.targetSuccessId.length && typeof(this.options.targetSuccessId[i]) == 'string'; i++) {
                    $(this.options.targetSuccessId[i]).update(transport.responseText);
                }
            }*/
        }
    },
    
    onFailure: function(transport, exObj) {

    },
    
    onComplete: function() {
        this._enableControls(this.options.targetSuccessId);
    },
    
    _createOption: function(text, value, selectedAttr) {
        var option = document.createElement("OPTION");
        option.text = text;
        option.value = value;
	    option.label = text;
	    if (selectedAttr && typeof(selectedAttr) == 'object') 
	        option.selected = selectedAttr.value;
	    return option;
    },
    
    _enableControls: function(controls) {
        for(var i = 0; i < controls.length; i++) {
            $(controls[i]).enable();
        }
    },
    
    _disableControls: function(controls) {
        for(var i = 0; i < controls.length; i++) {
            $(controls[i]).disable();
        }
    }
};

Tooltip = Class.create();
Tooltip.prototype = {
    initialize: function (options) {
        this.initEventHandlers();
        this.setOptions(options);
        this.setTarget(this.options.targetId);
        document.observe("dom:loaded", this.onLoadDelegate);
    },
    
    setOptions: function(options) {
        // default options
        this.options = {
            tooltipId: null,
            targetId: null,
            overTimeout: 0,
            outTimeout: 1000,
            showDuration: 0.4,
            hideDuration: 0.3,
            xOffset:10
        }
        
        Object.extend(this.options, options || {});
    },
    
    initEventHandlers: function() {
        this.mouseOverDelegate = this.onMouseOver.bindAsEventListener(this);
        this.mouseOutDelegate = this.onMouseOut.bindAsEventListener(this);
        this.mouseOutFinishedDelegate = this.onMouseOutFinished.bindAsEventListener(this);
        this.mouseOverFinishedDelegate = this.onMouseOverFinished.bindAsEventListener(this);
        this.onLoadDelegate = this.onLoad.bindAsEventListener(this);
    },
    
	addEventListeners: function(container) {
		Event.observe(container, "mouseover", this.mouseOverDelegate);
		Event.observe(container, "mouseout", this.mouseOutDelegate);
	},
	
	removeEventListeners: function(container) {
		Event.stopObserving(container, "mouseover", this.mouseOverDelegate);
		Event.stopObserving(container, "mouseout", this.mouseOutDelegate);
	},
	
	setTooltip: function(elementId) {
        var element = $(elementId);
        if (element) {
            this.panel = element.remove();
            document.body.appendChild(this.panel);
        } else {
            throw("Tooltip container '" + elementId + "' is not found.");
        }
	},
	
	setTarget: function(elementId) {
        var elements = $(document.body).getElementsBySelector(this.options.targetSelector);
        for(var i = 0; i < elements.length; i++) {
            this.addEventListeners(elements[i]);
        }
	},
	
	resetPosition: function() {
        this.panel.setStyle({
            display: 'none', 
            opacity: '0'
        });
        
        //top: (-1 * (this.panel.getHeight() - this.options.xOffset)) + 'px',
        //left:(parseInt(this.target.getWidth() / 2) - parseInt(this.panel.getWidth() / 2)) + 'px'
	},

    onMouseOver: function(eventObj) {
        this.disableHide = true;
        this.isMouseOut = false;
        
        //set target
        var target = $(eventObj.target);
        var position = target.cumulativeOffset();
        //set position
        this.panel.setStyle({
            display:'block', 
            opacity: '0',
            top: (position.top - this.panel.getHeight() + this.options.xOffset)  + 'px',
            left:(position.left - this.panel.getWidth() / 2 + target.getWidth() / 2) + 'px'
        });

        this.panel.show();
        var newPosition = parseInt(this.panel.style.top) - this.options.xOffset;

        this.panel.morph('top: ' + newPosition + 'px; opacity: 1;', { 
            duration: this.options.showDuration,
            afterFinish: this.mouseOverFinishedDelegate
        });
    },
    
    onMouseOut: function(senderObj, eventObj) {
        if (!this.disableHide) {
            var newPosition = parseInt(this.panel.style.top) - this.options.xOffset;
            this.panel.morph('top: ' + newPosition + 'px; opacity: 0;', { 
                duration: this.options.hideDuration,
                afterFinish: this.mouseOutFinishedDelegate
            });
        }
        
        this.isMouseOut = true;
    },
    
    onMouseOverFinished: function() {
        this.disableHide = false;
        
        if (this.isMouseOut) {
            this.onMouseOut();
        }
    },
    
    onMouseOutFinished: function() {
        this.resetPosition();
    },
    
    onLoad: function() {
        this.setTooltip(this.options.tooltipId);
        this.resetPosition();        
    }
};

var Reflector = {
    reflect: function(element) {
        var element = $(element);
        var options = {amount: 1/3, opacity: 1/3};
        Object.extend(options, arguments[1] || {});

        var p = element.parentNode, n = element.nextSibling;
        var d = 1.0/(element.height*options.amount);

        (element.height * options.amount).times( 
            function(line) {
                var h = Builder.node('div',
                    {style:'height:1px;overflow:hidden'},
                    [Builder.node('img', {src:element.src, style:'margin-top:-'+(element.height-line-1)+'px'} )]
                );
                p.insertBefore(h,n);
                $(h).setOpacity((1-d*line)*options.opacity);
            }
        );
    }
}

function parseFormAction(formId) {
    // bots defense
    if (formId){
        var form = $(formId)
        if (form) {
            var index = form.action.lastIndexOf('-');
            if (index > 0) {
                var digit = form.action.substring(index + 1, form.action.length - 1);
                if (digit > 0) {
                    form.action = form.action.substring(0, index) + '/';
                }
            }
        }
    }
	return true;
}

function reloadCapche(sender, imageId, imageSrc) {
    var capcheObj = $(imageId);

    var elements = document.getElementsByClassName('capche');
    if (elements) {
        var param = Math.random();
        for(var i = 0; i < elements.length; i++) {
            if (elements[i] && elements[i].src) {
                elements[i].src = imageSrc + '?' + param;
            }
        }
    }

    if(typeof(sender.reloadCounter) != 'undefined')
        sender.reloadCounter++;
    else
        sender.reloadCounter = 0;

    if(sender.reloadCounter > 2)
        sender.parentNode.style.display = 'none';
}
