Event.observe(document, 'dom:loaded', function()
{
    /* custom functions */

    // Customized Effect.Move function
    Effect.MoveDown = function(element, options)
    {
    
        element = $(element);
    
        // set defaults
        var dir = 'down';

        if (options) 
        {
            if (options['dir'])
            {
                dir = options['dir'];
            }
        }
    
        if (!element.ia_movedown_down)
        {
            element.ia_movedown_top = element.positionedOffset()[1];
            element.ia_movedown_left = element.positionedOffset()[0];
            element.ia_movedown_down = element.positionedOffset()[1] + element.getHeight();
        }
    
        // default move point
        var y = element.ia_movedown_down;
    
        if (dir != 'down')
        {
            y = element.ia_movedown_top;
        }
        
        new Effect.Move(element, {x: element.ia_movedown_left, y: y, mode: 'absolute'});
    }

    // Dynamicly loads Javascript files with onLoaded event firing
    window.Include = function(path, onload)
    {

        var script = new Element('script', {
            src  : path,
            type : 'text/javascript'
        });
 
        if (onload) {
            if (Prototype.Browser.IE) {
                Event.observe(script, 'readystatechange', function(e) {
                    if (this.readyState == 'loading')
                        return;
 
                    onload();
                }.bind(script));
            }
            else
                Event.observe(script, 'load', onload.bind(script));
        }
 
        $$('head')[0].insert(script);

    }

    /* Horizontal scrollbar */

    var initHorizontalScroll = function(container,track,options)
    {
        
        /* Horizontal Bar */
        var myClass = Class.create({
            initialize: function(container,track,options){
                this.enabled = false;
                this.notificationTimeout = false;
                this.container = $(container);
                this.boundMouseWheelEvent = this.onMouseWheel.bindAsEventListener(this);
                this.boundResizeObserver = this.onWindowResize.bind(this);
                this.track = $(track);
                this.handle = this.track.firstDescendant();
                this.options = Object.extend({
                    active_class_name: 'scrolling',
                    apply_active_class_name_to: this.container,
                    notification_timeout_length: 125,
                    handle_minimum_width: 25,
                    scroll_to_smoothing: 0.01,
                    scroll_to_steps: 15,
                    proportional: true,
                    slider_options: {}
                },options || {});
                this.slider = new Control.Slider(this.handle,this.track,Object.extend({
                    axis: 'horizontal',
                    onSlide: this.onChange.bind(this),
                    onChange: this.onChange.bind(this)
                },this.options.slider_options));
                this.recalculateLayout();
                Event.observe(window,'resize',this.boundResizeObserver);
                this.handle.observe('mousedown',function(){
                    if(this.auto_sliding_executer)
                        this.auto_sliding_executer.stop();
                }.bind(this));
            },
            destroy: function(){
                Event.stopObserving(window,'resize',this.boundResizeObserver);
            },
            enable: function(){
                this.enabled = true;
                this.container.observe('mouse:wheel',this.boundMouseWheelEvent);
                this.slider.setEnabled();
                this.track.show();
                if(this.options.active_class_name)
                    $(this.options.apply_active_class_name_to).addClassName(this.options.active_class_name);
                this.notify('enabled');
            },
            disable: function(){
                this.enabled = false;
                this.container.stopObserving('mouse:wheel',this.boundMouseWheelEvent);
                this.slider.setDisabled();
                this.track.hide();
                if(this.options.active_class_name)
                    $(this.options.apply_active_class_name_to).removeClassName(this.options.active_class_name);
                this.notify('disabled');
                this.reset();
            },
            reset: function(){
                this.slider.setValue(0);
            },
            recalculateLayout: function(){
                if(this.container.scrollWidth <= this.container.offsetWidth)
                    this.disable();
                else{
                    this.slider.trackLength = this.slider.maximumOffset() - this.slider.minimumOffset();
                    if(this.options.proportional){
                        this.handle.style.width = Math.max(this.container.offsetWidth * (this.container.offsetWidth / this.container.scrollWidth),this.options.handle_minimum_width) + 'px';
                        this.slider.handleLength = this.handle.style.width.replace(/px/,'');
                    }
                    this.enable();
                }
            },
            onWindowResize: function(){
                this.recalculateLayout();
                this.scrollBy(0);
            },
            onMouseWheel: function(event){
                if(this.auto_sliding_executer)
                    this.auto_sliding_executer.stop();
                this.slider.setValueBy(-(event.memo.delta / 20)); //put in math to account for the window width
                event.stop();
                return false;
            },
            onChange: function(value){
                this.container.scrollLeft = Math.round(value / this.slider.maximum * (this.container.scrollWidth - this.container.offsetWidth));
                if(this.notification_timeout)
                    window.clearTimeout(this.notificationTimeout);
                this.notificationTimeout = window.setTimeout(function(){
                    this.notify('change',value);
                }.bind(this),this.options.notification_timeout_length);
            },
            getCurrentMaximumDelta: function(){
                return this.slider.maximum * (this.container.scrollWidth - this.container.offsetWidth);
            },
            getDeltaToElement: function(element){
                return this.slider.maximum * ((element.positionedOffset().left + (element.getWidth() / 2)) - (this.container.getWidth() / 2));
            },
            scrollTo: function(x,animate){
                var current_maximum_delta = this.getCurrentMaximumDelta();
                if(x == 'left')
                    x = 0;
                else if(x == 'right')
                    x = current_maximum_delta;
                else if(typeof(x) != "number")
                    x = this.getDeltaToElement($(x));
                if(this.enabled){
                    x = Math.max(0,Math.min(x,current_maximum_delta));
                    if(this.auto_sliding_executer)
                        this.auto_sliding_executer.stop();
                    var target_value = x / current_maximum_delta;
                    var original_slider_value = this.slider.value;
                    var delta = (target_value - original_slider_value) * current_maximum_delta;
                    if(animate){
                        this.auto_sliding_executer = new PeriodicalExecuter(function(){
                            if(Math.round(this.slider.value * 100) / 100 < Math.round(target_value * 100) / 100 || Math.round(this.slider.value * 100) / 100 > Math.round(target_value * 100) / 100){
                                this.scrollBy(delta / this.options.scroll_to_steps);
                            }else{
                                this.auto_sliding_executer.stop();
                                this.auto_sliding_executer = null;
                                if(typeof(animate) == "function")
                                    animate();
                            }           
                        }.bind(this),this.options.scroll_to_smoothing);
                    }else
                        this.scrollBy(delta);
                }else if(typeof(animate) == "function")
                    animate();
            },
            scrollBy: function(x){
                if(!this.enabled)
                    return false;
                this.slider.setValueBy(x / this.getCurrentMaximumDelta());
            }
        });
        Object.Event.extend(myClass);

        return new myClass(container,track,options);
    }

    /* main script */

    var f,e,i;

    // add observers to input fields
    $$('input.input-text, input.input-password').each(function(el)
    {
        if (el.value !== '')
        {
            el.isEmpty = false;
        }
        else
        {
            if (!Prototype.Browser.IE || !el.hasClassName('input-password'))
            {
                if (el.hasClassName('input-password'))
                {
                    el.type = 'text';
                }
                el.value = el.title;
                el.isEmpty = true;
                el.addClassName('text-stub');
            }
        }

        el.observe('focus', function(event){
            Event.element(event).fire('my:focus');
        });
        
        el.observe('my:focus', function(event){
            e = Event.element(event);
            if (e.isEmpty)
            {
                if (!Prototype.Browser.IE || !el.hasClassName('input-password'))
                {
                    if (e.hasClassName('input-password'))
                    {
                        e.type = 'password';
                    }
                    e.isEmpty = false;
                    e.value = '';
                    e.removeClassName('text-stub');
                }
            }
        });

        el.observe('blur', function(event){
            Event.element(event).fire('my:blur');
        });

        el.observe('my:blur', function(event){
            e = Event.element(event);
            if (e.value == '')
            {
                if (!Prototype.Browser.IE || !el.hasClassName('input-password'))
                {
                    if (e.hasClassName('input-password'))
                    {
                        e.type = 'text';
                    }
                    e.isEmpty = true;
                    e.value = e.title;
                    e.addClassName('text-stub');
                }
            }
        });
    });

    // Add observers to textarea fields
    $$('textarea.textarea').each(function(el)
    {
        if (el.value !== '')
        {
            el.isEmpty = false;
        }
        else
        {
            el.value = el.title;
            el.isEmpty = true;
            el.addClassName('text-stub');
        }

        el.observe('focus', function(event){
            Event.element(event).fire('my:focus');
        });
        
        el.observe('my:focus', function(event){
            e = Event.element(event);
            if (e.isEmpty)
            {
                e.isEmpty = false;
                e.value = '';
                e.removeClassName('text-stub');
            }
        });

        el.observe('blur', function(event){
            Event.element(event).fire('my:blur');
        });
        el.observe('my:blur', function(event){
            e = Event.element(event);
            if (e.value == '')
            {
                e.isEmpty = true;
                e.value = e.title;
                e.addClassName('text-stub');
            }
        });
    });

    // replace submit button with text
    $$('input.ia_text-submit').each(function(item)
    {
        var parentFormAction;

        // hack for IE-nested-forms
        if (Prototype.Browser.IE && !item.up('form'))
        {
            parentForm = $(item.id.replace(/\-submit$/, '-form'));
        }
        else
        {
            parentForm = item.up('form');
        }

        if (!parentForm)
        {
            return; // do nothing
        }

        // {{{ create text element with submit action
        var el = new Element('a',
        {
            'href': parentForm.readAttribute('action'),
            'class': 'ia_text-submit'
        });

        el.form = parentForm;

        // Copy text from the button
        el.innerHTML = item.value;

        el.observe('click', function(e)
        {
            Event.stop(e);

            var el = Event.element(e);

            if (!el.form)
            {
                return; // do nothing
            }

            $$('input.input-text, input.input-password').each(function(el)
            {
                if (el.isEmpty)
                {
                    el.isEmpty = false;
                    el.value = '';
                    el.removeClassName('text-stub');
                }
            });
            // hack for IE-nested-froms
            if (Prototype.Browser.IE)
            {
                $$('#shopping_bag-items input.input-checkbox').each(function(el)
                {
                    if (el.checked)
                    {
// TODO: add to request
                    }
                });
            }

            el.form.submit();
        });
        // }}}

        // replace button with new text element
        item.replace(el);

    });

    /* replace scrollbars with custom ones */
    // TODO: Make it thru classes
    // include Livepipe Core and Control.ScrollBar
    window.Include('/a/lib/livepipe.net/livepipe.js', function(){
        window.Include('/a/lib/livepipe.net/scrollbar.js', function(){

            // {{{ item description
            if ($('item_description-content'))
            {
                (function()
                {
                    // create vertical scrollbar track and handler
                    var track = new Element('div',
                    {
                        id: 'scrollbar_track-v-1',
                        'class': 'scrollbar_track-v'
                    });
                    var handle = new Element('div',
                    {
                        id: 'scrollbar_handle-v-1',
                        'class': 'scrollbar_handle-v'
                    });
    
                    // set height
                    track.setStyle({
                        'height': ($('item_description-content').getHeight() - 2) + 'px'
                    });
    
                    $('item_description-content').down().setStyle({
                        'height': $('item_description-content').getHeight() + 'px'
                    });

                    $('item_description-content').down().addClassName('overflow_hidden');
                    $('item_description-content').addClassName('overflow_hidden');

                    // inject them into the document
                    track.insert({bottom: handle});
                    $('item_description-content').insert({bottom: track});
    
                    var vScrollBar = new Control.ScrollBar($('item_description-content').down(),'scrollbar_track-v-1');
                })();

            }
            // }}}


            // {{{ decorate select elements
            // DO decoration only for item page for now
            if ($('item_description-variants')) $$('select.select').each(function(el)
            {
                // convert real event to custom ones
                el.observe('change', function(e)
                {
                    var el = Event.element(e);
        
                    el.fire('ia:change');
                });
        
                var select = new Element('div',
                {
                    'class': el.className
                }).insert(new Element('input',
                    {
                        'id': el.id,
                        'type': 'hidden',
                        'name': el.name,
                        'value': $F(el),
                        'class': 'hidden select'
                    })
                ).insert(new Element('div',
                    {
                        'class': 'end'
                    })
                ).insert(new Element('div',
                    {
                        'class': 'body'
                    })
                ).insert(new Element('div',
                    {
                        'class': 'button'
                    })
                ).insert(new Element('div',
                    {
                        'class': 'data'
                    })
                ).insert({bottom: new Element('div',
                    {
                        'class': 'cover'
                    })
                });
        
                // show selected
                if (el.options.length && el.selectedIndex >= 0 && el.options[el.selectedIndex])
                {
                    select.down('div.body').update(el.options[el.selectedIndex].text);
                }
        
                var data = select.down('div.data');
        
                data.insert(new Element('div', {/* just empty thing to make Effect.Slide less buggy */}));
        
                // copy options
                for (var i=0; i<el.options.length; i++)
                {
                    data.insert({'bottom': new Element('div',
                        {
                            'class': 'option row_' + i + ' ' + (i%2 ? ' odd' : ' even')
                        }).insert(new Element('span',
                            {
                                'class': 'value'
                            }).update(el.options[i].value)
                        ).insert(new Element('span',
                            {
                                'class': 'text'
                            }).update(el.options[i].text) // add marquee for long names
                        )
                    });
        
                    // add selected flag
                    if (el.selectedIndex == i)
                    {
                        data.down('div.row_' + i).addClassName('selected');
                    }
        
                    // add disabled flag
                    if (el.options[i].disabled)
                    {
                        data.down('div.row_' + i).addClassName('disabled');
                    }
                }
        
                // hide data
                data.hide();
        
                // add some logic to the new select element
                select.observe('click', function(e)
                {
                    var data, open;
                    var el = Event.element(e);
        
                    Event.stop(e);
        
                    if (el.tagName == 'DIV' && el.hasClassName('select'))
                    {
                        data = el.down('div.data');
                    }
                    else
                    {
                        data = el.up('div.select').down('div.data');
                    }
        
                    open = data.retrieve('open', false);
        
                    if (open)
                    {
                        data.hide();
                        open = false;
                    }
                    else
                    {
                        data.show();
                        open = true;
                    }
        
                    data.store('open', open);
        
                });
        
                // add some logic to data layer
                data.observe('mouseover', function(e)
                {
                    var el = Event.element(e);
        
                    if (!el.hasClassName('option'))
                    {
                        el = el.up('div.option');
                    }
        
                    if (el && !el.hasClassName('disabled'))
                    {
                        // remove active class from other elements
                        el.up('div.data').select('div.option.active').invoke('removeClassName', 'active');
            
                        el.addClassName('active');
                    }
                });
        
                // add some logic to data layer
                data.observe('mouseout', function(e)
                {
                    var el = Event.element(e);
        
                    if (!el.hasClassName('option'))
                    {
                        el = el.up('div.option');
                    }
        
                    if (el)
                    {
                        // remove active class from other elements
                        el.up('div.data').select('div.option.active').invoke('removeClassName', 'active');
                    }
                });
        
                // add some action
                data.observe('click', function(e)
                {
                    var data;
                    var el = Event.element(e);
        
                    if (!el.hasClassName('option'))
                    {
                        el = el.up('div.option');
                    }
        
                    if (el && !el.hasClassName('disabled'))
                    {
                        if (el.up('div.select').input)
                        {
                            data = el.up('div.select').input;
                        }
                        else if (el.up('div.select').down('input.hidden.select'))
                        {
                            data = el.up('div.select').down('input.hidden.select');
                        }
                        else
                        {
                            return false;
                        }
        
                        if (data)
                        {
                            data.value = el.down('span.value').innerHTML;
        
                            // notify observers
                            data.fire('ia:change');
                        }
        
                        el.up('div.select').down('div.body').update(el.down('span.text').innerHTML);
        
                    }
                });
        
                // replace button
                Element.replace(el, select)
            });
            // }}}

// item page

            // check if we have item variants select box
            if ($('item_description-variants'))
            {
                // add new hidden element for variants
                $('item_control-add-form').insert({
                    top: new Element('input',
                    {
                        'id':   'item_control-add-form-variant',
                        'type': 'hidden',
                        'name': 'variant'
                    })
                });

                $('item_description-variants').down('div.select').observe('ia:change', function(e)
                {
                    // we should have input[type=hidden].select inside custom select box
                    if (this.down('input.select').value)
                    {
                        $('item_control-add-form-variant').value = this.down('input.select').value;
                        $('item_control-add').show();
                    }
                    else
                    {
                        $('item_control-add-form-variant').value = '';
                        $('item_control-add').hide();
                    }
                }.bind($('item_description-variants').down('div.select')));

                // set initial state
                $('item_description-variants').down('div.select').fire('ia:change');
            }

// shopping_bag-items

            // {{{ shopping_bag-items
            if ($('shopping_bag-items'))
            {
                (function()
                {
                    // create semi-transporent background for the shopping bag
                    var bg = new Element('div',
                    {
                        'id': 'shopping_bag-items-background'
                    });

                    bg.setOpacity(0.6);

                    $('shopping_bag-items').up().insert({top: bg});

                    // create vertical scrollbar track and handler
                    var track = new Element('div',
                    {
                        'id': 'scrollbar_track-v-2',
                        'class': 'scrollbar_track-v'
                    });
                    var handle = new Element('div',
                    {
                        'id': 'scrollbar_handle-v-2',
                        'class': 'scrollbar_handle-v'
                    });
    
                    // set height
                    track.setStyle({
                        'top': '2px',
                        'height': ($('shopping_bag-items').getHeight() - 10) + 'px'
                    });
    
                    $('shopping_bag-items').down().setStyle({
                        'height': ($('shopping_bag-items').getHeight() - 10) + 'px'
                    });

                    $('shopping_bag-items').down().addClassName('overflow_hidden');
                    $('shopping_bag-items').addClassName('overflow_hidden');

                    // inject them into the document
                    track.insert({bottom: handle});
                    $('shopping_bag-items').insert({bottom: track});
    
                    var vScrollBar = new Control.ScrollBar($('shopping_bag-items').down(),'scrollbar_track-v-2');
                })();
            }

            // {{{ items list
            if ($('items_list'))
            {
                (function()
                {
                    // create horizontal scrollbar track and handler
                    var track = new Element('div',
                    {
                        id: 'scrollbar_track-h-1',
                        'class': 'scrollbar_track-h'
                    });
                    var handle = new Element('div',
                    {
                        id: 'scrollbar_handle-h-1',
                        'class': 'scrollbar_handle-h'
                    });
    
                    // set height
                    track.setStyle({
                        'width': ($('items_list').getWidth() - 2) + 'px'
                    });
    
                    $('items_list').down().setStyle({
                        'width': $('items_list').getWidth() + 'px'
                    });

                    $('items_list').down().addClassName('overflow_hidden');
                    $('items_list').addClassName('overflow_hidden');

                    // inject them into the document
                    track.insert({bottom: handle});
                    $('items_list').insert({bottom: track});
    
                    var hScrollBar = initHorizontalScroll($('items_list').down(),'scrollbar_track-h-1');
    
                    if ($('items_list-item-current'))
                    {
                        hScrollBar.scrollTo($('items_list-item-current'));
                    }
                })();
            }
            // }}}

            // {{{ shopping bag controls
            if ($('shopping_bag-items-container'))
            {
                // hanlde Create New Address, New Recipient, New Message options
                $$('span.shopping_bag-items-control-address, span.shopping_bag-items-control-recipient, span.shopping_bag-items-control-note').each(function(el)
                {
                    if (el.down('select'))
                    {
                        el.down('select').observe('change', function(e)
                        {
                            var el = Event.element(e);

                            if (el.getValue() == '0')
                            {
                                el.up('form').submit();
                            }
                        });
                    }
                });
            }
            // group controls
            if ($('shopping_bag-control-address'))
            {
                $$('div#shopping_bag-control-address select').each(function(el)
                {
                    // hack for IE-nested-forms
                    if (Prototype.Browser.IE && !el.up('form'))
                    {
                        parentForm = $('shopping_bag-control-form');
                    }
                    else
                    {
                        parentForm = el.up('form');
                    }

                    el.parentForm = parentForm;

                    el.observe('change', function(e)
                    {
                        var el = Event.element(e);

                        if (el.getValue() == '0')
                        {
                            if (el.parentForm)
                            {
                                el.parentForm.submit();
                            }

                            // hack for IE-nested-forms
                            if (Prototype.Browser.IE && !el.up('form'))
                            {
                                $$('#shopping_bag-items input.input-checkbox').each(function(el)
                                {
                                    el.checked = $('shopping_bag-items-header-order-checkbox').checked;
                                });
                            }
                            else
                            {
                                parentForm = el.up('form');
                            }
                            // or do nothing
                        }
                    });
                });
            }

            // replace submit method because of IE
            if ($('shopping_bag-control-form'))
            {
                (function(){
                                
                    $('shopping_bag-control-form').oSubmit = $('shopping_bag-control-form').submit;

                    $('shopping_bag-control-form').submit = function()
                    {
                        var f;

                        // TODO: Check if fields already here

                        // hack for IE-nested-forms
                        if (Prototype.Browser.IE)
                        {
                            // add checked items
                            $$('#shopping_bag-items input.input-checkbox').each(function(el)
                            {
                                if (el.checked)
                                {
                                    f = new Element('input',
                                    {
                                        'type': 'hidden',
                                        'name': el.name,
                                        'value': el.value
                                    });

                                    $('shopping_bag-control-form').insert({bottom: f});
                                }
                            });

                            // add address controls
                            $$('#shopping_bag-control-address select.select').each(function(el)
                            {
                                f = new Element('input',
                                {
                                    'type': 'hidden',
                                    'name': el.name,
                                    'value': el.getValue()
                                });

                                $('shopping_bag-control-form').insert({bottom: f});
                            });

                            // add delivery date
                            if ($('shopping_bag-control-date'))
                            {
                                f = new Element('input',
                                {
                                    'type': 'hidden',
                                    'name': $('shopping_bag-control-date').name,
                                    'value': $('shopping_bag-control-date').getValue()
                                });

                                $('shopping_bag-control-form').insert({bottom: f});
                            }

                            // group-submit key
                            if ($('shopping_bag-control-group'))
                            {
                                f = new Element('input',
                                {
                                    'type': 'hidden',
                                    'name': $('shopping_bag-control-group').name,
                                    'value': $('shopping_bag-control-group').getValue()
                                });

                                $('shopping_bag-control-form').insert({bottom: f});
                            }
                        }

                        // do real submit
                        this.oSubmit();
                    }

                })();
            }

            // }}}


            // {{{ order_items (payment page)
            if ($('order_items'))
            {
                (function()
                {
                    // create vertical scrollbar track and handler
                    var track = new Element('div',
                    {
                        'class': 'scrollbar_track-v'
                    });
                    var handle = new Element('div',
                    {
                        'class': 'scrollbar_handle-v'
                    });
    
                    // set height
                    track.setStyle({
                        'top': '0px',
                        'height': ($('order_items').getHeight() - 2) + 'px'
                    });
    
                    $('order_items').down().setStyle({
                        'height': ($('order_items').getHeight() - 2) + 'px'
                    });

                    $('order_items').down().addClassName('overflow_hidden');
                    $('order_items').addClassName('overflow_hidden');

                    // inject them into the document
                    track.insert({bottom: handle});
                    $('order_items').insert({bottom: track});
    
                    var vScrollBar = new Control.ScrollBar($('order_items').down(), track);
                })();
            }

            // {{{ static content
            if ($('static_data-board_content') && $('static_data-content'))
            {
                (function()
                {
                    // create vertical scrollbar track and handler
                    var track = new Element('div',
                    {
                        'class': 'scrollbar_track-v'
                    });
                    var handle = new Element('div',
                    {
                        'class': 'scrollbar_handle-v'
                    });
    
                    // set height
                    track.setStyle({
                        'top': '0px',
                        'height': ($('static_data-board_content').getHeight() - 2) + 'px'
                    });
    
                    $('static_data-content').setStyle({
                        'height': ($('static_data-board_content').getHeight() - 10) + 'px'
                    });

                    $('static_data-content').addClassName('overflow_hidden');
                    $('static_data-board_content').addClassName('overflow_hidden');

                    // inject them into the document
                    track.insert({bottom: handle});
                    $('static_data-board_content').insert({bottom: track});
    
                    var vScrollBar = new Control.ScrollBar($('static_data-content'), track);
                })();
            }
            // }}}

            // {{{ general vertical scrollbar replacement
            $$('div.ia_scrollbar_vertical').each(function(el)
            {
                // create vertical scrollbar track and handler
                var track = new Element('div',
                {
                    'class': 'scrollbar_track-v'
                });
                var handle = new Element('div',
                {
                    'class': 'scrollbar_handle-v'
                });

                // set height
                track.setStyle({
                    'top': '0px',
                    'height': (el.getHeight() - 2) + 'px'
                });

                el.down().setStyle({
                    'height': (el.getHeight() - 10) + 'px'
                });

                el.down().addClassName('overflow_hidden');
                el.addClassName('overflow_hidden');

                // inject them into the document
                track.insert({bottom: handle});
                el.insert({bottom: track});

                var vScrollBar = new Control.ScrollBar(el.down(), track);

                el.scrollbar = vScrollBar;
            });
            // }}}
        });
    });

    // {{{ shopping_bag-suggest
    if ($('shopping_bag-suggest'))
    {
        (function()
        {
            // create semi-transporent background for the shopping bag
            var bg = new Element('div',
            {
                'id': 'shopping_bag-suggest-background'
            });

            bg.setOpacity(0.6);
            
            $('shopping_bag-suggest').up().insert({top: bg});
        })();
    }

    // {{{ gift card
    if ($('gift_card'))
    {
        (function(){

            var holder = new Element('div',
            {
                'id': 'gift_card-cover'
            });

            holder.setOpacity(0.1);

            // add object on top of image's parent div
            $('gift_card-img').up('div').insert({after: holder});

            holder.observe('click', function(e)
            {
                $('gift_card-body').setStyle({
                    'top': (document.body.cumulativeScrollOffset()[1] + Math.floor(document.viewport.getDimensions().height*0.5) - Math.floor($('gift_card-body').getHeight()*0.5) + 150 /* just to make it visually in the middle */) + 'px'
                });

                new Effect.Parallel([
                  new Effect.Appear('cover', {sync: true, from: 0, to: 0.8}), 
                  new Effect.Appear('gift_card-body', {sync: true, from: 0, to: 1 }) 
                ], { 
                  duration: 1.5
                });
            });

            var cover = new Element('div',
            {
                'id': 'cover'
            });
            cover.setStyle({
                'width': '100%',
                'height': ($('copyright').getHeight() + $('copyright').cumulativeOffset()[1]) + 'px'
            });

            cover.hide();
            $(document.body).insert({bottom: cover});

            var card = new Element('div',
            {
                'id': 'gift_card-body'
            });
            card.hide();
            document.body.insert({bottom: card});

            card.observe('click', function(e)
            {
                Event.stop(e);

                new Effect.Parallel([
                  new Effect.Fade('cover', {sync: true, from: 0.8, to: 0}), 
                  new Effect.Fade('gift_card-body', {sync: true, from: 1, to: 0 }) 
                ], { 
                  duration: 1.5
                });

            });

            cover.observe('click', function(e)
            {
                Event.stop(e);

                new Effect.Parallel([
                  new Effect.Fade('cover', {sync: true, from: 0.8, to: 0}), 
                  new Effect.Fade('gift_card-body', {sync: true, from: 1, to: 0 }) 
                ], { 
                  duration: 1.5
                });

            });

        })();
    }

    /* add some interactivity */

    // shipping data section
    if ($('shipping_data'))
    {
        $$('#shipping_data-address-preset select').invoke('observe', 'change', function(e)
        {
            var el = Event.element(e);

            $('shipping_data-address-preset-checkbox').checked = true;
        });

        $$('#shipping_data-message-preset select').invoke('observe', 'change', function(e)
        {
            var el = Event.element(e);

            $('shipping_data-message-preset-checkbox').checked = true;
        });
        // get popup error message
        (function(el)
        {
            if (el)
            {
                // show message
                pop_alert(el.down('.pop-errors-text').innerHTML, el.down('.pop-errors-title').innerHTML);
            }
        })($$('.pop-errors').first());
    }

    /* home page specific */

    if ($('body-home'))
    {
        // hide banner messages
        $$('.banner_message').each(function(e){

            e.hide();
            Effect.MoveDown(e);
            e.hidden = true;

            window.setTimeout(function(){
                e.show();
            }, 1000);

        });

        var showBanner = function(el)
        {
            if (el.hidden)
            {
                Effect.MoveDown(el, {dir: 'up'});
            }
        }
        var hideBanner = function(el)
        {
            if (el.hidden)
            {
                Effect.MoveDown(el);
            }
        }

        // control left banner
        $('banner_left-text').observe('mouseover', function(e)
        {
            showBanner($('banner_message_left-text'));
        });
        $('banner_left-text').observe('mouseout', function(e)
        {
            hideBanner($('banner_message_left-text'));
        });

        // control right banner
        $('banner_right-text').observe('mouseover', function(e)
        {
            showBanner($('banner_message_right-text'));
        });
        $('banner_right-text').observe('mouseout', function(e)
        {
            hideBanner($('banner_message_right-text'));
        });
    }

    // add calendar
    window.Include('/a/lib/scal.fieldguidetoprogrammers.com/scal.js', function()
    {

        $$('input.ia_date').each(function(el)
        {

            el.observe('focus', function(e)
            {

                var el = Event.element(e);

                if (!el.cal)
                {
                    el.cal = new Element('div', { 'id': el.id+'_cal', 'class': 'ia_cal', 'style': 'z-index: 9999; position: absolute; display: none;' });
    
                    el.calChange = function(d)
                    {
                        this.parent.value = d.format(this.options.updateformat);
                        this.parent.isEmpty = false;
                        this.parent.removeClassName('text-stub');
                    };

                    document.body.appendChild(el.cal);

                    el.calObj = new scal(el.cal, el.calChange, {
                        titleformat:'mmmm yyyy',
                        closebutton:'X',
                        dayheadlength:2,
                        weekdaystart:0,
                        updateformat: 'yyyy-mm-dd'
                        });
                    el.calObj.parent = el;

                    // add text message
                    message = new Element('div',
                    {
                        'class': 'cal-message'
                    });
    
                    message.update('Delivery date should be at least 2 business days from now.');

                    el.cal.insert({bottom: message});
                }

                el.cal.top = el.cumulativeOffset()[1] - el.cumulativeScrollOffset()[1] + document.body.cumulativeScrollOffset()[1] + el.getHeight();
                el.cal.left = el.cumulativeOffset()[0]  - el.cumulativeScrollOffset()[0] + document.body.cumulativeScrollOffset()[0];

                el.cal.setStyle({
                    'left': el.cal.left + 'px',
                    'top': el.cal.top + 'px'
                });

                el.calObj.openCalendar();
            });

            el.observe('blur', function(e)
            {
                var el = Event.element(e);

                // check if mouse over or not
                if (
                       mouseX < el.cal.left
                    || mouseX > el.cal.left + el.cal.getWidth()
                    || mouseY < el.cal.top
                    || mouseY > el.cal.top + el.cal.getHeight()
                    )
                {
                    el.calObj.closeCalendar();
                }
                else
                {
                    calToClose = el;
                }

            });

        });

        calToClose = null;

        // {{{ let's track down the mouse
        Event.observe(document, 'mousemove', function(event){
            mouseX = Event.pointerX(event);
            mouseY = Event.pointerY(event);

            if (calToClose)
            {
                if (
                       mouseX < calToClose.cal.left
                    || mouseX > calToClose.cal.left + calToClose.cal.getWidth()
                    || mouseY < calToClose.cal.top
                    || mouseY > calToClose.cal.top + calToClose.cal.getHeight()
                    )
                {
                    calToClose.calObj.closeCalendar();
                    calToClose = null;
                }
            }
        });
    });

    /* add select all orders */
    if ($('shopping_bag-items-header-order'))
    {
        (function()
        {
            var c = new Element('input',
            {
                'type': 'checkbox',
                'title': 'Select/Unselect all items',
                'id': 'shopping_bag-items-header-order-checkbox',
                'class': 'input-checkbox'
            });

            $('shopping_bag-items-header-order').up().insert({top: c});

            $('shopping_bag-items-header-order').update('<label for="shopping_bag-items-header-order-checkbox">SELECT ALL</label>');

            c.observe('click', function(e)
            {
                $$('#shopping_bag-items input.input-checkbox').each(function(el)
                {
                    el.checked = $('shopping_bag-items-header-order-checkbox').checked;
                });
            });
        })();
    }

    // {{{ add live function to the search box
    if ($('search-words'))
    {
        // wrap into function to make variables local
        (function(){

            // turn off autocomplete
            $('search-words').setAttribute('autocomplete', 'off');

            // create search results div
            var result = new Element('div',
            {
                'id': 'search-words-result',
                'class': 'ia_dropdown-box'
            });

            // some makeup
            result.setOpacity(0.9);

            // hide it
            result.hide();

            // place it
            result.setStyle({
                'top': (parseInt($('search-words').cumulativeOffset()[1], 10) + parseInt($('search-words').getHeight(), 10)) + 'px',
                'left': $('search-words').cumulativeOffset()[0] + 'px',
                'width': (parseInt($('search-words').getWidth())-12) + 'px'
            });

            // inject result div
            $(document.body).insert({bottom: result});

/*
            // add "live" search behavior
            $('search-words').observe('keyup', function(e)
            {
                var el = e.element();

                if (el.value.length > 2)
                {
                    if (el.value !== el.oldValue)
                    {
                        $('search-words-result').show();
                        new Ajax.Updater($('search-words-result'), '/search/items.js', { method: 'post', parameters: 'q='+el.value});
                    }
                }
                else
                {
                    $('search-words-result').hide();
                }

                // store current value
                el.oldValue = el.value

                if ($('search_item-result-1'))
                {
                    $('search_item-result-1').addClassName('search_item-result-current');

                    if (e.keyCode == Event.KEY_RETURN)
                    {
                        document.location = $('search_item-result-1').down('a').href;
                    }
                }
            });
*/

        new Ajax.Autocompleter("search-words", "search-words-result", "/search/items.js",
        {
          paramName: "q", 
          minChars: 2
        });

        })();
    }

    /* add print div for text areas */
    $$('textarea.textarea').each(function(el)
    {
        var d = new Element('div',
        {
            'class': 'textarea'
        });

        d.update(el.value);

        el.insert({before: d});
    });

/* fire loaded event */

document.fire('loaded:main');

/* End */
});

