var effects = {
    ac: {
        duration: 0.3,
        transition: Effect.Transitions.sinoidal
    },
    avs: {
        duration: 0.3,
        transition: Effect.Transitions.sinoidal
    },
    cart: {
        duration: 0.3,
        transition: Effect.Transitions.sinoidal,
        timeout: 200
    },
    def: {
        duration: 0.6,
        timeout: 1000
    },
    game: {
        duration: 0.6
    },
    header: {
        duration: 0.3,
        transition: Effect.Transitions.sinoidal,
        top: {
            duration: 0.1
        },
        timeout: 1500
    },
    hub: {
        duration: 0.4
    },
    newsletter: {
        duration: 0.3,
        transition: Effect.Transitions.sinoidal,
        top: {
            duration: 0.1
        },
        timeout: 5000
    },
    pager: {
        duration: 0.8,
        transition: Effect.Transitions.sinoidal,
        paginator: {
            opacity: 0.6
        }
    },
    registration: {
        input: {
            duration: 0.3
        },
        forgotten: {
            duration: 0.8
        },
        tooltip: {
            duration: 0.2,
            delay: 0.2
        }
    }
};

var options = {
    modal: {
        fade: true,
        fadeDuration: 0.2,
        closeOnClick: false
    }
};

var AC = {
    COLLAPSED: 'collapsed',
    EXPANDED : 'expanded',
    LUMINOUS : 'luminous'
};

var CONST = {
    class_col_left_row_cnt_box: '.col_left .row_cnt_box'
}

var CALLBACK = {
    updatePurchase: Prototype.emptyFunction
}

var Cookie = {

    set: function(name, value, options) {
        var expire = ''; 
        var o      = options || {};
        var path   = (o.path)   ? '; path=' + o.path : '; path=/';
        var domain = (o.domain) ? '; domain=' + o.domain : '';
        var secure = (o.secure == true) ? '; secure' : '';
        var date = new Date();

        if(Object.isNumber(o)) {
            date.setTime(date.getTime() + (o * 1000));
            expire = '; expires=' + date.toGMTString();
        } else if(o.expires) {
            date.setTime(date.getTime() + (o.expires * 1000));
            expire = '; expires=' + date.toGMTString();
        }

        document.cookie = name + "=" + escape(value) + expire + path + domain + secure;
        return this;
    },

    get: function(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for(var i = 0; i < ca.length; i++){
            var c = ca[i];
            while(c.charAt(0) == ' ')
                c = c.substring(1,c.length);
            if(c.indexOf(nameEQ) == 0)
                return unescape(c.substring(nameEQ.length,c.length));
        }
        return null;
    },

    unset: function(name) {
        this.set(name, '', -1, true);
        return this;
    }
};

Array.prototype.in_array = function(p_val) {
    for(var i = 0, l = this.length; i < l; i++) {
        if(this[i] == p_val) {
            return true;
        }
    }
    return false;
}

ProExtension = {
    findNearest: function(element, required, search) {
        element = $(element);
        if (element.tagName.toLowerCase() == required) return element;
        var search = search || 'up';
        switch (search) {
            case 'up':
                return element.up(required);
            case 'down':
                return element.down(required);
        }
        return false;
    },
    cufonRefresh: function(element) {
        element = $(element);
        element.select('.cufon800').each(function(el) {
            if (typeof(Cufon) == 'function') Cufon.replace(el);
        });
    },
    setHeight: function(element, size, type) {
        var type = type || 'px';
        $(element).setStyle({
            height: size + type
        });
    },
    getStyleValue: function(element, style) {
        return parseInt($(element).getStyle(style), 10);
    }
};

Element.addMethods(ProExtension);

Array.prototype.toJSON = function() {
    var results = [];
    this.each(function(object) {
        var value = Object.toJSON(object);
        if (!Object.isUndefined(value)) results.push(value);
    });
    return '[' + results.join(',') + ']';
};

ALoader = Class.create({
    initialize: function(){
        myDebug.log('ALoader - initialize');
        this.cls = 'aloader';
        this.last = null;
        this.lastAnchor = null;
        this.inProcess = false;
        this.onLoad = Prototype.emptyFunction;
        if(this.initBlocks()) {
            this.initAction();
            this.initSelectAction();
            this.initialize2();
        }
    },
    initBlocks: function() {
        myDebug.log('ALoader - initBlocks');
        // Use this to set/test your vital blocks,
        // return true if everything is OK else false.
        return true;
    },
    initAction: function(){
        $$('a.' + this.cls).each(function(el){
            el.observe('click', this.click.bind(this));
        }.bind(this));
    },
    initSelectAction: function(){
        $$('select.' + this.cls).each(function(el){
            el.observe('change', function(){
                this.loadFromUrl($(el.name + el.value).value);
                this.last = el;
            }.bind(this));
        }.bind(this));
    },
    reInitAction: function(from){
        from.select('.' + this.cls).each(function(el){
            el.observe('click', this.click.bind(this));
        }.bind(this));
    },
    beforeLoad: function(callback){
        myDebug.log('ALoader - beforeLoad');
        callback();
    },
    click: function(event){
        myDebug.log('ALoader - click');
        var el = Event.element(event).findNearest('a');
        Event.stop(event);
        if (this.inProcess) {
            myDebug.log('ALoader - stop click action, already processing!');
            return false;
        }
        this.inProcess = true;
        this.last = el;
        this.beforeLoad(function(){
            this.loadFromUrl(el.href);
            this.onLoad();
        }.bind(this));
    },
    loadFromUrl: function(url){
        myDebug.log('ALoader - loadFromUrl');
        this.inProcess = true;
        new Ajax.Request(url, {
            method: 'post',
            parameters: {
                aloader: true
            },
            onSuccess: this.success.bind(this),
            onFailure: this.failure.bind(this),
            onComplete: this.complete.bind(this)
        });
    },
    success: function(transport){
        myDebug.log('ALoader - success');
        this.process(transport.responseText.evalJSON());
    },
    failure: function(transport){
        myDebug.log('ALoader - failure');
    },
    complete: function(transport){
        myDebug.log('ALoader - complete');
        this.inProcess = false;
    },
    setUrlList: function(obj, name){
        obj.each(function(item){
            var link = $(name + item.id);
            if(link!=null)
                link.href = item.url;
        });
    },
    setUrlSelect: function(obj, name){
        obj.each(function(item){
            var selectItem = $(name + item.id);
            if (selectItem!=null)
                selectItem.value = item.url;
        });
    },
    setSelectValue: function(group, value) {
        var elements = $$(group);
        if (elements.size()>0)
            elements.first().value = value;
    },
    anchorBuilder: function(history) {
        var vars = new Array();
        Object.keys(history).each(function(variable) {
            vars.push(variable + '_' + history[variable]);
        });
        this.lastAnchor = vars.join(':');
        window.location = '#' + vars.join(':');
    },
    anchorLoader: function(url) {
        var anchor = window.location.hash.slice(1);
        if (!anchor.empty() && anchor != this.lastAnchor) {
            this.lastAnchor = anchor;
            anchor.split(':').each(function(v) {
                var pair = v.split('_');
                if(pair.length==2)
                    url.addVar(pair[0], pair[1]);
            });
            this.beforeLoad(function() {
                this.loadFromUrl(url.construct());
            }.bind(this));
        }
    }
});

CategoryIndexALoader = Class.create(ALoader, {
    initBlocks: function() {
        myDebug.log('CategoryIndexALoader - initBlocks');
        this.pageBlock = $('selectedPage');
        this.containerBlock = $('catContainer');
        this.catalogPagerTopBlock = $('catalogPager');
        this.catalogPagerBottomBlock = $('catalogPagerBottom');
        this.sortingBlock = $('catalogSorting');
        this.filtersBlock = $('filterCat');
        this.clearFiltersBlock = $('clearFilters');
        this.breadcrumbBlock = $('breadcrumbContainer') != null ? $('breadcrumbContainer') : $('breadcrumbwoj');
        if ($('titleH1') != null) {
        	this.titleWoj = $('titleH1');
        	
        }
        
        
        if(this.pageBlock!=null && 
           this.containerBlock!=null && 
           this.catalogPagerTopBlock!=null && 
           this.catalogPagerBottomBlock!=null &&
           this.sortingBlock!=null && 
           this.breadcrumbBlock!=null)
            return true;
        else {
            myDebug.err('CategoryIndexALoader - Fail to initialize all blocks');
            return false;
        }
    },
    initialize2: function(){
        myDebug.log('CategoryIndexALoader - initialize2');
        this.page = this.pageBlock.value;
        this.clearUrl = false;
        new PeriodicalExecuter(function() {
            this.anchorLoader(new UrlConstructor('category/index'));
        }.bind(this), 0.4);
    },
    beforeLoad: function(callback){
        myDebug.log('CategoryIndexALoader - beforeLoad');
        this.catalogPagerTopBlock.setOpacity(effects.pager.paginator.opacity);
        this.catalogPagerBottomBlock.setOpacity(effects.pager.paginator.opacity);
        new Effect.Opacity(this.containerBlock, {
            from: 1,
            to: 0.2,
            duration: effects.pager.duration / 2,
            afterFinish: callback
        });
    },
    process: function(obj){
        myDebug.log('CategoryIndexALoader - process');
        this.anchorBuilder(obj.history);
        var xOffset = (this.page < obj.page) ? -1 : 1;
        this.page = obj.page;
        
        if (obj.noresults) {
            $$('.no_result_search').invoke('update', obj.pagerHelper);
        }

        this.processFilters(obj);

        // Insert new page content
        this.containerBlock.insert(obj.categoryContent);

        // Get old page
        var contentOut = this.containerBlock.down('div.catalog_content');
        var tW = contentOut.getWidth();
        var totalW = contentOut.getOffsetParent().getWidth();
        var tH = contentOut.getHeight();
        contentOut.setStyle({
            height: tH + 'px',
            width: tW + 'px'
        });
        contentOut.absolutize();

        // Get new page
        var contentIn  = this.containerBlock.down('div.catalog_content', 1);
        contentIn.setStyle({
            left: xOffset * - totalW + 'px'
        });

        // Change page and remove the old one
        new Effect.Parallel([
            new Effect.Move(contentOut, {
                x: totalW * xOffset,
                y: 0,
                mode: 'absolute',
                sync: true
            }),
            new Effect.Move(contentIn, {
                x: totalW * xOffset,
                y: 0,
                mode: 'relative',
                sync: true
            })
        ], Object.extend({
            afterFinish: function() {
                contentOut.remove();
                this.processAfterFinish(obj);
            }.bind(this)
        }, effects.pager));

        // Scroll to the top of the page if needed
        try {
            if (this.last.cumulativeOffset().top > 700) {
                new Effect.ScrollTo('rootNode', effects.pager);
            }
        }
        catch(e) {}

        // Update all other blocks
        this.catalogPagerTopBlock.update(obj.catalogPager);
        resetOpacity(this.catalogPagerTopBlock);
        this.catalogPagerBottomBlock.update(obj.catalogPager);
        resetOpacity(this.catalogPagerBottomBlock);
        this.sortingBlock.update(obj.catalogSorting);
        this.breadcrumbBlock.update(obj.breadcrumbContainer);
        if (this.titleWoj != null)
        	this.titleWoj.update(obj.titleWOJ);

        var gameFoundBlock = $('gamesFound');
        if (gameFoundBlock!=null)
            gameFoundBlock.select('p').invoke('update', obj.gamesFound);

        if (typeof(DD_roundies) == 'object') {
            $('bsContainer').select('ignore').invoke('remove');
            $('bsContainer').select('.tr_lrb_roundify').each(function(el) {
                DD_roundies.roundify.call(el, [0,4,4,4]);
            });
        }
        new DropDown('ddBestsellers');
        Redirect.initUpperAImg(this.containerBlock);
        $$('.pagerHelper').invoke('update', obj.pagerHelper);

        $$(CONST.class_col_left_row_cnt_box).invoke('removeClassName', 'selected');
        $$(CONST.class_col_left_row_cnt_box + ' .game_name').invoke('removeClassName', 'colorH2').invoke('addClassName', 'colorW');

        this.setSelectValue('select[name="availability"]', obj.availabilityId);
        this.setSelectValue('select[name="publisher"]', obj.publisherId);
        this.setSelectValue('select[name="age"]', obj.ageId);

        this.setUrlList(obj.categories, 'category');
        this.setUrlList(obj.deals, 'deal');
        this.setUrlSelect(obj.availability, 'availability');
        this.setUrlSelect(obj.ages, 'age');
        this.setUrlSelect(obj.publishers, 'publisher');
        var categoryBlock = $('category' + obj.categoryId);

        if(categoryBlock!=null)
            categoryBlock.addClassName('selected').down('.game_name').addClassName('colorH2');
        var dealBlock = $('deal' + obj.dealId);

        if(dealBlock!=null)
            dealBlock.addClassName('selected').down('.game_name').addClassName('colorH2');

        // Initialise background
        var linkBlock = $('dynamicBackgroundLink');
        if(linkBlock!=null) {
            linkBlock.href = '#';
            linkBlock.setStyle({display: 'none'});
        }
        if (document.body.style.removeProperty) {
            // All browsers without IE < 9
            document.body.style.removeProperty("background");
        }
        else {
            // IE < 9
            document.body.style.removeAttribute("background-image");
            document.body.style.removeAttribute("background-attachment");
            document.body.style.removeAttribute("background-repeat");
            document.body.style.removeAttribute("background-position");
            document.body.style.removeAttribute("background-position-y");
            document.body.style.removeAttribute("background-color");
        }

        // Set background if needed
        if (obj.dynamic_background!=null && !Object.isUndefined(obj.dynamic_background.color) && !Object.isUndefined(obj.dynamic_background.url)) {

            var color = obj.dynamic_background.color;
            var url   = obj.dynamic_background.url;
            var link  = obj.dynamic_background.link;
            $(document.body).setStyle({background: 'url("' + url + '") no-repeat scroll center top #' + color + ''});
            
            if(link!='' && linkBlock!=null) {
                linkBlock.href = link;
                linkBlock.setStyle({display: 'block'});
            }
        }

        this.reInitAction(this.catalogPagerTopBlock);
        this.reInitAction(this.catalogPagerBottomBlock);
        this.reInitAction(this.sortingBlock);
        if (typeof(Cufon) == 'function')
            Cufon.refresh('.cufon800');
    },
    processFilters: function(obj) {
        myDebug.log('CategoryIndexALoader - processFilters');

        // Show / Hide clear filte button
        if(this.clearFiltersBlock!=null) {
            if (obj.clearFilters) {
                this.clearFiltersBlock.show();
                this.clearFiltersBlock.href = obj.clearUrl;
            }
            else
                this.clearFiltersBlock.hide();
        }

        // Manage filter bar
        if(this.filtersBlock!=null) {
            this.filtersBlock.replace(obj.catalogFilters);
            this.filtersBlock = $('filterCat');
            if(this.filtersBlock!=null)
                this.reInitAction(this.filtersBlock);
        }
    },
    complete: function() {
        myDebug.log('CategoryIndexALoader - complete');
        this.inProcess = false;
        
        // Start annimation of container block
        new Effect.Opacity(this.containerBlock, {
            from: 0.2,
            to: 1,
            duration: effects.pager.duration / 2,
            queue: 'end'
        });
    },
    processAfterFinish: function(obj){
        myDebug.log('CategoryIndexALoader - processAfterFinish');
        // normally only used by overloading (ex: MMES)
    }
});

TopicHubALoader = Class.create(CategoryIndexALoader, {
    initialize2: function(){
        myDebug.log('TopicHubALoader - initialize2');
        this.page = $('selectedPage').value;
        this.clearUrl = false;
        new PeriodicalExecuter(function() {
            this.anchorLoader(new UrlConstructor('topicHub/index'));
        }.bind(this), 0.4);
    },
    //redirect on select filters (not based on unreliable hidden input values)
    process: function($super,obj){
        myDebug.log('TopicHubALoader - process');
        obj.dealId = MvcSkel.getVar('topicHubDealId');
        //change clear filters url
        var clearUrl = new UrlSeoConstructor('TOPIC_HUB_INDEX');
        clearUrl.addSeoVar('topic',MvcSkel.getVar('topicHubUrlLabel'));
        obj.clearUrl = clearUrl.construct();
        
        var allGames = new UrlSeoConstructor('CATEGORY_INDEX_ALL').construct();
        if(obj.availabilityId > 0) {
            window.location = allGames +"?avlb="+obj.availabilityId;
        }
        if(obj.publisherId > 0) {
            window.location = allGames +"?pub="+obj.publisherId;
        }
        if(obj.ageId > 0) {
            window.location = allGames +"?age="+obj.ageId;
        }
        //call parent method
        $super(obj);
      
    }
});

HubIndexALoader = Class.create(ALoader, {
    initialize2: function(){
        myDebug.log('HubIndexALoader - initialize2');
        this.initCarousel();
        new PeriodicalExecuter(function() {
            this.anchorLoader(new UrlConstructor('hub/index'));
        }.bind(this), 0.4);
    },
    beforeLoad: function(callback){
        myDebug.log('HubIndexALoader - beforeLoad');
        var hubTopList = $('hubTopList').childElements();
        new Effect.Parallel([
            new Effect.Opacity(hubTopList[0], {
                sync: true,
                from: 1,
                to: 0.2
            }),
            new Effect.Opacity(hubTopList[1], {
                sync: true,
                from: 1,
                to: 0.2
            })
            ], Object.extend({
                queue: 'end',
                afterFinish: callback
            }, effects.hub));
    },
    process: function(obj){
        myDebug.log('HubIndexALoader - process');
        this.anchorBuilder(obj.history);
        if ($('breadcrumbContainer') != null)
        	$('breadcrumbContainer').update(obj.breadcrumbContainer);
        else
        	$('breadcrumbwoj').update(obj.breadcrumbContainer);
        
        $('viewAllGamesTop').update(obj.viewAllGamesTop);
        $('viewAllGamesBottom').update(obj.viewAllGamesBottom);
        if ($('hubCarouselHead')) {
            $('hubCarouselHead').replace(obj.hubCarouselHead);
        }
        if ($('carousel-lr')) {
            $('carousel-lr').update(obj.hubCarouselContent);
        }
        if ($('titleH1')) {
        	$('titleH1').update(obj.titleWOJ);
        }
       
        var hubTopList = $('hubTopList');
        hubTopList.update(obj.hubTopList);

        if (!Object.isUndefined(obj.background.color) && !Object.isUndefined(obj.background.url)) {
            var color = obj.background.color;
            var url   = obj.background.url;
            document.body.setStyle({
                background: 'url("' + url + '") no-repeat scroll center top #' + color
            });
            $('backgroundLink').value = obj.background.link;
        } else {
            document.body.removeAttribute('style');
        }

        hubTopList = $('hubTopList').childElements();
        new Effect.Parallel([
            new Effect.Opacity(hubTopList[0], {
                sync: true,
                from: 0.2,
                to: 1
            }),
            new Effect.Opacity(hubTopList[1], {
                sync: true,
                from: 0.2,
                to: 1
            })
            ], Object.extend({
                queue: 'end',
                beforeStart: this.updateControls.bind(this, obj)
            }, effects.hub));
        this.initCarousel();
    },
    updateControls: function(obj) {
        myDebug.log('HubIndexALoader - updateControls');
        $$('.col_left .row_cnt_box').invoke('removeClassName', 'selected');
        $$('.col_left .row_cnt_box .game_name').invoke('removeClassName', 'colorH2').invoke('addClassName', 'colorW');
        
        this.setUrlList(obj.categories, 'category');
        /*this.setUrlList(obj.deals, 'deal');
        this.setUrlSelect(obj.availability, 'availability');
        this.setUrlSelect(obj.ages, 'age');
        this.setUrlSelect(obj.publishers, 'publisher');*/
        $('category' + obj.categoryId).addClassName('selected').down('.game_name').addClassName('colorH2');
        //$('deal' + obj.dealId).addClassName('selected').down('.game_name').addClassName('colorH2');
        if (typeof(Cufon) == 'function') Cufon.refresh('.cufon800');
    },
    initCarousel: function() {
        myDebug.log('HubIndexALoader - initCarousel');
        new Carousel($('carousel'), $$('#carousel-content .slide'), $$('#carousel-arrow-right', '#carousel-arrow-left', 'a.carousel-jumper'), {
            duration: 0.8,
            transition: 'sinoidal',
            circular: false,
            step: 4,
            visibleSlides: 4,
            wheel: false
        });
    }
});

CatalogExpand = Class.create({
    initialize: function(){
        this.btn = $('headerCatalogExpandBtn');
        this.menu = $('headerCatalogExpand');
        if (!this.btn || !this.menu) return;
        this.timer = null;
        this.expanded = false;
        this.switchOn = false;
        this.btn.observe('mouseover', this.buttonOver.bind(this));
        this.btn.observe('mouseout', this.startHideTimer.bind(this));
        this.menu.observe('mouseover', this.clearHideTimer.bind(this));
        this.menu.observe('mouseout', this.startHideTimer.bind(this));
    },
    showMenu: function(){
        if (ShoppingCart) ShoppingCart.hide();
        HeaderNewsletter.hideBox();
        resetOpacity(this.menu);
        this.btn.addClassName('hover_now');
        if (this.btn.hasClassName('switch_on')) {
            this.btn.removeClassName('switch_on');
            this.switchOn = true;
        }
        this.menu.show();
        this.btn.cufonRefresh();
    },
    hideMenu: function(callback){
        this.menu.hide();
        callback();
    },
    hide: function() {
        if (!this.expanded)
            return;
        this.hideMenu(function(){
            this.expanded = false;
            this.btn.removeClassName('hover_now');
            this.btn.cufonRefresh();
            if (this.switchOn)
                this.btn.addClassName('switch_on');
        }.bind(this));
    },
    buttonOver: function(){
        this.clearHideTimer();
        if (this.expanded)
            return;
        this.expanded = true;
        this.showMenu();
    },
    clearHideTimer: function(){
        clearTimeout(this.timer);
    },
    startHideTimer: function(){
        this.timer = setTimeout(this.hide.bind(this), 200);
    }
});

Autocompleter = Class.create({
    initialize: function(){
        this.input = $('autocompleteGames');
        this.expand = $('headerAutocompleteExpand');
        this.form = $('searchForm');
        this.defClass = 'defaultText';
        if (!this.input || !this.form || !this.expand)
            return;
        this.cancel = this.form.down('a');
        this.moreInfo = $('acMoreInfo');
        this.searchArea = this.form.down('div.box_search_field');
        this.value = '';
        this.type = null;
        this.timeout = 500;
        this.hide = 3000;
        this.autohide = null;
        this.size = 3;
        this.selected = 0;
        this.count = 0;
        this.state = AC.COLLAPSED;
        this.area = null;
        this.init();
    },
    init: function(){
        this.cancel.observe('click', this.clearInput.bind(this));
        this.input.observe('focus',  this.activeInput.bind(this));
        this.input.observe('blur',   this.unactivateInput.bind(this));
        this.input.observe('keypress', this.inputKeyPress.bind(this));
        this.input.observe('keyup',    this.inputKeyUp.bind(this));
        this.moreInfo.observe('click',   this.goSearch.bind(this));
        this.searchArea.observe('click', this.activeInput.bind(this));
    },
    goSearch: function() {
        if (this.selected != 0 && AC.EXPANDED) {
            var item = $('autocompleteContent').down('a.row_cnt_box', this.selected - 1);
            window.location = item.href;
        } else {
            this.form.submit();
        }
    },
    setFocusState: function() {
        clearTimeout(this.area);
    },
    clearInput: function() {
        if (this.input.hasClassName(this.defClass)) return ;
        this.input.value = '';
        this.input.focus();
        this.hideResults();
    },
    activeInput: function() {
        clearTimeout(this.area);
        if (this.input.hasClassName(this.defClass)) {
            this.input.removeClassName(this.defClass).value = '';
            this.input.next().addClassName('cancelSearch');
        }
        this.setIcon();
        this.input.focus();
    },
    unactivateInput: function(event){
        this.area = setTimeout(function() {
            if (this.input.value.empty()) {
                this.input.addClassName(this.defClass).value = i18n('search_box_default_text');
                this.input.next().removeClassName('cancelSearch');
                this.cancel.focus();
                this.cancel.show();
            } else {
                this.hideResults();
            }
        }.bind(this), 500);
    },
    setIcon: function() {
        if (this.input.value.length == 0) this.cancel.hide();
        else this.cancel.show();
    },
    opacityResults: function(callback) {
        if (this.state == AC.LUMINOUS) return;
        this.state = AC.LUMINOUS;
        callback();
    },
    unopacityResults: function() {
        if (this.state != AC.LUMINOUS) return;
        this.state = AC.EXPANDED;
    },
    showResults: function() {
        if (this.state == AC.EXPANDED) return;
        this.state = AC.EXPANDED;
        this.expand.show();
    },
    hideResults: function() {
        if (this.state == AC.COLLAPSED) return;
        this.state = AC.COLLAPSED;
        this.expand.hide();
    },
    clearTimeout: function() {
        clearTimeout(this.autohide);
    },
    setHideTimeout: function() {
        this.clearTimeout();
        this.autohide = setTimeout(this.hideResults.bind(this), this.hide);
    },
    selectItem: function(id) {
        this.setHideTimeout();
        $$('.header_ac_expand .row_cnt_box').invoke('removeClassName', 'hover_now');
        var item = $('autocompleteContent').down('a.row_cnt_box', id - 1);
        if (item) item.addClassName('hover_now');
    },
    inputKeyPress: function(event){
        var key = event.keyCode || event.wich;
        switch (key) {
            case Event.KEY_RETURN:
                Event.stop(event);
                this.goSearch();
                break;
            case Event.KEY_TAB:
                Event.stop(event);
                break;
            case Event.KEY_ESC:
                Event.stop(event);
                this.clearInput();
                break;
        }
        return true;
    },
    inputKeyUp: function(event){
        var key = event.keyCode || event.wich;
        if (key == Event.KEY_DOWN) {
            if (this.selected < this.count) this.selectItem(++this.selected);
        }
        else if (key == Event.KEY_UP) {
            if (this.selected > 1) this.selectItem(--this.selected);
        }
        else {
            clearTimeout(this.type);
            this.type = setTimeout(this.beforeShow.bind(this), this.timeout);
            this.setIcon();
        }
        Event.stop(event);
    },
    beforeShow: function() {
        if (this.input.value.length < this.size) return;
        this.clearTimeout();
        this.value = this.input.value;
        if (this.state == AC.EXPANDED) this.opacityResults(this.load.bind(this));
        else this.load();
    },
    afterShow: function(transport) {
        var obj = transport.responseText.evalJSON();
        if (obj.content.empty()) {
            this.hideResults();
            return;
        }
        this.count = $('autocompleteContent').update(obj.content).select('a.row_cnt_box').size();
        Redirect.initUpperAFrom($('autocompleteContent'));
        this.moreInfo.down('span').update(obj.more);
        $('autocompleteContent').select('span.game_name_container').each(function(el) {
            var name = el.innerHTML;
            var re = new RegExp('(' + this.value + ')', 'i');
            el.innerHTML = name.replace(re, '<em class="colorH">$1</em>');
        }.bind(this));
        this.selected = 0;
        if (this.state == AC.LUMINOUS) this.unopacityResults();
        else if (this.state == AC.COLLAPSED) this.showResults();
    },
    load: function() {
        var url = new UrlConstructor('search/autocomplete');
        url.addVar('q', this.value);
        new Ajax.Request(url.construct(), {
            method: 'get',
            onSuccess: this.afterShow.bind(this)
        });
    }
});

Redirect = Class.create({
    initialize: function() {
        $$('select.redirect').invoke('observe', 'change', this.redirectBySelect.bind(this));
        this.initUpperAImg($('rootNode'));
    },
    initUpperAImg: function(container) {
        if (Prototype.Browser.IE) {
            container.select('img.redirectByUpperA').invoke('observe', 'click', this.redirectByUpperA.bind(this));
        }
    },
    initUpperAFrom: function(container) {
        if (Prototype.Browser.IE) {
            container.select('img.redirectByUpperA').invoke('observe', 'click', this.redirectByUpperA.bind(this));
        }
    },
    redirectBySelect: function(event) {
        var el = Event.element(event);
        if (url = $(el.name + el.value).value) window.location = url;
    },
    redirectByUpperA: function(event) {
        var a = Event.element(event).findNearest('a');
        if (a && !a.href.empty()) {
            window.location = a.href;
        }
    }
});

LanguageChooser = Class.create({
    initialize: function() {
        this.base = $('languageChooser');
        if (!this.base) return;
        this.list = this.base.next();
        this.timer = null;
        this.timeout = 2000;
        this.expanded = false;
        this.base.observe('click', this.toggle.bind(this));
        this.list.observe('click', this.toggle.bind(this));
        this.list.select('li').invoke('observe', 'click', this.setFlag.bind(this));
        this.list.observe('mouseover', this.clearHideTimeout.bind(this));
        this.list.observe('mouseout', this.setHideTimeout.bind(this));
    },
    toggle: function(event) {
        if (this.expanded) this.hide();
        else this.show();
    },
    show: function(event) {
        this.expanded = true;
        new Effect.Appear(this.list, Object.extend({
            queue: 'end',
            afterFinish: this.setHideTimeout.bind(this)
        }, effects.header));
    },
    hide: function(event) {
        this.expanded = false;
        this.clearHideTimeout();
        new Effect.Fade(this.list, Object.extend({
            queue: 'end'
        }, effects.header));
    },
    clearHideTimeout: function() {
        clearTimeout(this.timer);
    },
    setHideTimeout: function() {
        this.clearHideTimeout();
        this.timer = setTimeout(this.hide.bind(this), this.timeout);
    },
    setFlag: function(event) {
        var el = Event.element(event);
        var li = el.up('li');
        if (li!=undefined) {
            var src = li.down('img').src;
            this.base.down('img.flag_lang').src = src;
            this.list.down('li.current_lang img.flag_lang').src = src;
        }
    }
});