/* Subroutines */

/**
 * Function that could be used to round a number to a given decimal points. Returns the answer
 * Arguments :  number - The number that must be rounded
 *              decimal_points - The number of decimal points that should appear in the result
 */
function roundNumber(number,decimal_points)
{
    number = parseFloat(number);

    if(!decimal_points) return Math.round(number);
    
    if(number == 0) {
        var decimals = "";
        for(var i=0;i<decimal_points;i++) decimals += "0";
        return "0."+decimals;
    }

    var exponent = Math.pow(10,decimal_points);
    var num = Math.round((number * exponent)).toString();
    return num.slice(0,-1*decimal_points) + "." + num.slice(-1*decimal_points)
}

function pop_alert(text, title)
{
    if (!$('alert'))
    {
        (function(){

            var alert_cover = new Element('div',
            {
                'id': 'alert_cover'
            });
            alert_cover.setStyle({
                'width': '100%',
                'height': ($('copyright').getHeight() + $('copyright').cumulativeOffset()[1]) + 'px'
            });

            alert_cover.hide();
            $(document.body).insert({bottom: alert_cover});

            var alert_pop = new Element('div',
            {
                'id': 'alert'
            });
            alert_pop.hide();
            document.body.insert({bottom: alert_pop});

            new Ajax.Updater(alert_pop, '/c/alert.html',
            {
                onComplete: function ()
                {
                    // show alert
                    pop_alert(text, title);

                    // highlight Close links
                    $('alert-close').addClassName('highlighted interactive');

                    // Action for Close link
                    $('alert-close').observe('click', function(e)
                    {
                        Event.stop(e);
        
                        new Effect.Parallel([
                          new Effect.Fade('alert_cover', {sync: true, from: 0.8, to: 0}), 
                          new Effect.Fade('alert', {sync: true, from: 1, to: 0 })
                        ], { 
                          duration: 1.5
                        });
                    });
                }
            }); 
        })();
    }
    else
    {
        // Show alert message
        if (text)
        {

            $('alert-text').update(text);

            // IE Hack
            document.viewport = $(document).viewport;

            // check if title provided
            if (title)
            {
                $('alert-title').update(title);
            }
            else
            {
                $('alert-title').update('ALERT MESSAGE');
            }

            $('alert').setStyle({
                'top': (document.body.cumulativeScrollOffset()[1] + Math.floor(document.viewport.getDimensions().height*0.5) - Math.floor($('alert').getHeight()*0.5) /* just to make it visually in the middle */) + 'px'
            });

            new Effect.Parallel([
              new Effect.Appear('alert_cover', {sync: true, from: 0, to: 0.8}), 
              new Effect.Appear('alert', {sync: true, from: 0, to: 1 }) 
            ], { 
              duration: 1.5
            });

        }
    }
}