ModalWindows = Class.create({
    initialize: function(width) {
        this.width = width || 670;
        this.initStatic();
    },
    initStatic: function() {
        this.base = $('modalBase');
        if (!this.base) return;
        this.title     = this.base.down('.label_box');
        this.container = this.base.down('.modal_content');
        this.closeButtons = this.base.select('.modalCloseButton');
        $$('.smodal').invoke('observe', 'click', this.showStatic.bind(this));
        this.base.down('.modal_header').select('.closeModal').invoke('observe', 'click', Control.Modal.close);
    },
    reinitStatic: function(el) {
        $(el).select('.smodal').invoke('observe', 'click', this.showStatic.bind(this));
    },
    showStatic: function(event) {
        //patch fidelity Box
        if (event == null) {
            var container = $('modalCRM');
        }
        else {
            var el = Event.element(event);
            if (el.tagName != 'A') {
                var el = Event.element(event).up('a');
            }
            var container = $(el.className.match(/name-(\w+)\s?/)[1]);
        }
        try {
            var content = container.down('.content').innerHTML;
            var title   = container.down('.title').innerHTML;
            this.container.update(content);
            this.title.select('.title').invoke('update', title);
            Control.Modal.open(this.base, Object.extend({
                width: this.width,
                afterOpen: this.closeHandler.bind(this, this.base)
            }, options.modal));
            if (typeof(Cufon) == 'function') Cufon.refresh('.cufon800');
        } catch(e) {
        }
    },
    showModal: function(baseId, opt) {
        if (!$(baseId)) return;
        var opt = opt || { };
        var container = $(baseId);
        var width   = container.className.match(/w-(\d+)/)[1];
        var content = container.down('.content').innerHTML;
        var title   = container.down('.title').innerHTML;
        this.container.update(content);
        this.title.select('.title').invoke('update', title);
        var mopt = {
            closeButton: true
        };
        Object.extend(mopt, options.modal);
        Object.extend(mopt, {
            width: width || this.width,
            afterOpen: function() {
                this.closeHandler(this.base);
            }.bind(this)
        });
        Object.extend(mopt, opt);
        if (!mopt.closeButton) this.closeButtons.invoke('hide');
        Control.Modal.open(this.base, mopt);
        if (typeof(Cufon) == 'function') Cufon.refresh('.cufon800');
    },
    closeHandler: function(container) {
        container.select('.closeModal').invoke('observe', 'click', function() {
            Control.Modal.close();
        });
    },
    showText: function(content, title, width) {
        var title = title || '';
        var width = width || 600;
        this.container.update(content);
        this.title.select('.title').invoke('update', title);
        Control.Modal.open(this.base, Object.extend({
            width: width,
            afterOpen: this.closeHandler.bind(this, this.base)
        }, options.modal));
    }
});

ShoppingCart = Class.create({
    initialize: function() {
        this.cookie = 'cart';
        this.btn    = $('headerCartBox');
        if (!this.btn) return;
        this.btnOn  = this.btn.down('.cartOn');
        this.btnOff = this.btn.down('.cartOff');
        this.countGames = this.btn.down('.cart_count_games');
        this.cartExpand = $('headerCartExpand');
        this.cartContainer  = this.cartExpand.down('.expand_wrap');
        this.timer = null;
        this.expanded = false;
        this.maxItems = DEFINE.get('CART_MAXIMUM_ITEMS');
        this.maxGames = DEFINE.get('CART_MAXIMUM_GAMES');
        this.expire = DEFINE.get('CART_COOKIE_DAYS') *  84600;
        this.cart = new Array();
        this.loadFromCookie();
        this.initButtons();
        this.initRemove();
    //        this.initOutsideClick();
    },
    reset: function() {
        Cookie.unset(this.cookie);
        Cookie.set('sync', 1, this.expire);       
    },
    initButtons: function() {
        this.btn.observe('mouseover', this.showCart.bind(this));
        this.btn.observe('mouseout', this.startHideTimer.bind(this));//Hide cart content after effects.cart.timeout ms
        this.btn.observe('mouseover', this.clearHideTimer.bind(this));//Clear timer set     
        this.cartExpand.observe('mouseout', this.startHideTimer.bind(this));
        this.cartExpand.observe('mouseover', this.clearHideTimer.bind(this));
        $$('.addToCart').invoke('observe', 'click', this.add.bind(this));
    },
    clickInElement: function(event, el) {
        var clickX = event.clientX;
        var clickY = event.clientY;
        var offset = el.cumulativeOffset();
        var size = el.getDimensions();
        if (clickX < offset[0] || clickX > (offset[0] + size.width) || clickY < offset[1] || clickY > (offset[1] + size.height))
            return false;
        else
            return true;
    },
    initOutsideClick: function(event) {
        $(document.body).observe('click', function(event) {
            if (this.expanded && !this.clickInElement(event, this.btn) && !this.clickInElement(event, this.cartExpand))
                this.hideCart();
        }.bind(this));
    },
    loadFromCookie: function() {
        var c = Cookie.get(this.cookie);
        if (c) this.cart = $A(c.evalJSON());
    },    
    showCart: function() {
        CatalogExpand.hide();
        HeaderNewsletter.hideBox();
        resetOpacity(this.cartExpand);
        this.btn.addClassName('hover_now');
        this.btn.cufonRefresh();
        this.cartExpand.show();
        this.expanded = true;
    },
    hideCart: function() {
        this.cartExpand.hide();
        this.expanded = false;
        this.btn.removeClassName('hover_now');
        this.btn.cufonRefresh();
    },
    hide: function() {
        if (!this.expanded)
            return;
        this.hideCart();
    },
    clearHideTimer: function(){
        clearTimeout(this.timer);
    },
    startHideTimer: function(){
        this.timer = setTimeout(this.hide.bind(this), effects.cart.timeout);
    },
    setCartButton: function() {
        if (this.cart.size()) {
            this.btnOff.hide();
            this.btnOn.show();
            this.countGames.update(this.cart.size());
        } else {
            this.btnOn.hide();
            this.btnOff.show();
        }
    },
    addToCookie: function(gameObject) {
        var indexOfGameInCart = this.getGameIndexInCart(gameObject.id);
        if (this.cart.size() < this.maxItems && indexOfGameInCart < 0) {
            this.getContent(gameObject);
        }else if (this.cart.size() >= this.maxItems && indexOfGameInCart < 0) {
            var monostoreCode = MvcSkel.getVar('monostoreCode');
            if(monostoreCode!=false) {
                ModalWindows.showText(i18n('MONOSTORE_cart_maximum_reached', $H({
                    countItems: this.maxItems, 
                    countGames: this.maxGames,
                    monostore_code: monostoreCode
                })), i18n('cart_maximum_reached_title'));
            }
            else {
                ModalWindows.showText(i18n('cart_maximum_reached', $H({
                    countItems: this.maxItems,
                    countGames: this.maxGames
                })), i18n('cart_maximum_reached_title'));
            }
        }else {
            if (!this.expanded) this.showCart();
        }
    },
    getContent: function(gameObject) {
        var url = new UrlConstructor('game/add_to_cart');
        var c = this.cart.clone();
        c.push(gameObject);
        var monostoreCode = MvcSkel.getVar('monostoreCode');
        if(monostoreCode!=false)
            url.addVar('monostoreCode', monostoreCode);
        url.addVar('cart', c.toJSON());
        new Ajax.Request(url.construct(), {
            method: 'get',
            onSuccess: this.render.bind(this)
        });
    },
    checkMaxGames: function(obj) {
        if (obj.countGames > this.maxGames) {
            var monostoreCode = MvcSkel.getVar('monostoreCode');
            if(monostoreCode!=false) {
                ModalWindows.showText(i18n('MONOSTORE_cart_maximum_reached', $H({
                    countItems: this.maxItems, 
                    countGames: this.maxGames,
                    monostore_code: monostoreCode
                })), i18n('cart_maximum_reached_title'));
            }
            else {
                ModalWindows.showText(i18n('cart_maximum_reached', $H({
                    countItems: this.maxItems,
                    countGames: this.maxGames
                })), i18n('cart_maximum_reached_title'));
            }
            return false;
        }
        return true;
    },
    render: function(transport) {
        var obj = transport.responseText.evalJSON();
        if (this.checkMaxGames(obj)) {
            this.cart.push(obj.gameObject);
            Cookie.set(this.cookie, this.cart.toJSON(), this.expire);
            this.cartContainer.update(obj.content);
            this.setCartButton();
            this.initRemove();
            if (!this.expanded) this.showCart();
        }
    },
    updateCart: function() {
        var url = new UrlConstructor('game/add_to_cart');
        var monostoreCode = MvcSkel.getVar('monostoreCode');
        if(monostoreCode!=false)
            url.addVar('monostoreCode', monostoreCode);
        url.addVar('cart', this.cart.toJSON());
        new Ajax.Request(url.construct(), {
            method: 'get',
            onSuccess: this.renderUpdate.bind(this)
        });
    },
    renderUpdate: function(transport) {
        var obj = transport.responseText.evalJSON();
        this.cartContainer.update(obj.content);
        this.setCartButton();
        this.cartExpand.cufonRefresh();
        this.initRemove();
    },
    add: function(event) {
        var el = Event.element(event).findNearest('a');
        var gameId = parseInt(el.className.match(/gameId-(\w+)\s?/)[1]);
        var isAGift = el.className.match(/isAGift/)!=null;
        this.addToCookie({
            'id':gameId,
            'gift':isAGift
        });
        new Effect.ScrollTo('rootNode', Object.extend({
            queue: 'end'
        }, effects.game));
    },
    initRemove: function() {
        this.cartContainer.select('.delete_item_btn').invoke('observe', 'click', this.remove.bind(this));
    },
    remove: function(event) {
        var el = Event.element(event).findNearest('.row_cnt_box');
        var gameId = parseInt(el.className.match(/gameId-(\w+)\s?/)[1]);
        var total = this.cartExpand.down('.total_box');
        var indexOfGameInCart = this.getGameIndexInCart(gameId);
        if(indexOfGameInCart>=0) {
            this.cart.splice(indexOfGameInCart,1);
            Cookie.set(this.cookie, this.cart.toJSON(), this.expire);
            Cookie.set('sync', 1, this.expire);
            new Effect.Parallel([
                new Effect.SlideUp(el, {
                    sync: true
                }),
                new Effect.Morph(total, {
                    sync: true,
                    style: 'height:' + this.cart.size() * 60 + 'px'
                })
                ], Object.extend({
                    afterFinish: this.updateCart.bind(this)
                }, effects.cart));
        }
    },
    getGameIndexInCart: function(gameId) {
        var position = -1;

        this.cart.each(function(s, index) {
            if(s.id==gameId)
            	position = index;
        });

        return position;
    }
});

/**
* Class to handle information and error tooltips
*/
FormValidator = Class.create({

    initialize: function() {
        this.formValidationMasks = new Array();
        this.formValidationMasks['email'] = /^[a-z0-9\-\._]+@[a-z0-9\-\._]+\.[a-z]{2,5}$/i; // Email
        this.formValidationMasks['numeric'] = /^[0-9]*$/i; // Numeric
        this.formValidationMasks['alpha']= /^[a-z0-9\@\.]}$/i;
        this.formValidationMasks['password']= /^[a-zA-Z0-9]{6,20}$/i;

        this.formFunction = [
        'checkBirthday',
        'checkAvailability',
        'checkConfirmation',
        'checkNewsletter',
        ];
        this.messageAjax = new Array();
    },

    initFormValidation: function(nomForm) {

        //retrieve input and select fields
        var inputFields = $(nomForm).getElementsByTagName('INPUT');
        var selectBoxes = $(nomForm).getElementsByTagName('SELECT');
        var textareaField = $(nomForm).getElementsByTagName('TEXTAREA');
		
        var inputs = new Array();

        for (var i = 0; i < inputFields.length; i++) {
            type = inputFields[i].getAttribute("type");
            if (type == "text" || type=='password') {
                inputs[inputs.length] = inputFields[i]; //retrieve data
            }
        } //end foreach inputfield
		
        for (var nb = 0; nb < textareaField.length; nb++) {
            inputs[inputs.length] = textareaField[nb];
        }

        for (var no = 0; no < selectBoxes.length; no++) {
            inputs[inputs.length] = selectBoxes[no];
        } //end foreach selectbox

        //for each page input:
        inputs.each( function(el) {
            $(el);
            el.observe('focus', this.setFocused.bind(this));
            el.observe('blur', this.setUnFocused.bind(this));
            this.initTooltip(el);
        }.bind(this));

    }, //end init form


    initTooltip: function(el) {
        //event to mask error tooltips
        el.observe('focus', this.resetErrorTooltip.bindAsEventListener(this));
        //assign error control events
        if (el.tagName == 'SELECT') {
            el.observe('change', this.checkValid.bindAsEventListener(this));
        }
        el.observe('blur', this.checkValid.bindAsEventListener(this));

        //check control status
        if ( el.className.match(/validated/) ){
            return;
        }

        var xoffset = 0;
        try {
            xoffset = parseInt(el.className.match(/x-(\d+)/)[1]);
        } catch (e) {}
		
        var yoffset = 0;
        try {
            yoffset = parseInt(el.className.match(/y-(\d+)/)[1]);
        } catch (e) {}
		
        var x_symbol = '+';
        var y_symbol = '+';
        try {
            x_symbol = el.className.match(/xsymbol_(\S+)/)[1];
        }catch(e) {}
        try {
            y_symbol = el.className.match(/ysymbol_(\S+)/)[1];
        }
        catch(e) {}

        //error tooltip creation
        if (el.hasClassName('top_error_tip')) {
            new BadTip(el, 'error', {
                hook: {
                    target: 'topRight',
                    tip: 'bottomLeft'
                },
                width: 300,
                arrow: 'bottom',
                showOn: 'error:show',
                hideOn: 'error:hide',
                offset: {
                    x: -28,
                    y: -12
                }
            }, 'error');
        } else {
            new BadTip(el, 'error', {
                showOn: 'error:show',
                hideOn: 'error:hide',
                offset: {
                    x: eval('20' +x_symbol+ xoffset),
                    y: eval('0' +y_symbol+ yoffset)
                }
            }, 'error'
            );
        }
        //check if the tooltip is required
        if ( el.className.match(/notooltip/) ) {
            return;
        } else {
            //create help tooltip
            if (tipkey = el.className.match(/tip_(\w+)/)) {
                var msg = i18n(tipkey[1]);
                new BadTip(el, msg, {
                    showOn: 'focus',
                    hideOn: 'blur',
                    offset: {
                        x: 20 + xoffset,
                        y: 0 + yoffset
                    },
                    onShow: function(tip) {  }
                }
                );
            }
        }
        var inErrorState = el.previous('input[name="error"]');
        if (inErrorState) el.fire('error:show', inErrorState.value);
    },

    //mask the error tooltip when selecting an input
    resetErrorTooltip: function(event) {
        event.element().fire('error:hide');
    },

    //verify if a form element is valid
    checkValid: function(event) {
        var el = event.element();

        //retrieve type
        isValid = this.checkFormElements(el);
        if (isValid === false) {
            this.toError(el, i18n(el.className.match(/error_(\w+)/)[1]));
        } else if (isValid === true) {
            this.toOk(el);
        } else {
            this.toError(el, this.messageAjax[isValid]);
        }

    }, //end function checkValid

    checkFormElements: function(el) {
        var isValid = true;
        if (el.hasClassName('skip')) return true;
        if (el.value.empty() || el.value == -1 || (el.type == 'checkbox' && !el.checked)) return false;

        if (limitStartChar = el.className.match(/limitStart_(\w+)/)) {
            limitStartChar = limitStartChar[1];
        }
        if (limitStartChar == null) {
            limitStartChar = 1;
        }
		
        if (limitStopChar = el.className.match(/limitStop_(\w+)/)) {
            limitStopChar = limitStopChar[1];
        }
        if (limitStopChar == null) {
            limitStopChar = 250;
        }

        if (!eval("/^.{"+limitStartChar+","+limitStopChar+"}$/i").test(el.value)) {
            isValid = false;
        }
        if (!isValid) return isValid;

        if (type = el.className.match(/type_(\w+)/)) {
            type = type[1];
            if (this.formValidationMasks[type]) {
                //retrieve number of max character
                if (this.formValidationMasks[type].test(el.value)) {
                    isValid = true;
                } else {
                    isValid = false;
                }
            }
        }
        if (!isValid) return isValid;
		
        if (tabControlSup = el.className.match(/control_(\w+)/gi)) {
            for (var nb = 0; nb < tabControlSup.length; nb = nb + 1) {
                controlSup = tabControlSup[nb].split(/control_/);
                if (controlSup[1] != undefined) {
                    controlSup = controlSup[1];
                }
				
                if (this.in_array(controlSup, this.formFunction)) {
                    isValid = eval('this.' + controlSup + '(el);');
                }
            }
        }
        return isValid;
    },

    toError: function(el, msg) {
        if (msg) el.fire('error:show', msg);
        if (el.tagName != 'SELECT' && el.type !='checkbox' ) {
            el.removeClassName('validated');
            if (dataField = el.up('.data_field').down('.checked')) dataField.hide();
            new Effect.Morph(el.findNearest('div.input_box'), Object.extend(Object.clone(effects.registration.input), {
                style: 'border-color:#C80000; background-color:#FEEFEF;'
            }));
        }
    },

    toOk: function(el, msg) {
        el.fire('error:hide');
        el.addClassName('validated');
        if (msg) el.fire('error:show', msg);
        if (el.tagName != 'SELECT' && el.type !='checkbox') {
            if (dataField = el.up('.data_field').down('.checked')) dataField.show();
        }
    },

    setFocused: function(event) {
        var el = Event.element(event).findNearest('input');
        if (el == undefined) {
            el = Event.element(event).findNearest('textarea');
        }
        if (el == undefined) {
            return;
        }

        if (valueValid = el.className.match(/noAjax_(\w+)/)) {
            valueValid = valueValid[1];
            el.removeClassName('noAjax_'+valueValid);
        }
		
        if (dataField = el.up('.data_field').down('.checked')) dataField.hide();
        new Effect.Morph(el.up('div.input_box'), Object.extend(Object.clone(effects.registration.input), {
            style: 'border-color:#000; background-color:#FAFAFA;'
        }));
    },
    setUnFocused: function(event) {
        var el = Event.element(event).findNearest('input');
        if (el == undefined) {
            el = Event.element(event).findNearest('textarea');
        }
        if (el == undefined) {
            return;
        }
        new Effect.Morph(el.up('div.input_box'), Object.extend(Object.clone(effects.registration.input), {
            style: 'border-color:#949191; background-color:#FAFAFA;',
            queue: 'front'
        }));
    },

    //utility function equivalent to php in_array
    in_array: function(needle, hashstack) {
        needleHash = eval("/"+needle+"/g");
        if (needleHash.test(hashstack.join()) ) {
            return true;
        }else {
            return false;
        }
    },

    /******************
	* Special function
	*******************/

    checkConfirmation: function(el) {
        master = el.id;
        posid = el.id.indexOf("Confirm",0);
        if (posid > 0) {
            idvalue = el.id.substring(0, posid);
            testconfirm = $(idvalue);
        } else {
            testconfirm = $(el.id + 'Confirm');
        }
        if (testconfirm.value.empty() || testconfirm.value != el.value) {
            return false;
        } else {
            return true;
        }
    },
	
    checkAvailability: function(el) {
        if (valueValid = el.className.match(/noAjax_(\w+)/)) {
            valueValid = valueValid[1];
            if (valueValid == 'true' || valueValid == 'false') {
                return eval(valueValid);
            } else {
                return valueValid;
            }
        }
        var url = new UrlConstructor('login/check');
        url.addVar(type, el.value);
        if (el.value.length ==0) {
            return false;
        }
        var returnvalue = false;
        new Ajax.Request(url.construct(), {
            method: 'get',
            asynchronous : false,
            onSuccess: function (transport) {
                var obj = transport.responseText.evalJSON();
                if (obj.status)  {
                    returnvalue = true;
                } else {
                    returnvalue = el.name+'_checkAvailability';
                    this.messageAjax[returnvalue] = obj.message;
                }
                el.addClassName('noAjax_'+returnvalue);
            }.bind(this)
        });
        return returnvalue;
    },

    checkBirthday: function(event) {
        alert('birthday work todo');
        return;
        var el = event.element();
        if (el.value == -1) {
            if (this.a.indexOf(el.name) == -1) this.a.push(el.name);
            el.removeClassName('validated');
        } else {
            el.fire('error:hide');
            el.addClassName('validated');
            this.a = new Array();
        }
        if (this.a.size() == 3) $$('.year_field').first().fire('error:show', i18n('signup_birthday_invalid'));
    },
    checkNewsletter: function(event) {
        alert('newsletter work todo');
        return;
        var el = event.element();
        if (el.value == -1) {
            el.fire('error:show', i18n('signup_newsletter_invalid'));
            el.removeClassName('validated');
        }else {
            el.fire('error:hide');
            el.addClassName('validated');
        }
    }

} ); //end class FormValidator

HomeCarousel = Class.create({
    initialize: function(){
        if (!$('carousel')) return;
        this.initCarousel();
        this.initTabs();
    },
    initTabs: function() {
        var loading = 'tabSwitch';
        if($('carousel-tabs')) {
            new Control.Tabs('carousel-tabs', {
                beforeChange: function() {
                    if($(this.activeLink)) {
                        $(loading).show();
                    }
                },
                afterChange: function(){
                    var activeLink = this.activeLink;
                    $A(this.links).each(function(link){
                        var id = link.id.substr(0, 11);
                        var activeId = activeLink.id.substr(0, 11);
                        var state = link.id.substr(17, 6);
                        if(link.id == activeLink.id){
                            if (state != 'active') {
                                activeLink.hide();
                                $(id + '-link-active').show();
                                activeLink = $(id + '-link-active');
                                link.up().addClassName('active');
                                $$('.' + id + '-squares').each(function(item){
                                    item.show();
                                });
                            }
                        } else {
                            if (id != activeId) {
                                $(id + '-link-active').hide();
                                $(id + '-link-inactive').show();
                                link.up().removeClassName('active');
                                $$('.' + id + '-squares').each(function(item){
                                    item.hide();
                                });
                            }
                        }
                    });
                    if($(loading).visible()) {
                        new Effect.Fade($(loading));
                    }
                }
            });
        }
    },
    initCarousel: function() {
        var options = {
            duration: 1.3,
            transition: 'sinoidal',
            circular: false,
            step: 6,
            visibleSlides: 6,
            wheel: false
        };
        var options_small = {
            duration: 1.3,
            transition: 'sinoidal',
            circular: false,
            step: 4,
            visibleSlides: 4,
            wheel: false
        };
        var options2 = {
            duration: 1.3,
            transition: 'sinoidal',
            circular: false,
            step: 6,
            visibleSlides: 6,
            wheel: false,
            leftArrowId:  'carousel-arrow-left-2',
            rightArrowId: 'carousel-arrow-right-2',
            jumperClassName: 'carousel-jumper-2',
            carouselJumper:     'carousel-jumper-2-'
        };

        if ($('carousel-small')) {
            new Carousel($('carousel'), $$('#carousel-small .slide'), $$('#carousel-arrow-right', '#carousel-arrow-left', 'a.carousel-jumper'), options_small);
        } else {
            if ($('carousel')) new Carousel($('carousel'), $$('#carousel-content .slide'), $$('#carousel-arrow-right', '#carousel-arrow-left', 'a.carousel-jumper'), options);
        }
        if ($('carousel-2')) new Carousel($('carousel-2'), $$('#carousel-content-2 .slide'), $$('#carousel-arrow-right-2', '#carousel-arrow-left-2', 'a.carousel-jumper-2'), options2);
    }

});

HomeGondola = Class.create({
    initialize: function(){
        var jumpers = $$('a.gondola-jumper');
        if (jumpers.length > 0) {
            new Gondola($('gondola_content'), $$('#gondola_content .gondola_capsule'), $$('a.gondola-jumper'), {
                duration: 0.7,
                step: 1,
                visibleSlides: 1,
                wheel: false,
                auto: true,
                frequency: 3.5,
                imgURLs: window.imgURLs
            });
        }
    }
});
MediaViewer = Class.create({
    initialize: function(){
        this.elements = $$('.gameVideo').concat($$('.gameScreenshot'));
        this.elements.invoke('observe', 'click', this.mediaClick.bind(this));
        this.list = new Hash();
        this.elements.each(function(el) {
            if (!el.id.empty()) {
                var id = parseInt(el.id.match(/media-(\w+)/)[1]);
                this.list.set(id, el.down('input').value);
            }
        }.bind(this));
        this.current    = 1;
        this.defSize    = 400;
        this.defVideo   = {
            height: 390,
            width: 650
        };
        this.mediaBox   = $('modalMediaBox');
        this.loaderDiv  = this.mediaBox.down('div.loader');
        this.loader     = this.mediaBox.down('div.loader img');
        this.imgDiv     = this.mediaBox.down('div.screen');
        this.img        = this.mediaBox.down('div.screen img');
        this.img.observe('load', this.screenLoad.bind(this));
        this.keyhandler = this.mediaBox.down('input');
        this.keyhandler.observe('keyup', this.inputKeyUp.bind(this));
        this.next       = this.mediaBox.down('.arrow_right_wrapper');
        this.prev       = this.mediaBox.down('.arrow_left_wrapper');
        this.nextHandler = this.goNext.bind(this);
        this.prevHandler = this.goPrev.bind(this);
    },
    mediaClick: function(event) {
        var el = Event.element(event).findNearest('a');
        if (el.id.empty()) el = el.previous('a');
        Event.stop(event);
        this.current = parseInt(el.id.match(/media-(\w+)/)[1]);
        this.show();
    },
    inputKeyUp: function(event){
        var key = event.keyCode || event.wich;
        if (key == Event.KEY_RIGHT) {
            this.goNext();
        } else if (key == Event.KEY_LEFT) {
            this.goPrev();
        }
        Event.stop(event);
    },
    goNext: function() {
        if (this.current == this.list.size()) return;
        this.current++;
        this.refresh();
        this.show();
    },
    goPrev: function() {
        if (this.current == 1) return;
        this.current--;
        this.refresh();
        this.show();
    },
    DDRoundies :function() {
        if (typeof(DD_roundies) == 'object') DD_roundies.roundify.call(this.mediaBox, [5,5,5,5]);
    },
    refresh: function() {
        if (this.current == 1) {
            Event.stopObserving(this.prev, 'click', this.prevHandler);
            this.prev.down('a').addClassName('arrow_btn_media_inactive');
        } else {
            Event.observe(this.prev, 'click', this.prevHandler);
            this.prev.down('a').removeClassName('arrow_btn_media_inactive');
        }
        if (this.current == this.list.size()) {
            Event.stopObserving(this.next, 'click', this.nextHandler);
            this.next.down('a').addClassName('arrow_btn_media_inactive');
        } else {
            Event.observe(this.next, 'click', this.nextHandler);
            this.next.down('a').removeClassName('arrow_btn_media_inactive');
        }
    },
    getMediaType: function() {
        var link = this.list.get(this.current);
        return link.match(/\.(\w+)$/)[1];
    },
    getImageDimensions: function(newImg, cb) {
        try {
            if (!newImg.height || !newImg.width) throw('can\'t get image size');
            cb({
                height: newImg.height,
                width: newImg.width
            });
        } catch(e) {
            setTimeout(function() {
                this.getImageDimensions(newImg, cb);
            }.bind(this), 200);
        }
    },
    getImageSize: function(link, callback) {
        var newImg = new Image();
        newImg.src = link;
        this.getImageDimensions(newImg, function(size) {
            callback(size);
        });
    },
    resizeArrow: function() {
        var center = parseInt((this.mediaBox.getHeight() - 110) / 2);
        this.next.setStyle({
            top: center + 'px'
        });
        this.prev.setStyle({
            top: center + 'px'
        });
        var loaderTop  = parseInt((this.mediaBox.getHeight() - this.loader.getHeight()) / 2);
        var loaderLeft = parseInt((this.mediaBox.getWidth() - this.loader.getWidth()) / 2);
        this.loaderDiv.setStyle({
            top: loaderTop + 'px',
            left: loaderLeft + 'px'
        });
    },
    resize: function() {
        var link = this.list.get(this.current);
        var type = this.getMediaType();
        if (type == 'flv') {
            var size = $('flowplayer').getDimensions();
            this.startEffect(size);
        } else {
            this.getImageSize(link, function(size) {
                this.startEffect(size);
            }.bind(this));
        }
    },
    startEffect: function(size) {
        this.refresh();
        new Effect.Morph(this.mediaBox, Object.extend(Object.clone(effects.game), {
            style: 'width: ' + size.width + 'px; height: ' + size.height + 'px;',
            afterUpdate: function(){
                this.resizeArrow();
                Control.Modal.current.position();
            }.bind(this)
        }));
    },
    removeHandler: function() {
        this.loaderDiv.hide();
        this.imgDiv.hide();
        this.removeFlash();
        if (typeof(DD_roundies) == 'object') {
            var prev = this.mediaBox.previous();
            if (prev.tagName.toLowerCase() == 'ignore') prev.remove();
        }
    },
    afterOpenHandler: function(event) {
        this.resizeArrow();
        this.keyhandler.focus();
        this.DDRoundies();
        this.mediaBox.select('.closeModal').invoke('observe', 'click', function() {
            Control.Modal.close();
        }.bind(this));
    },
    screenLoad: function(link) {
        this.loaderDiv.hide();
        this.imgDiv.show();
        this.resize();
        new Effect.Opacity(this.img, Object.extend(Object.clone(effects.game), {
            from: 0.1,
            to: 1
        }));
    },
    show: function() {
        if (Control.Modal.current) {
            new Effect.Opacity(this.img, Object.extend(Object.clone(effects.game), {
                from: 1,
                to: 0.1,
                afterFinish: this.showCallback.bind(this)
            }));
        } else this.showCallback();
    },
    showCallback: function() {
        var link = this.list.get(this.current);
        var type = link.match(/\.(\w+)$/)[1];
        switch(type) {
            case 'jpeg':
            case 'gif':
            case 'jpg':
                this.removeFlash();
                this.loaderDiv.show();
                if (!Control.Modal.current) {
                    Control.Modal.open(this.mediaBox, Object.extend(Object.clone(options.modal), {
                        width: this.defSize,
                        height: this.defSize,
                        closeOnClick: 'overlay',
                        afterOpen: function() {
                            this.img.setOpacity(0.1);
                            this.img.src = link;
                            this.afterOpenHandler();
                        }.bind(this),
                        afterClose: this.removeHandler.bind(this)
                    }));
                } else {
                    this.img.setOpacity(0.1);
                    this.img.src = link;
                    this.keyhandler.focus();
                }
                break;
            case 'flv':
                this.removeHandler();
                var video = new Element('div', {
                    id: 'flowplayer'
                });
                video.setStyle({
                    width: this.defVideo.width + 'px',
                    height: this.defVideo.height + 'px'
                });
                this.mediaBox.insert(video);
                var params = {
                    'clip': link
                };
                if ($('flowplayerLicense').value) {
                    params = {
                        key: $('flowplayerLicense').value,
                        clip: {
                            url:link,
                            scaling:'fit'
                        }
                    };
                }
                $f('flowplayer', {
                    src: '/skins/bad/flash/flowplayer.commercial-3.1.5.swf',
                    wmode: 'opaque'
                }, params);
                if (!Control.Modal.current) {
                    Control.Modal.open(this.mediaBox, Object.extend({
                        width: this.defVideo.width,
                        height: this.defVideo.height,
                        afterOpen: function() {
                            this.afterOpenHandler();
                            this.resize();
                        }.bind(this),
                        afterClose: this.removeHandler.bind(this)
                    }, options.modal));
                } else {
                    this.DDRoundies();
                    this.resize();
                }
                break;
        }
    },
    removeFlash: function() {
        if (fdiv = $('flowplayer')) {
            this.mediaBox.setStyle({
                width: fdiv.getWidth()+'px',
                height: fdiv.getHeight()+'px'
            });
            fdiv.remove();
        }
    }
});

BadTip = Class.create({
    initialize: function(el, content, opt, type) {
        var opt = opt || {};
        this.type = type || 'info';
        this.className = 'righttip';
        this.opt = Object.extend(Object.clone(effects.registration.tooltip), {
            effect: 'appear',
            className: this.className,
            hook: {
                target: 'rightMiddle',
                tip: 'leftMiddle'
            }
        });

        if (MvcSkel.getVar('portalId') == 'woj_') {
            var cntx = $('context').getValue();
            if (!/checkout_index/.test(cntx) && !/download_index/.test(cntx)) opt.offset.y = opt.offset.y - 125;
        }
        
        this.opt = Object.extend(this.opt, opt);
        this.tip = new Tip(el, this.getContent(content), this.opt);
        if (!Object.isUndefined(opt.width)) this.tip.tip.setStyle({
            width: opt.width + 'px'
        });
    },
    getContent: function(content) {
        var type = Object.isUndefined(this.opt.arrow) ? '' : ' ' + this.opt.arrow;
        var el = new Element('div', {
            'class': this.type + type
        });
        var span = new Element('span', {
            'class': 'tip roundify'
        }).update(content);
        var div = new Element('div', {
            'class': 'pointer'
        }).update('pointer');
        el.appendChild(span);
        el.appendChild(div);
        return el;
    }
});

Registration = Class.create({
    initialize: function() {
        try {
            this.initSubmitForm($('fmCreate'), $('btnCreate'));
        } catch(e) {};
        try {
            this.initSubmitForm($('fmLogin'), $('btnLogin'));
        } catch(e) {};
        try {
            this.initForgetPassword();
        } catch(e) {};
        this.initValidation();
        try {
            this.initLoginErrors();
        } catch (e) {};
    },
    initSubmitForm: function(form, submit) {
        if (!form) return;
        var inputs = form.select('input[type="text"]');
        inputs = inputs.concat(form.select('input[type="password"]'));
        inputs = inputs.concat(form.select('.type_gender'));
        var smb = form.select('input[type="submit"]').size();
        if (smb) form.observe('submit', this.submitFormHandler.bindAsEventListener(this, submit));
        inputs.invoke('observe', 'focus', this.setFocused.bind(this));
        inputs.invoke('observe', 'blur', this.setUnFocused.bind(this));
        inputs = inputs.concat(form.select('select'));
        inputs = inputs.each(function(el) {
            if (!el.hasClassName('wotooltip')) this.initTooltip(el);
            if (!smb) el.observe('keypress', this.inputKeyPress.bindAsEventListener(this, form, submit));
        }.bind(this));
        submit.observe('click', this.submitForm.bindAsEventListener(this, form, inputs));
        submit.observe('submit:click', this.submitForm.bindAsEventListener(this, form, inputs, submit));
        
        submit.observe('mouseover', function() {
            submit.focus();
            if (this.checkFormElements(inputs)) submit.addClassName('enabled').cufonRefresh();
            else submit.removeClassName('enabled').cufonRefresh();
        }.bind(this));
        submit.observe('mouseout', function() {
            setTimeout(function() {
                submit.cufonRefresh();
            }, 100);
        });
        new PeriodicalExecuter(function(pe) {
            if (this.checkFormElements(inputs)) submit.addClassName('enabled').cufonRefresh();
            else submit.removeClassName('enabled').cufonRefresh();
        }.bind(this), 1);
        return inputs;
    },
    initTooltip: function(el) {
        if (offset = el.className.match(/xoffset-(\d+)/)) xoffset = parseInt(offset[1]);
        else xoffset = 0;
        new BadTip(el, 'error', {
            showOn: 'error:show',
            hideOn: 'error:hide',
            offset: {
                x: 20 + xoffset,
                y: 0
            }
        }, 'error');
        if (tipkey = el.className.match(/tip_(\w+)/)) {
            var msg = i18n(tipkey[1]);
            new BadTip(el, msg, {
                showOn: 'focus',
                hideOn: 'blur',
                offset: {
                    x: 20 + xoffset,
                    y: 0
                },
                onShow: function(tip) {  }
            });
        }
        el.observe('focus', this.activateField.bindAsEventListener(this));
    },
    initValidation: function() {
        try {
            this.a = new Array();
            this.initValidationCreate();
        } catch (e) { };
        try {
            this.initValidationAccount();
        } catch (e) { };
    },

    initValidationCreate : function() {
        $$('select.birthday').invoke('observe', 'blur', this.checkBirthday.bindAsEventListener(this));
        $$('select.birthday').each(function(el) {
            this.checkBirthday(false, el, true);
        }.bind(this));
        $('regEmail').observe('blur', this.checkConfirmation.bindAsEventListener(this, $('regEmail'), $('regEmailConfirm')));
        $('regEmailConfirm').observe('blur', this.checkConfirmation.bindAsEventListener(this, $('regEmail'), $('regEmailConfirm')));
        $('regPassword').observe('blur', this.checkValid.bindAsEventListener(this));
        $('regPassword').observe('blur', this.checkConfirmation.bindAsEventListener(this, $('regPassword'), $('regPasswordConfirm')));
        $('regPasswordConfirm').observe('blur', this.checkConfirmation.bindAsEventListener(this, $('regPassword'), $('regPasswordConfirm')));
        var newsletterType = $('newsletterType');
        newsletterType.observe('blur', this.checkNewsletter.bindAsEventListener(this));
        newsletterType.observe('change', this.checkNewsletter.bindAsEventListener(this));
        this.checkNewsletter(false, newsletterType, true);
        if (DEFINE.get('SUBSCRIPTION_LOGIN_AVAILABILITY')) {
            $('regEmail').observe('blur',  this.checkAvailability.bindAsEventListener(this));
        } else {
            $('regEmail').observe('blur',  this.checkValid.bindAsEventListener(this));
        }
        var nickname = $('nickname');
        if (nickname)
            nickname.observe('blur',  this.checkAvailability.bindAsEventListener(this));
        var regLname = $('regLname');
        var regFname = $('regFname');
        if (regLname && regFname) {
            regLname.observe('blur', this.checkValid.bindAsEventListener(this));
            regFname.observe('blur', this.checkValid.bindAsEventListener(this));
            this.checkValid(false, regLname, true);
            this.checkValid(false, regFname, true);
        }
        var gender = $$('input.genderField');
        if (gender.size()) {
            gender.invoke('observe', 'click', this.checkGender.bindAsEventListener(this, gender));
            gender.invoke('observe', 'blur', this.checkGender.bindAsEventListener(this, gender));
            this.checkGender(false, gender);
        }
        
    },
    initValidationAccount : function() {
        var lEmail = $('loginEmail');
        lEmail.observe('blur', this.checkValid.bindAsEventListener(this));
        if (!lEmail.value.empty()) this.checkValid(null, lEmail);
    },
    initForgetPassword: function() {
        var link    = $('linkForgetPassword');
        var email   = $('login_forgot_email');
        var close   = $('btnForgetPasswordClose');
        var ok      = $('btnForgetPassword');
        this.initTooltip(email);

        link.observe('click', this.showToggleForgetPassword.bind(this));
        email.observe('blur', this.checkValid.bindAsEventListener(this));
        email.observe('blur', this.setUnFocused.bind(this));
        email.observe('focus', this.setFocused.bind(this));
        close.observe('click', this.showToggleForgetPassword.bind(this));

        ok.observe('click', this.sendForgetPasswordRequest.bind(this));
        ok.observe('mouseover', function() {
            ok.focus();
            if (this.checkFormElements([email])) ok.addClassName('enabled');
            else ok.removeClassName('enabled');
        }.bind(this));
        new PeriodicalExecuter(function(pe) {
            if (this.checkFormElements([email])) ok.addClassName('enabled');
            else ok.removeClassName('enabled');
        }.bind(this), 1);
    },
    initLoginErrors: function() {
        var err = $('loginError');
        setTimeout(function() {
            if (err && !err.value.empty()) $('loginEmail').fire('error:show', err.value);	
        }, 500);
    },
    showToggleForgetPassword: function(event) {
        var box = $('boxForgetPassword');
        new Effect.toggle(box, 'blind',
            Object.extend(
                Object.clone(effects.registration.forgotten), {
                    beforeStart: function() {
                        $('login_forgot_email').fire('error:hide');
                    },
                    afterFinish: function() {
                        if (!box.visible()) {
                            box.down('.forgotten_step1').show();
                            box.down('.forgotten_step2').hide();
                            $('btnForgetPassword').removeClassName('enabled');
                            $('login_forgot_email').fire('error:hide');
                        }
                    }
                }));
    },
    sendForgetPasswordRequest: function(event) {
        var email = $('login_forgot_email');
        var url = new UrlConstructor('login/forgot_password');
        url.addVar('email', email.value);
        new Ajax.Request(url.construct(), {
            method: 'get',
            onSuccess: function(transport){
                var obj = transport.responseText.evalJSON();
                if (obj.status) {
                    $('forgotten_step1').hide();
                    $('forgotten_step2').show();
                    $('btnForgetPasswordClose').addClassName('enabled');
                } else {
                    email.fire('error:show', i18n('forgot_password_error'));
                }
            }
        });
    },
    isValid: function(type, value) {
        switch(type) {
            case 'email':
                return /^[a-z0-9\-\._]+@[a-z0-9\-\._]+\.[a-z]{2,5}$/i.test(value);
            case 'login':
                return /^[a-z0-9\@\.\-_]{1,255}$/i.test(value);
            case 'nickname':
                return /^[a-z0-9]{1,20}$/i.test(value);
            case 'password':
                return /^[a-z0-9]{6,20}$/i.test(value);
            case 'notempty':
                return /^.+$/i.test(value);
            case 'fname':
                return /^[\w\-\s\'\.]+$/i.test(value);
            case 'lname':
                return /^[\w\-\s\'\.]+$/i.test(value);
                break;
        }
    },
    checkFormElements: function(elements) {
        var isValid = true;
        elements.each(function(el) {
            if (el.hasClassName('skip')) return false;
            if (!el.hasClassName('validated') || el.value.empty() || el.value == -1) isValid = false;
        }.bind(this));
        return isValid;
    },
    submitForm: function(event, form, inputs, submit) {
        var el = submit || event.element().findNearest('a');
        if (el.hasClassName('enabled')) {
            if (el.hasClassName('ajaxSend')) {
                if (form.id == 'fmLogin') {
                    var url = new UrlConstructor('actionController/shop/login');
                } else {
                    var url = new UrlConstructor('actionController/shop/registration');
                }
                new Ajax.Request(url.construct(), {
                    method: 'post',
                    parameters: form.serialize(true),
                    onSuccess: this.changeAccountBox.bind(this)
                });
            } else {
                form.submit();
            }
        } else {
            inputs.each(function(inp) {
                if (!inp.hasClassName('validated') && (type = inp.className.match(/type_(\w+)/))) {
                    inp.fire('error:show', i18n('signup_' + type[1] + '_invalid'));
                }
            });
        }
    },
    changeAccountBox : function(transport) {
        var obj = transport.responseText.evalJSON();
        $('login_section').update(obj.content);
    },
    submitFormHandler: function(event, submit) {
        event.stop();
        submit.focus();
        submit.fire('submit:click');
    },
    inputKeyPress: function(event, form, submit) {
        var key = event.keyCode || event.wich;
        if (key == Event.KEY_RETURN) {
            submit.focus();
            setTimeout(function() {
                if (submit.hasClassName('enabled')) form.submit();
            }, 1000);
        }
    },
    checkValid: function(event, element, disable) {
        var element = element ? element : event.element();
        var value = element.value;
        if (type = element.className.match(/type_(\w+)/)) {
            type = type[1];
            if (this.isValid(type, value)) this.toOk(element);
            else if (!disable) this.toError(element, i18n('signup_' + type + '_invalid'));
        }
    },
    checkConfirmation: function(event, master, confirm) {
        var type = confirm.className.match(/type_(\w+)/)[1];
        if (confirm.value.empty() || confirm.value != master.value)
            this.toError(confirm, i18n('signup_' + type + '_confirmation_not_match'));
        else this.toOk(confirm);
    },
    checkAvailability: function(event) {
        var el = Event.element(event).findNearest('input');
        if (type = el.className.match(/type_(\w+)/)) {
            var type = type[1];
            if (this.isValid(type, el.value)) {
                var url = new UrlConstructor('login/check');
                url.addVar(type, el.value);
                new Ajax.Request(url.construct(), {
                    method: 'get',
                    onSuccess: this.setStatus.bind(this, el)
                });
            } else this.toError(el, i18n('signup_' + type + '_invalid'));
        }
    },
    setStatus: function(el, transport) {
        var obj = transport.responseText.evalJSON();
        if (obj.status) this.toOk(el);
        else this.toError(el, obj.message);
    },
    checkGender: function(event, gender) {
        var el = gender.find(function(radio) {
            return radio.hasClassName('type_gender');
        });
        if (gender.find(function(radio) {
            return radio.checked;
        })) {
            el.fire('error:hide');
            el.addClassName('validated');
        } else {
            el.removeClassName('validated');
        }
    },
    checkBirthday: function(event, element, disable) {
        var el = element ? element : event.element();
        if (el.value == -1) {
            if (this.a.indexOf(el.name) == -1) this.a.push(el.name);
            el.removeClassName('validated');
        } else {
            el.fire('error:hide');
            el.addClassName('validated');
            this.a = new Array();
        }
        if (this.a.size() == 3 && !disable) $$('.year_field').first().fire('error:show', i18n('signup_birthday_invalid'));
    },
    checkNewsletter: function(event, element, disable) {
        var el = element ? element : event.element();
        if (el.value == -1 && !disable) {
            el.fire('error:show', i18n('signup_newsletter_invalid'));
            el.removeClassName('validated');
        } else {
            el.fire('error:hide');
            el.addClassName('validated');
        }
    },
    setFocused: function(event) {
        var el = Event.element(event).findNearest('input');
        if (el.up('.data_field')) {
            if (dataField = el.up('.data_field').down('.checked')) dataField.hide();
            var inputBox = el.up('div.input_box');
            if (inputBox) {
                new Effect.Morph(inputBox, Object.extend(Object.clone(effects.registration.input), {
                    style: 'border-color:#000; background-color:#FAFAFA;'
                }));
            }
        }
    },
    setUnFocused: function(event) {
        var el = Event.element(event).findNearest('input');
        if (el.up('.data_field')) {
            var inputBox = el.up('div.input_box');
            if (inputBox) {
                new Effect.Morph(inputBox, Object.extend(Object.clone(effects.registration.input), {
                    style: 'border-color:#949191; background-color:#FAFAFA;',
                    queue: 'front'
                }));
            }
        }
    },
    activateField: function(event) {
        event.element().fire('error:hide');
    },
    toError: function(el, msg) {
        el.removeClassName('validated');
        if (dataField = el.up('.data_field').down('.checked')) dataField.hide();
        if (msg) el.fire('error:show', msg);
        new Effect.Morph(el.findNearest('div.input_box'), Object.extend(Object.clone(effects.registration.input), {
            style: 'border-color:#C80000; background-color:#FEEFEF;'
        }));
    },
    toOk: function(el) {
        el.fire('error:hide');
        el.addClassName('validated');
        if (dataField = el.up('.data_field').down('.checked')) dataField.show();
    }
});

Howitworks = Class.create({
    initialize: function() {
        if (!$('howitworks')) return;
        this.btn_expand_all = $('hiw_expand_all');
        this.btn_collapse_all = $('hiw_collapse_all');
        var topic_group = $$('.topic_group');
        topic_group.each(function(el) {
            el.observe('click', this.toggleTopic.bindAsEventListener(el));
        }.bind(this));
        this.btn_expand_all.observe('click', function() {
            topic_group.each(function(el) {
                if (!el.hasClassName('expanded_topic')) {
                    el.addClassName('expanded_topic');
                }
            });
        });
        this.btn_collapse_all.observe('click', function() {
            topic_group.each(function(el) {
                if (el.hasClassName('expanded_topic')) {
                    el.removeClassName('expanded_topic');
                }
            });
        });
    },
    toggleTopic: function(event) {
        var topic = event.element();
        if (!topic.hasClassName('topic_group')) {
            topic = topic.up('.topic_group');
        }
        if (topic.hasClassName('expanded_topic')) {
            topic.removeClassName('expanded_topic');
        }
        else {
            topic.addClassName('expanded_topic');
        }
    }
});

HeaderNewsletter = Class.create(Registration, {
    initialize: function() {
        if (!(this.box = $('headerNewsletterExpand'))) return;
        this.newsletterState  = this.box.down('.header_newsletter');
        if (!(this.newsletter = $('linkNewsletter'))) return;
        this.forgetOk         = this.box.down('.forget_ok');
        this.forgetEmail      = $('newsletterHeaderForgetEmail');
        this.newsletterEmail  = $('newsletterHeaderEmail');
        this.newsletterMode   = $('newsletterHeaderMode');
        this.button           = $('btnHeaderNewsletter');
        this.timer   = null;
        this.block   = false;
        this.valid   = true;
        this.email   = null;
        this.mode    = null;
        this.updated = false;
        this.linkOverlay = this.newsletter.next();
        this.newsletterEmail.observe('focus', this.emptyEmailField.bindAsEventListener(this));
        this.newsletter.observe('click',  this.showBox.bindAsEventListener(this));
        this.linkOverlay.observe('mouseover', this.clearHideTimeout.bindAsEventListener(this));
        this.linkOverlay.observe('mouseout',  this.setHideTimeout.bindAsEventListener(this));
        this.box.observe('mouseover', this.clearHideTimeout.bindAsEventListener(this));
        this.box.observe('mouseout',  this.setHideTimeout.bindAsEventListener(this));
        this.button.observe('click',  this.saveSubscription.bindAsEventListener(this));
        this.newsletterEmail.observe('blur', this.checkEmail.bindAsEventListener(this));
        this.newsletterMode.observe('change', this.checkNewsletter.bindAsEventListener(this));
        this.initTooltip(this.newsletterEmail);
        this.initTooltip(this.newsletterMode);
    },
    showBox: function() {
        if (this.block) return;
        CatalogExpand.hide();
        if (ShoppingCart) ShoppingCart.hide();
        new Effect.BlindDown(this.linkOverlay, Object.extend(Object.clone(effects.newsletter.top), {
            queue: 'end',
            beforeStart: function() {
                this.block = true;
                this.clearHideTimeout();
            }.bind(this)
        }
        ));
        new Effect.Appear(this.box, Object.extend(Object.clone(effects.newsletter), {
            queue: 'end'
        }));
        $('tooltip_area').style.zIndex = 5;
    },
    hideBox: function() {
        if (!this.newsletter) return;
        this.clearHideTimeout();
        if (!this.updated) {
            this.newsletterEmail.fire('error:hide');
            this.newsletterMode.fire('error:hide');
        }
        new Effect.Fade(this.box, Object.extend(Object.clone(effects.newsletter), {
            queue: 'end',
            beforeStart: function() {
                this.clearHideTimeout();
            }.bind(this),
            afterFinish: this.clearHideTimeout.bind(this)
        }));
        new Effect.BlindUp(this.linkOverlay, Object.extend(Object.clone(effects.newsletter.top), {
            queue: 'end',
            beforeStart: this.clearHideTimeout.bind(this),
            afterFinish: function() {
                this.block = false;
                this.newsletterState.show();
                this.clearHideTimeout();
                if (!this.updated) {
                    this.newsletterEmail.removeClassName('error');
                    this.newsletterMode.removeClassName('error');
                }
            }.bind(this)
        }));
        $('tooltip_area').style.zIndex = 2;
    },
    clearHideTimeout: function() {
        clearTimeout(this.timer);
    },
    setHideTimeout: function() {
        this.clearHideTimeout();
        this.timer = setTimeout(this.hideBox.bindAsEventListener(this), effects.newsletter.timeout);
    },
    emptyEmailField: function() {
        if (this.newsletterEmail._cleared) return;
        this.newsletterEmail.clear();
        this.newsletterEmail._cleared = true;
    },
    checkEmail: function() {
        this.email = $('newsletterHeaderEmail').value;
        if (!this.email) {
            this.newsletterEmail.fire('error:show', i18n('signup_email_invalid'));
            this.newsletterEmail.addClassName('error');
            this.valid = false;
            return;
        }
        if (this.email == 'Enter your email') {
            this.newsletterEmail.fire('error:show', i18n('signup_email_invalid'));
            this.newsletterEmail.addClassName('error');
            this.valid = false;
            return;
        }
        this.newsletterEmail.removeClassName('error');
        this.valid = true;
    },
    checkNewsletter: function() {
        this.mode  = $('newsletterHeaderMode').value;

        if (this.mode == '-1') {
            this.newsletterMode.fire('error:show', i18n('signup_newsletter_invalid'));
            this.newsletterMode.addClassName('error');
            this.valid = false;
            return;
        }
        this.newsletterMode.removeClassName('error');
        this.valid = true;
    },
    saveSubscription: function() {
        this.checkEmail();
        this.checkNewsletter();
        if (! this.valid) return;
        new Ajax.Request('/newsletter/subscribe/email/' + this.email + '/mode/' + this.mode, {
            method: 'get',
            onSuccess: function(transport) {
                var obj = transport.responseText.evalJSON();
                if (obj.error) {
                    this.newsletterEmail.addClassName('error');
                    this.newsletterEmail.fire('error:show', i18n('signup_email_invalid'));
                    return;
                }
                if (obj.content.empty()) {
                    return;
                }
                this.newsletterEmail.removeClassName('error');
                this.box.down(3).update(obj.content);
                this.updated = true;
                $('btnHeaderNewsletter').observe('click', this.hideBox.bindAsEventListener(this));
            }.bind(this)
        });
    }
});

ModalCRMWindow = Class.create(ModalWindows, {
	
});

ModalAVSWindow = Class.create(Registration, {
    initialize: function() {
        if (parseInt(MvcSkel.getVar('showAvs'))) {
            ModalWindows.showModal('modalAVS', {
                closeButton: false,
                afterOpen: this.initAvsProcess.bind(this),
                beforeClose: this.beforeCloseModal.bind(this)
            });
        }
    },
    initAvsProcess: function() {
        this.a = new Array();
        this.avsAvailableAttempts = parseInt(MvcSkel.getVar('avsAvailableAttempts'));
        this.avsSuccess = false;
        this.avs  = $('avsBox');
        this.info = $('noteAvsBoxInfo');
        this.infoBox = this.info.down('.atten_note_box');
        this.form = $('noteAvsForm');
        this.formBtn = this.form.down('.button_container');
        this.check = $('avsPinCheck');
        this.check.down('.button_container').observe('click', this.checkPin.bind(this));
        $('avsCancelRemoveAction').observe('click', this.cancelAndRemoveAdultGames.bind(this));
        this.create = $('avsPinCreate');
        this.pinInput = this.check.down('input');
        this.errorTip = new BadTip(this.pinInput, 'error', {
            hook: {
                target: 'topRight',
                tip: 'bottomLeft'
            },
            width: 300,
            arrow: 'bottom',
            showOn: 'error:show',
            hideOn: 'error:hide',
            offset: {
                x: -40,
                y: -42
            }
        }, 'error');
        Event.observe(window, 'resize', this.updateModalPosition.bind(this));
        Event.observe(window, 'scroll', this.updateModalPosition.bind(this));
        this.avs.observe('click', this.toggleInfo.bind(this));
        this.initSubmitForm(this.create, this.formBtn);
        var inputs = this.create.select('input[type="text"]');
        inputs.invoke('observe', 'blur', this.checkValid.bindAsEventListener(this));
        $$('select.birthday').invoke('observe', 'blur', this.checkBirthday.bindAsEventListener(this));
    },
    beforeCloseModal: function() {
        this.pinInput.fire('error:hide');
    },
    updateModalPosition: function() {
        this.errorTip.tip.position();
        if (Control.Modal.current) Control.Modal.current.position();
    },
    hideForm: function(event) {
        if (this.form.visible()) {
            new Effect.BlindUp(this.form, Object.extend(Object.clone(effects.avs), {
                queue: 'end',
                afterUpdate: this.updateModalPosition.bind(this)
            }));
        }
    },
    toggleForm: function(event) {
        if (!this.avsAvailableAttempts || this.avsSuccess) return false;
        if (this.form.visible()) {
            new Effect.BlindUp(this.form, Object.extend(Object.clone(effects.avs), {
                queue: 'end',
                afterUpdate: this.updateModalPosition.bind(this),
                afterFinish: this.toRetrieveState.bind(this)
            }));
        } else {
            new Effect.BlindDown(this.form, Object.extend(Object.clone(effects.avs), {
                queue: 'end',
                afterUpdate: this.updateModalPosition.bind(this),
                beforeStart: this.toRetrieveState.bind(this)
            }));
        }
    },
    toggleInfo: function() {
        if (!this.avsAvailableAttempts) this.toAttempErrorState();
        if (this.info.visible()) {
            new Effect.BlindUp(this.info, Object.extend(Object.clone(effects.avs), {
                afterFinish: this.toggleForm.bind(this),
                afterUpdate: this.updateModalPosition.bind(this)
            }));
        } else {
            new Effect.BlindDown(this.info, Object.extend(Object.clone(effects.avs), {
                afterFinish: this.toggleForm.bind(this),
                afterUpdate: this.updateModalPosition.bind(this)
            }));
        }
    },
    checkPin: function() {
        this.check.request({
            onSuccess: function(transport) {
                var obj = transport.responseText.evalJSON();
                var berr = new BADErrorManager(obj, false);
                if (berr.noErrors()) {
                    Control.Modal.close();
                } else {
                    this.pinInput.fire('error:show', berr.getErrorByLabel('pin').msg);
                }
            }.bind(this)
        });
    },
    cancelAndRemoveAdultGames: function() {
    	new Ajax.Request('/checkout/avsCancel', {
    		method: 'post',
    		onSuccess: function(transport) {
                var obj = transport.responseText.evalJSON();
                Cookie.set('sync', 1);
                //if OK, just reload, else redirect home
                var destinationUrl = window.location.href;
                if(obj.mustRedirect) {
                    var homeUrl = new UrlSeoConstructor('INDEX_INDEX');
                    destinationUrl = homeUrl.construct();
                }
                window.location.href = destinationUrl;
    		}
    	});
    },
    hideAllNote: function() {
        ['note_good', 'note_retrieve', 'note_error', 'note_error3'].each(function(info) {
            this.infoBox.down('.' + info).hide();
        }.bind(this));
        ['atten_good', 'atten_retrieve', 'atten_error'].each(function(box) {
            this.infoBox.removeClassName(box);
        }.bind(this));
    },
    toSuccessState: function(userEmail) {
        this.hideAllNote();
        this.infoBox.addClassName('atten_good');
        this.infoBox.down('.note_good').show();
        this.avsSuccess = true;
        $('avsUserEmail').update(userEmail);
        this.hideForm();
    },
    toRetrieveState: function() {
        this.hideAllNote();
        this.infoBox.addClassName('atten_retrieve');
        this.infoBox.down('.note_retrieve').show();
    },
    toErrorState: function(attempts) {
        $('attemptCounter').update(attempts);
        this.hideAllNote();
        this.infoBox.addClassName('atten_error');
        this.infoBox.down('.note_error').show();
    },
    toAttempErrorState: function() {
        this.hideAllNote();
        this.infoBox.addClassName('atten_error');
        this.infoBox.down('.note_error3').show();
        this.hideForm();
    },
    createPin: function() {
        this.create.request({
            onSuccess: function(transport) {
                var obj = transport.responseText.evalJSON();
                var berr = new BADErrorManager(obj, false);
                if (berr.noErrors()) {
                    this.toSuccessState(obj.userEmail);
                } else {
                    this.avsAvailableAttempts = parseInt(obj.available);
                    if (this.avsAvailableAttempts)
                        this.toErrorState(this.avsAvailableAttempts);
                    else
                        this.toAttempErrorState();
                }
            }.bind(this)
        });
    },
    submitForm: function(event, form, inputs) {
        var el = event.element().findNearest('a');
        if (el.hasClassName('enabled')) {
            this.createPin();
        } else {
            inputs.each(function(inp) {
                if (!inp.hasClassName('validated') && (type = inp.className.match(/type_(\w+)/))) {
                    inp.fire('error:show', i18n('signup_' + type[1] + '_invalid'));
                }
            });
        }
    }
});

ModalUserReviewWindow = Class.create(ModalWindows, {
    initialized : false,
    initStatic: function() {
        this.base = $('modalUserReviews');
        this.userReviewClass = null;
        if (!this.base) return;
        this.container = this.base.down('.review_content');
        window.userReviewWindow = this;
        $$('.dmodal').invoke('observe', 'item:click', this.showStatic.bind(this));
        $$('.dmodal').invoke('observe', 'window:check', this.checkWindowState.bind(this));
        this.base.down('.modal_header').select('.closeModal').invoke('observe', 'click', window.userReviewWindow.closeModalWindow);
        if (Cookie.get('userReview')) {
            Cookie.unset('userReview');
            $$('.dmodal').first().fire('window:check');
        }
    },
    checkWindowState: function(event) {
        var el = Event.element(event);
        if (el.tagName != 'A') {
            return;
        }
        if (el.rel != "auth") {
            return;
        }
        el.fire('item:click');
    },
    showStatic: function(event) {
        var el = Event.element(event);
        if (el.tagName != 'A') {
            el = el.up('a');
        }
        if (el.rel != "auth") {
            var url = new UrlSeoConstructor('LOGIN_DEFAULT');
            url.addVar('dest', MvcSkel.getVar('redirect'));
            Cookie.set('userReview', 1, 3600);
            window.location = url.construct();
            return;
        }
        if (this.initialized) {
            Control.Modal.open(this.base, options.modal);
            return;
        }
        try {
            new Ajax.Request('/game/review/', {
                onSuccess: function(transport) {
                    var obj = transport.responseText.evalJSON();
                    window.userReviewWindow.container.update(obj.content);
                    Control.Modal.open(window.userReviewWindow.base, Object.extend({
                        width: window.userReviewWindow.width,
                        afterOpen: function() {
                            var rating = $$('div.rating_container');
                            rating.each(function(el) {
                                new Control.Rating(el, {
                                    value: 3,
                                    multiple: true,
                                    afterChange: function(value) {
                                        window.userReview.rating = value;
                                    }
                                });
                            });
                            window.userReviewClass = new UserReview($(window.userReviewWindow.base).down('.modal_body'));
                            $(window.userReviewWindow.container).select('.closeModal').each(
                                function(el){
                                    el.cufonRefresh();
                                }
                                );
                            $(window.userReviewWindow.container).select('.showPreview').each(
                                function(el){
                                    el.cufonRefresh();
                                }
                                );
                            $(window.userReviewWindow.container).select('.closeModal').invoke('observe', 'click',window.userReviewWindow.closeModalWindow);
                            $(window.userReviewWindow.container).select('.showPreview').invoke('observe', 'click', window.userReviewClass.showPreview.bind(window.userReviewClass));
                        }
                    }, options.modal));
                }
            });
            this.initialized = true;
        } catch(e) {
        }
    },
    closeModalWindow: function() {
        Control.Modal.close();
        if (window.userReview.mode == 'preview') {
            window.userReview.body.down(0).next(0).remove();
            window.userReview.body.down(0).show();
            window.userReview.mode = 'edit';
        }
        window.userReviewWindow.container.select('.review_element').each(function(el) {
            el.fire('error:hide');
        });
    }
});

UserReview = Class.create(Registration, {
    body: null,
    titleElement: null,
    reviewElement: null,
    rating: 3,
    gameId: null,
    mode:  'edit',
    initialize: function(body) {
        window.userReview = this;
        this.body = body;
        this.valid = true;
        this.initToolTips();
    },
    initToolTips: function() {
        $$('.review_element').each( function(el) {
            el.id = 'review-' + el.type;
            if (el.type == 'textarea') {
                window.userReview.reviewElement = el;
                el.observe('blur', window.userReview.checkReviewValidity.bindAsEventListener(window.userReview));
                if (!$('counter-review')){
                    $(el).insert({
                        after: '<div id="counter-review"></div>'
                    });
                }
                makeItCount(el.id, 'counter-review',1000);
            } else {
                window.userReview.titleElement  = el;
                el.observe('blur', window.userReview.checkTitleValidity.bindAsEventListener(window.userReview));
            }
            if (offset = el.className.match(/xoffset-(\d+)/)) xoffset = parseInt(offset[1]);
            else xoffset = 0;
            new BadTip(el, 'error', {
                showOn: 'error:show',
                hideOn: 'error:hide',
                offset: {
                    x: 20 + xoffset,
                    y: 0
                }
            }, 'error');
        });
    },
    showPreview: function() {
        this.body.select('.review_element').each(function(el) {
            window.userReview.checkValidity(el);
        });
        if (! this.reviewValid || ! this.titleValid) return;
        this.gameId = $('userReviewsBox').className.match(/gameId-(\w+)\s?/)[1];
        var params = {
            'gameId': this.gameId,
            'review': this.reviewElement.value,
            'title': this.titleElement.value,
            'rating': this.rating
        };
        new Ajax.Request('/game/preview/', {
            method: 'post',
            parameters: params,
            onSuccess: function(transport) {
                this.mode = 'preview';
                var obj = transport.responseText.evalJSON();
                if (obj.invalid == 'title') {
                    this.titleElement.fire('error:show', obj.error);
                    return;
                }
                if (obj.invalid == 'review') {
                    this.reviewElement.fire('error:show', obj.error);
                    return;
                }
                if (obj.content.empty()) {
                    return;
                }
                this.titleElement.fire('error:hide');
                this.reviewElement.fire('error:hide');
                this.body.down(0).hide();
                new Insertion.After(this.body.down(0), obj.content);
                this.body.down('.user_reviews_box_content').select('.editModal').each(
                    function(el){
                        el.cufonRefresh();
                    }
                    );
                this.body.down('.user_reviews_box_content').select('.publishModal').each(
                    function(el){
                        el.cufonRefresh();
                    }
                    );
                this.body.down('.user_reviews_box_content').select('.closeModal').each(
                    function(el){
                        el.cufonRefresh();
                    }
                    );

                this.body.down('.user_reviews_box_content').select('.editModal').invoke('observe', 'click',this.editModalWindow);
                this.body.down('.user_reviews_box_content').select('.closeModal').invoke('observe', 'click',window.userReviewWindow.closeModalWindow);
                this.body.down('.user_reviews_box_content').select('.publishModal').invoke('observe', 'click',this.publishModalWindow.bind(this));
            }.bind(this)
        });
    },
    editModalWindow: function() {
        window.userReview.body.down(0).next(0).replace(window.userReview.body.down(0));
        window.userReview.body.down(0).show();
    },
    publishModalWindow: function() {
        var params = {
            'gameId': this.gameId,
            'review': this.reviewElement.value,
            'title': this.titleElement.value,
            'rating': this.rating
        };
        new Ajax.Request('/game/rate/', {
            method: 'post',
            parameters: params,
            onSuccess: function(transport) {
                var obj = transport.responseText.evalJSON();
                if (obj.content.empty()) {
                    return;
                }
                this.mode = 'publish';
                this.body.update(obj.content);
                this.body.down('.modal_content').select('.closeModal').each(
                    function(el){
                        el.cufonRefresh();
                    }
                    );
                this.body.down('.modal_content').select('.closeModal').invoke('observe', 'click',window.userReviewWindow.closeModalWindow);
            }.bind(this)
        });
    },
    checkValidity: function(el) {
        if (el.type == 'textarea') {
            this.checkReviewValidity();
        } else {
            this.checkTitleValidity();
        }
    },
    checkTitleValidity: function() {
        if (!this.titleElement.value) {
            this.titleElement.fire('error:show', i18n('user_review_title_invalid'));
            this.titleValid = false;
            return;
        }
        this.titleElement.fire('error:hide');
        this.titleValid = true;
    },
    checkReviewValidity: function() {
        if (!this.reviewElement.value) {
            this.reviewElement.fire('error:show', i18n('user_review_text_invalid'));
            this.reviewValid = false;
            return;
        }
        this.reviewElement.fire('error:hide');
        this.reviewValid = true;
    }

});

BADErrorManager = Class.create({
    initialize: function(obj, modal) {
        this.base      = $('modalError');
        this.title     = this.base.down('.label_box');
        this.container = this.base.down('.modal_content');
        this.base.down('.modal_header').select('.closeModal').invoke('observe', 'click', Control.Modal.close);
        this.width  = 510;
        this.modal  = Object.isUndefined(modal) ? true : modal;
        this.errors = obj.errors;
        this.errorCount = parseInt(obj.errorCount);
        if (this.errorCount > 0 && this.modal) this.show();
    },
    show: function() {
        try {
            var content = this.getContent();
            var title   = i18n('error');
            this.container.update(content);
            this.title.select('.title').invoke('update', title);
            Control.Modal.open(this.base, Object.extend({
                width: this.width,
                afterOpen: this.closeHandler.bind(this, this.base)
            }, options.modal));
        } catch(e) {
        }
    },
    getErrorByLabel: function(label) {
        return this.errors.find(function(el) {
            return el.label == label;
        });
    },
    closeHandler: function(container) {
        container.select('.closeModal').invoke('observe', 'click', function() {
            Control.Modal.close();
        });
    },
    noErrors: function() {
        return this.errorCount ? false : true;
    },
    getContent: function() {
        var tbl = new Element('table', {
            'class': 'errors',
            cellpadding: '0',
            cellspacing: '0',
            border: '0'
        });
        var tb  = new Element('tbody');
        var tr  = null;
        var td  = null;
        tbl.insert(tb);
        this.errors.each(function(el) {
            tr = new Element('tr');
            td = new Element('td', {
                'class': 'label',
                rowspan: el.msg.size()
            }).update(el.label);
            tr.insert(td);
            f = true;
            el.msg.each(function(e) {
                if (!f) tr = new Element('tr');
                td = new Element('td', {
                    'class': 'description'
                }).update(e);
                tr.insert(td);
                tb.insert(tr);
                f = false;
            });
            tr = new Element('tr');
            td = new Element('td', {
                'class': 'space',
                colspan: 2
            });
            tr.insert(td);
            tb.insert(tr);
        }.bind(this));
        return tbl;
    }
});

AjaxForm = Class.create(Registration, {
    initialize: function(fm, opt) {
        this.fm = $(fm);
        Object.extend(this, opt);
        this.btnEdit.observe('click', this.toEditState.bind(this));
        this.btnSave.observe('click', this.saveAction.bind(this));
        this.btnBaseEdit = this.btnEdit.up('div.' + this.btnBase);
        this.btnBaseSave = this.btnSave.up('div.' + this.btnBase);
        this.initValidation();
        this.fm.select('input').each(function(el) {
            this.initTooltip(el);
        }.bind(this));
        var inputs = this.fm.select('input[type="text"]');
        inputs = inputs.concat(this.fm.select('input[type="password"]'));
        inputs.invoke('observe', 'focus', this.setFocused.bind(this));
        inputs.invoke('observe', 'blur', this.setUnFocused.bind(this));

    },
    initValidation: function() {
        var profEmail = $('profile_email');
        var profConfEmail = $('profile_confirm_email');
        if (profEmail && profConfEmail) {
            profEmail.observe('blur', this.checkValid.bindAsEventListener(this));
            profEmail.observe('blur', this.checkConfirmation.bindAsEventListener(this, profEmail, profConfEmail));
            profConfEmail.observe('blur', this.checkConfirmation.bindAsEventListener(this, profEmail, profConfEmail));
        }
        var profNewPass = $('profile_new_password');
        var profConfPass = $('profile_confirm_password');
        if (profNewPass) {
            profNewPass.observe('blur', this.checkValid.bindAsEventListener(this));
            profNewPass.observe('blur', this.checkConfirmation.bindAsEventListener(this, profNewPass, profConfPass));
            profConfPass.observe('blur', this.checkConfirmation.bindAsEventListener(this, profNewPass, profConfPass));
        }
    },
    saveAction: function(event) {
        this.fm.request({
            onSuccess: function(transport) {
                var obj = transport.responseText.evalJSON();
                var berr = new BADErrorManager(obj);
                if (berr.noErrors()) {
                    this.toViewState(event);
                    var completeness = parseInt(obj.completenessScore);
                    $('completenessScore').update(completeness);
                    $('completenessBar').setStyle({
                        width: completeness + '%'
                    });
                    if (completeness >= 100) $('completenessDetails').hide();
                }
            }.bind(this)
        });
    },
    toViewState: function(event) {
        this.btnBaseEdit.show();
        this.btnBaseSave.hide();
        this.fm.select('input').invoke('fire', 'error:hide');
        this.fm.select('.editable').each(function(elem) {
            var next = elem.next();
            if (matches = elem.className.match(/toggle-(\w+)/)) {
                this.fm.select('.' + matches[1]).each(function(el) {
                    if (el.visible()) el.hide();
                    else el.show();
                });
            }
            if (matches = elem.className.match(/type-(\w+)/)) {
                if (matches[1] == 'input') {
                    var inpt = (elem.down('input') || elem.down('select'));
                    next.down().update(inpt.value);
                    next.show();
                    elem.hide();
                } else if (matches[1] == 'gender') {
                    if (radio = this.fm.getInputs('radio', 'gender').find(function(radio) {
                        return radio.checked;
                    })) {
                        next.down().update(elem.select('label[for="' + radio.id + '"]').first().innerHTML);
                    }
                    next.show();
                    elem.hide();
                } else if (matches[1] == 'birthday') {
                    next.down().update(
                        formatNumber(elem.down('select').value) + '/' +
                        formatNumber(elem.down('select', 1).value) + '/' +
                        elem.down('select', 2).value
                        );
                    next.show();
                    elem.hide();
                } else if (matches[1] == 'country') {
                    next.down().update(
                        i18n('ISO_' + elem.down('select').value)
                        );
                    next.show();
                    elem.hide();
                }
            }
        }.bind(this));
    },
    toEditState: function(event) {
        this.btnBaseEdit.hide();
        this.btnBaseSave.show();
        this.fm.select('.editable').each(function(elem) {
            var next = elem.next();
            if (matches = elem.className.match(/toggle-(\w+)/)) {
                this.fm.select('.' + matches[1]).each(function(el) {
                    if (el.visible()) el.hide();
                    else el.show();
                });
            }
            if (matches = elem.className.match(/type-(\w+)/)) {
                if (matches[1] == 'input') {
                    var inpt = (elem.down('input') || elem.down('select'));
                    inpt.value = next.down().innerHTML;
                    next.hide();
                    elem.show();
                } else if (matches[1] == 'country') {
                    var sel = elem.down('select');
                    var val = next.down().innerHTML;
                    var option = '';
                    for (i = 0; i < sel.options.length; i++) {
                        var item = sel.options[i];
                        if (item.label == val) {
                            option = item.value;
                            break;
                        }
                    }
                    sel.value = option;
                    next.hide();
                    elem.show();
                } else if (matches[1] == 'gender') {
                    var civ = next.down().innerHTML.strip();
                    if (sel = elem.select('label').find(function(lbl) {
                        return lbl.innerHTML.strip() == civ;
                    })) {
                        sel.previous('input').checked = true;
                    }
                    next.hide();
                    elem.show();
                } else if (matches[1] == 'birthday') {
                    var dateparse = next.down().innerHTML.match(/(\d+)\/(\d+)\/(\d+)/);
                    if (dateparse) {
                        elem.down('select').value = parseInt(dateparse[1], 10);
                        elem.down('select', 1).value = parseInt(dateparse[2], 10);
                        elem.down('select', 2).value = parseInt(dateparse[3], 10);
                    }
                    next.hide();
                    elem.show();
                }
            }
        }.bind(this));
    }
});

PaymentPending = Class.create({
    initialize: function() {
        if (!(this.base = $('modalPending'))) return;
        Event.observe(window, 'keypress', this.keyHandler.bind(this));
    },
    DDRoundies: function() {
        if (typeof(DD_roundies) == 'object') DD_roundies.roundify.call(this.base, [5,5,5,5]);
    },
    keyHandler: function(event) {
        var key = event.keyCode || event.wich;
        if (key == Event.KEY_ESC) this.closeProcess();
    },
    showProcess: function() {
        try {
            Control.Modal.open(this.base, Object.extend({
                afterOpen: function() {
                    this.DDRoundies();
                }.bind(this)
            }, options.modal));
        } catch(e) {
        }
    },
    closeProcess: function() {
        if(Control.Modal.current)
            Control.Modal.current.close();
    }
});

Profile = Class.create(ModalWindows, {
    initialize: function() {
        $$('.aEvent').invoke('observe', 'click', this.loadPurchase.bindAsEventListener(this));
        this.updatePurchase($$('.aEvent').first());
        if (parseInt(MvcSkel.getVar('avsPinCode'))) this.getPin();
        if (!$('carousel')) return;
        new Carousel($('carousel'), $$('#carousel-content .slide'), $$('#carousel-arrow-right', '#carousel-arrow-left', 'a.carousel-jumper'), {
            duration: 0.8,
            transition: 'sinoidal',
            circular: false,
            step: 6,
            visibleSlides: 6,
            wheel: false
        });		
    },
    loadPurchase: function(event) {
        var el = event.element().findNearest('a');
        Event.stop(event);
        this.updatePurchase(el);
    },
    updatePurchase: function(el) {
        var id = null;
        if (el) {
            var purchaseRef = el.className.match(/purchaseRef-(\d+)/i)[1];
            var gameId = el.className.match(/gameId-(\d+)/i)[1];
            var url = new UrlConstructor('profile/get_purchase_info');
            url.addVar('purchaseRef', purchaseRef);
            url.addVar('gameId', gameId);
            new Ajax.Request(url.construct(), {
                onSuccess: function(transport) {
                    var obj = transport.responseText.evalJSON();
                    $('dlContent').show().update(obj.purchase);
                    CALLBACK.updatePurchase();
                    this.initResendConfirmationEmail($('resendConfirmationEmail'), purchaseRef);
                }.bind(this)
            });
        }
    },
    initResendConfirmationEmail: function(a, id) {
        a.observe('click', function() {
            var url = new UrlConstructor('shop/resend_confirmation_email');
            url.setAction(true);
            url.addVar('purchaseRef', id);
            new Ajax.Request(url.construct(), {
                onSuccess: function(transport) {
                    var obj = transport.responseText.evalJSON();
                    var berr = new BADErrorManager(obj);
                    if (berr.noErrors()) this.emailSent(obj.email);
                }.bind(this)
            });
        }.bind(this));
    },
    emailSent: function(email) {
        ModalWindows.showText(
            i18n('profile_confirmation_email_resent', $H({
                email: email
            }))
            );
    },
    getPin: function() {
        ModalWindows.showModal('modalAVSGetPin', {
            afterOpen: this.pinRequest.bind(this)
        });
    },
    pinRequest: function(event) {
        var pin = $('avs_pin');
        var pending = $('avs_pin_pending');
        
        var url = new UrlConstructor('profile/avs_get_pin');
        new Ajax.Request(url.construct(), {
            onSuccess: function(transport) {
                var obj = transport.responseText.evalJSON();
                pending.hide();
                pin.up('.wrap_fields').show();
                var berr = new BADErrorManager(obj);
                if (berr.noErrors()) {
                    pin.value = obj.pin;
                }
            }.bind(this)
        });
    }
});

DownloadPage = Class.create({
    testmodal: null,
    initialize: function() {
        this.testmodal = new ModalCRMWindow(510);
        this.testmodal.showStatic();
        $$('.fidelityButton').invoke('observe', 'click', this.saveDetails.bind(this));
    },
    saveDetails: function() {
        var firstnames = this.testmodal.base.select('.firstName');
        var sirnames = this.testmodal.base.select('.surname');
        var genders = this.testmodal.base.select('.gender');
        var birthdays = this.testmodal.base.select('.birthdayDay');
        var birthmonths = this.testmodal.base.select('.birthdayMonth');
        var birthyears = this.testmodal.base.select('.birthdayYear');
        var ntypes = this.testmodal.base.select('.newsletterType');
        var params = {
            'firstName'      : firstnames[0].value,
            'surname'        : sirnames[0].value,
            'gender'         : genders[0].value,
            'birthdayDay'    : birthdays[0].value,
            'birthdayMonth'  : birthmonths[0].value,
            'birthdayYear'   : birthyears[0].value,
            'newsletterType' : ntypes[0].value
        };
        var url = new UrlConstructor('download/details_save');
        new Ajax.Request(url.construct(), {
            method: 'post',
            parameters: params,
            onSuccess: function(transport) {
                var obj = transport.responseText.evalJSON();
                Control.Modal.close();
            }.bind(this)
        });
    }
});

MyDetails = Class.create(Profile, {
    initialize: function() {
        if (!(this.btnEdit = $('updateDetails')) ||  !(this.btnUpdate = $('confirmUpdate'))) return;
        this.details = new AjaxForm('myDetails', {
            btnBase: 'button_form',
            btnEdit: this.btnEdit,
            btnSave: this.btnUpdate
        });
        if (this.nletter = $('profileNewsletter'))
            this.nletter.select('input').invoke('observe', 'click', this.saveNewsletter.bind(this));
    },
    saveNewsletter: function(event) {
        this.nletter.request({
            onSuccess: function(transport) {
                var obj = transport.responseText.evalJSON();
                var berr = new BADErrorManager(obj);
            }.bind(this)
        });
    }
});

DefaultValue = Class.create({
    initialize: function() {
        var inputs = $$('input.defaultValue');
        inputs.invoke('addClassName', 'defaultText');
        inputs.each(function(el) {
            var value = el.value;
            el.observe('focus', this.toggleDefault.bindAsEventListener(this, value));
            el.observe('blur', this.toggleDefault.bindAsEventListener(this, value));
        }.bind(this));
    },
    toggleDefault: function(event,value) {
        var input = event.element();
        if (input.hasClassName('defaultText')) {
            input.removeClassName('defaultText');
            input.value = '';
        } else if (input.value.empty()) {
            input.addClassName('defaultText');
            input.value = value;
        }
    }
});

DoubleClickProtection = Class.create({
    initialize: function() {
        $$('.clickProtected').invoke('observe', 'click', this.clickProtection.bind(this));
    },
    clickProtection: function(event) {
        var el = event.element();
        if (!el.hasClassName('clickDone')) el.addClassName('clickDone');
        else Event.stop(event);
    }
});

TermsConditions = Class.create({
    termsClass: 'termsAndConditions',
    initialize: function() {
        $$('.' + this.termsClass).invoke('observe', 'click', this.showWindow.bind(this));
    },
    showWindow: function() {
        ModalWindows.showModal('modalTermsConditions', {
            afterOpen: this.updateContent.bind(this)
        });
    },
    updateContent: function() {
        var url = new UrlConstructor('Support/Terms');
        var monostoreCode = MvcSkel.getVar('monostoreCode');
        if(monostoreCode!=false)
            url.addVar('monostoreCode', monostoreCode);
        new Ajax.Request(url.construct(), {
            onComplete: function(request){
                $('modal_terms').update(request.responseText);
            }.bind(this)
        });
    }
});

DropDown = Class.create({
    initialize: function(overId) {
        this.timer = null;
        this.overId = $(overId);
        if(this.overId!=null) {
            this.contentId = $(this.overId.className.match(/ddContainer-(\w+)/)[1]);
            this.contentId.hide();
            this.overId.observe('mouseover', this.showBox.bindAsEventListener(this));
            this.overId.observe('mouseout',  this.setHideTimeout.bindAsEventListener(this));
            this.contentId.observe('mouseover', this.clearHideTimeout.bindAsEventListener(this));
            this.contentId.observe('mouseout',  this.setHideTimeout.bindAsEventListener(this));
        }
    },
    showBox: function() {
        if (this.contentId.visible()) 
            return false;
        this.contentId.show();
        this.overId.addClassName('js_hover');
        this.clearHideTimeout();
    },
    hideBox: function() {
        if (!this.contentId.visible()) 
            return false;
        this.clearHideTimeout();
        this.contentId.hide();
        this.overId.removeClassName('js_hover');
        this.clearHideTimeout();
    },
    clearHideTimeout: function() {
        clearTimeout(this.timer);
    },
    setHideTimeout: function() {
        this.clearHideTimeout();
        this.timer = setTimeout(this.hideBox.bindAsEventListener(this), effects.def.timeout);
    }
});

function publisher(img){
    var img = $(img);
    img.hide();
    img.next().show();
}

function submit(name) {
    $$('form[name="' + name + '"]').first().submit();
    return false;
}

function gameAdjustFont() {
    if (!(namebox = $('game_name_full'))) return;
    var curHeight = namebox.offsetHeight;
    var curFontsize = 26;
    while (curHeight >= $('gamename_box').offsetHeight && curFontsize > 0) {
        curFontsize--;
        namebox.style.fontSize = curFontsize + 'px';
        var curHeight = namebox.offsetHeight;
    }
}


function resetOpacity(element) {
    if (Prototype.Browser.IE) {
        var filter = element.getStyle('filter');
        element.style.filter = filter.replace(/alpha\([^\)]*\)/gi,'') + 'alpha(opacity=' + (1 * 100) + ')';
    } else element.setOpacity(1);
}

function charCounter(el, counter, maxlimit, limited){
    if($F(el).length >= maxlimit){
        $(counter).addClassName('charcount-limit');
        $(counter).removeClassName('charcount-safe');
        if(limited) {
            $(el).value = $F(el).substring(0, maxlimit);
            $(el).scrollTop = 374;
        }
    } else {
        $(counter).removeClassName('charcount-limit');
        $(counter).addClassName('charcount-safe');
    }
    $(counter).update( $F(el).length + '/' + maxlimit );

}

function makeItCount(el, counter, maxsize, limited){
    if(limited == null) limited = true;
    if ($(el)){
        Event.observe($(el), 'keyup', function(){
            charCounter(el, counter, maxsize, limited+1);
        }, false);
        Event.observe($(el), 'keydown', function(){
            charCounter(el, counter, maxsize, limited+1);
        }, false);
        charCounter(el, counter,maxsize,limited);
    }
}

function checkDownloader(idrefresh, playerLink) {
    window.onload = function() {
        var downloader_version = GetDownloaderVersion();

        if (downloader_version == null) {
            var htmlSource = '<p>'+i18n('DOWNLOAD_PREPARE_DOWNLOAD_MANAGER_DISABLED')+'</p>';
            htmlSource += '<div class="button_type button_form btn_downloader">';
            htmlSource += '<a class="button_container" href="' + playerLink +'">';
            htmlSource += '<span class="btn_left btn_typeA png_bg"></span>';
            htmlSource += '<span class="btn_right btn_typeA png_bg">';
            htmlSource += '<p class="btn_text"><i>'+i18n('DOWNLOAD_GET_OUR_DOWNLOADER')+'</i><b>'+i18n('DOWNLOAD_GET_OUR_DOWNLOADER')+'</b></p>';
            htmlSource += '</span></a></div';
            $(idrefresh).update(htmlSource);
        } else {
            $(idrefresh).update('<p>'+i18n('DOWNLOAD_PREPARE_DOWNLOAD_MANAGER_ALREADY_ENABLED')+'</p>');
        }
    }
}

function o_popup(page, hauteur, largeur, options) {
    options = options | 'menubar=no,scrollbars=no,statusbar=no,resizable=no,location=no';
    hauteur = hauteur | 400;
    largeur = largeur | 550;
    var top=(screen.height-hauteur)/2;
    var left=(screen.width-largeur)/2;
    window.open(page,"","top="+top+",left="+left+",width="+largeur+",height="+hauteur+","+options);
}

var myDebug = {
    log: function(text) {
        try{
            //console.log(text);
        } catch (e) {}
    },
    err: function(text) {
        try{
            console.error(text);
        } catch (e) {
            //alert(text);
        }
    }
};

var io_operation = "ioBegin";
var io_bbout_element_id = "n01t4v01";
var io_install_stm = false;
var io_exclude_stm = 12;
var io_install_flash = false;
var io_install_stm_error_handler = "";
var io_flash_needs_update_handler = "";
var io_install_flash_error_handler = "";
var io_max_wait = 5000;
var io_submit_form_id = "checkoutForm";

function addBookmark(title, url) {
	    var msg = "Malheureusement, votre navigateur ne supporte pas cette action, appuyer sur ctrl+D (Command+D sur Mac) pour ajouter manuellement cette page aux favoris.";
	    if (window.sidebar) {
	        window.sidebar.addPanel(title, url, "");
	    } else if (document.all) {
	        window.external.AddFavorite(url, title);
	    } else if (window.opera && window.print) {
	        alert (msg);
	/*
	// opera
	    var elem = document.createElement('a');
	    elem.setAttribute('href',url);
	    elem.setAttribute('title',title);
	    elem.setAttribute('rel','sidebar');
	    elem.click();
	*/

	    } else if (window.chrome) {
	        alert (msg);
	    }
}

document.observe("dom:loaded", function() {
    var cntx = $('context').getValue();

    if (/category_index/.test(cntx) || /search_index/.test(cntx)) {
        myDebug.log('category_index || search_index');
        new CategoryIndexALoader();
        new DropDown('ddBestsellers');
    }
    if(/topichub_index/.test(cntx)) {
        myDebug.log('topichub_index');
        new TopicHubALoader();
        new DropDown('ddBestsellers');
    }
    
});
    
Event.observe(window, 'load', function(){
    var cntx = $('context').getValue();

    ModalWindows  = new ModalWindows();
    if (/checkout_index/.test(cntx) || /monostore_checkout/.test(cntx)) {
        ModalAVSWindow = new ModalAVSWindow();
        if ($('expand_orange_login')) {
            new DropDown('expand_orange_login');
        }
    } else {
        if (DEFINE.get('CART_ENABLE')) {
            ShoppingCart = new ShoppingCart();
        }
        CatalogExpand    = new CatalogExpand();
        HeaderNewsletter = new HeaderNewsletter();
    }
    Redirect = new Redirect();
   
    
    if (/^hub_index/.test(cntx)) {
        new HubIndexALoader();
    }
    if (/game_index/.test(cntx) || /monostore_index/.test(cntx)) {
        new MediaViewer();
        new ModalUserReviewWindow(600);
        if (typeof(Cufon) != 'function') gameAdjustFont();
    }
    if (/profile_details/.test(cntx)) {
        new MyDetails();
    }
    if (/profile_.*/.test(cntx)) {
        new Profile();
    }
    if (/login_index/.test(cntx) || /.+_login/.test(cntx)) {
        new Registration();
    }
    if (/index_index/.test(cntx)) {
        new HomeCarousel();
        new HomeGondola();
    }
    if (/support_hiw/.test(cntx)) {
        new Howitworks();
    }
    if (/download_index/.test(cntx)) {
        new DownloadPage();
    }
    
    new TermsConditions();
    new DoubleClickProtection();
    new DefaultValue();
    new Autocompleter();
    new LanguageChooser();
    new InitSWFobjects();
    
});

