if (!window.jfmStaticHost)
    window.jfmStaticHost = "http://" + window.location.host;

// Workaround flags
var ieVersionMatch = navigator.appVersion.match(/MSIE (\d+\.\d+)/, '');
var ieVersion = ieVersionMatch != null ? Number(ieVersionMatch[1]) : null;
var pngTransparencyHack = ieVersion && ieVersion >= 5.5 && ieVersion < 7;
var noPngFades = ieVersion && ieVersion < 8;
var zIndexBug = noPngFades;

function doAppear(elt, options) {
    if (noPngFades)
        $(elt).show();
    else
        new Effect.Appear(elt, options);
}

function doFade(elt, options) {
    if (noPngFades)
        $(elt).hide();
    else
        new Effect.Fade(elt, options);
}

function imageUrl(basename) {
    return jfmStaticHost + basename;
}

// standard layout
function placeFooter() {
    var bottom;
    if (typeof(window.innerHeight) == 'number') {
      //Non-IE
      bottom = window.innerHeight;
    }
    else if (document.documentElement &&
                (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
      //IE 6+ in 'standards compliant mode'
      bottom = document.documentElement.clientHeight;
    }
    else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
      //IE 4 compatible
      bottom = document.body.clientHeight;
    }

    var yOffset = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
    $('footer').style.top = (bottom - 56 + yOffset) + "px";
}

window.onload = placeFooter;
window.onresize = placeFooter;
window.onscroll = placeFooter;

// Image button

ImageButton = Class.create();
Object.extend(ImageButton.prototype, {
    initialize: function (element, upSrc, hoverSrc, disabledSrc) {
        if (disabledSrc === undefined)
            disabledSrc = upSrc;
        this.element = $(element);
        this.upSrc = upSrc;
        this.hoverSrc = hoverSrc;
        this.disabledSrc = disabledSrc;
        this.enabled = true;
        
        this.element.src = upSrc;
        new Image().src = hoverSrc;
        new Image().src = disabledSrc;
        
        Event.observe(element, "mouseout", this.onMouseOut.bind(this));
        Event.observe(element, "mouseover", this.onMouseOver.bind(this));
        Event.observe(element, "click", this.handleClick.bind(this));
    },
    
    onMouseOut: function (event) {
        if (this.enabled)
            this.element.src = this.upSrc;
    },
    
    onMouseOver: function (event) {
        if (this.enabled)
            this.element.src = this.hoverSrc;
    },
    
    handleClick: function (event) {
        if (this.enabled && this.onClick)
            this.onClick(event);
    },
    
    setEnabled: function (state) {
        this.enabled = state;
        this.element.src = state ? this.upSrc : this.disabledSrc;
    }
});

ImageLoader = Class.create();
Object.extend(ImageLoader.prototype, {
    // element should be an empty div
    initialize: function (element, imgSrc) {
        this.element = $(element);
        this.setSrc(imgSrc);
    },
    
    setSrc: function (imgSrc) {
        this.imgSrc = imgSrc;
        this.timeout = window.setTimeout(this.setLoading.bind(this), 500);
        this.imgLoader = document.createElement("img");
        this.imgLoader.className = "loaded_image";
        try {
            Event.observe(this.imgLoader, "load", this.onLoad.bind(this));
            Event.observe(this.imgLoader, "readystatechange", this.onReadyStateChange.bind(this));
        }
        catch (e) {
        }
        this.imgLoader.src = imgSrc;
    },
    
    refresh: function () {
        this.setSrc(this.imgSrc);
    },
    
    onReadyStateChange: function () {
        if (this.imgLoader.readyState == 4)
            this.onLoad();
    },
    
    onLoad: function (event) {
        window.clearTimeout(this.timeout);
        this.element.innerHTML = "";
        this.element.appendChild(this.imgLoader);
    },
    
    setLoading: function () {
        this.indicator = document.createElement("img");
        this.indicator.className = "image_loader";
        this.indicator.src = imageUrl("/images/loading.gif");
        this.element.appendChild(this.indicator);
    }
});
    
// Homepage animation

Effect.Scroll = Class.create();
Object.extend(Object.extend(Effect.Scroll.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    if(!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      x:    0,
      y:    0,
      mode: 'relative'
    }, arguments[1] || {});
    this.start(options);
  },
  
  setup: function() {
    this.element.makePositioned();
    this.originalLeft = parseFloat(this.element.scrollLeft || '0');
    this.originalTop  = parseFloat(this.element.scrollTop  || '0');
    if(this.options.mode == 'absolute') {
      // absolute movement, so we need to calc deltaX and deltaY
      this.options.x = this.options.x - this.originalLeft;
      this.options.y = this.options.y - this.originalTop;
    }
  },
  
  update: function(position) {
    this.element.scrollLeft = Math.round(this.options.x * position + this.originalLeft);
    this.element.scrollTop = Math.round(this.options.y * position + this.originalTop);
  }
});


FlowerScroller = function () {};
FlowerScroller.prototype = {
  numFlowers: 6,
  flowersLoaded: 0,
  realWidth: 0,
  flowersX: 0,

  start: function () {
    this.startIndex = Math.floor(Math.random() * this.numFlowers);
    for (var i = 0; i < this.numFlowers; i++) {
      var img = document.createElement("img");
      $(img).hide();
      $("flower_list").appendChild(img);
      Event.observe(img, "load", this.showFlower.bind(this, img));
      img.src = imageUrl("/images/welcome_bouquet_" + ((i + this.startIndex) % this.numFlowers + 1) + ".jpg");
    }
  },

  showFlower: function (img) {
    doAppear(img, {duration: 0.5});
    this.flowersLoaded++;
    if (this.flowersLoaded == this.numFlowers)
      this.startScroller();
  },
  
  startScroller: function () {
    var flowers = $("flower_list").getElementsByTagName("img");
    for (var i = 0; i < flowers.length; i++) {
      this.realWidth += flowers[i].width;
    }
    this.numFlowers = flowers.length;
    new Insertion.Bottom("flower_list", "<img src='" + imageUrl("/images/welcome_bouquet_") + (this.startIndex % this.numFlowers + 1) + ".jpg' />");
    new Insertion.Bottom("flower_list", "<img src='" + imageUrl("/images/welcome_bouquet_") + ((this.startIndex + 1) % this.numFlowers + 1) + ".jpg' />");
    this.startScrollFunc();
  },
  
  startScrollFunc: function () {
    $("flower_scroller").scrollLeft = 0;
    new Effect.Scroll("flower_scroller",
      {x: this.realWidth, duration: 10 * this.numFlowers, transition: Effect.Transitions.linear,
       afterFinish: this.startScrollFunc.bind(this)});
  }
};

// Scrolling div (specialized for garden)
ScrollDiv = Class.create();
Object.extend(ScrollDiv.prototype, {
    initialize: function (element, contentWidth) {
        element = $(element);
        this.element = element;
        this.pageSize = element.clientWidth * 0.5;
        this.arrowLeft = element.getElementsByClassName("arrow_left")[0];
        this.arrowRight = element.getElementsByClassName("arrow_right")[0];
        this.scrollingDiv = element.getElementsByClassName("scrolling_div")[0];
        this.content = element.getElementsByClassName("scroller_content")[0];
        this.contentWidth = contentWidth;
        this.content.style.width = contentWidth + "px";
        
        if (this.contentWidth <= this.element.clientWidth) {
            Element.hide(this.arrowLeft);
            Element.hide(this.arrowRight);
        }
        else {
            this.arrowLeft.style.opacity = 0.5;
            this.arrowRight.style.opacity = 0.5;
            Event.observe(this.arrowLeft, "mousedown", this.goLeft.bindAsEventListener(this));
            Event.observe(this.arrowRight, "mousedown", this.goRight.bindAsEventListener(this));
            Event.observe(this.arrowLeft, "mouseover", this.onArrowOver.bindAsEventListener(this));
            Event.observe(this.arrowRight, "mouseover", this.onArrowOver.bindAsEventListener(this));
            Event.observe(this.arrowLeft, "mouseout", this.onArrowOut.bindAsEventListener(this));
            Event.observe(this.arrowRight, "mouseout", this.onArrowOut.bindAsEventListener(this));
        }
    },
    
    onArrowOver: function (event) {
        Event.element(event).style.opacity = 1;
    },
    
    onArrowOut: function (event) {
        Event.element(event).style.opacity = 0.5;
    },
    
    goLeft: function (event) {
        this.scroll(- this.pageSize);
    },
    
    goRight: function (event) {
        this.scroll(this.pageSize);
    },
    
    scroll: function (amount) {
        new Effect.Scroll(this.scrollingDiv, {x: amount, duration: 0.5});
    },
    
    resize: function (newWidth) {
        if (newWidth < this.contentWidth) {
            me = this;
            if (this.scrollingDiv.scrollLeft + this.element.clientWidth > newWidth) {
                new Effect.Scroll(this.scrollingDiv, {x: newWidth - this.contentWidth, duration: 0.5,
                    afterFinish: function () { me.content.style.width = newWidth + "px"; }});
            }
            else {
                this.content.style.width = newWidth + "px";
            }
            
            this.contentWidth = newWidth;
            
            if (this.contentWidth <= this.element.clientWidth) {
                Element.hide(this.arrowLeft);
                Element.hide(this.arrowRight);
            }
        }
    }
});

// Greenhouse

var bouquets = [];
var watering;
var waterRequest;
var needyBouquets;
var fairyIndex;

// Bouquet in the greenhouse

GardenBouquet = Class.create();
Object.extend(GardenBouquet.prototype, {
    initialize: function (bouquetInfo, size) {
        var element = this.element = $(document.createElement("div"));
        this.size = size;
        this.bouquetId = bouquetInfo[0];
        this.sender = bouquetInfo[1];
        this.message = bouquetInfo[2];
        element.addClassName("garden_bouquet");
        
        new Insertion.Bottom(element, "<a href='/bouquet/" + this.bouquetId + "' title='Zoom in'><div class='bouquet_img'></div></a>");
        new Insertion.Bottom(element, "<div class='bouquet_card'><p>" + this.sender.escapeHTML() + "</p></div>");
        new Insertion.Bottom(element, "<img class='mulch_btn' />");
        
        this.bouquetImage = element.getElementsByClassName("bouquet_img")[0];
        this.card = element.getElementsByClassName("bouquet_card")[0];
        this.mulchElt = element.getElementsByClassName("mulch_btn")[0];
        this.mulchElt.hide();
        
        this.imageLoader = new ImageLoader(this.bouquetImage, "/bouquet/image/" + this.bouquetId + "." + size + ".png");
        this.mulchBtn = new ImageButton(this.mulchElt, "/images/mulch.png", "/images/mulch_hvr.png", "/images/mulch.png");
        this.mulchBtn.onClick = this.onMulchClick.bind(this);
        
        if (showMulch) {
            Event.observe(this.bouquetImage, "mouseout", this.onMouseOut.bindAsEventListener(this));
            Event.observe(this.bouquetImage, "mouseover", this.onMouseOver.bindAsEventListener(this));
        }
        
        Event.observe(this.card, "mouseover", this.onCardOver.bindAsEventListener(this));
    },
    
    refresh: function () {
        this.imageLoader.setSrc("/bouquet/image/" + this.bouquetId + "." + this.size + "." + Math.floor(Math.random() * 1000000000) + ".png");
    },
    
    onMouseOver: function (event) {
        this.mulchElt.show();
    },
    
    onMouseOut: function (event) {
    	var reltg = (event.relatedTarget) ? event.relatedTarget : event.toElement;
        if (reltg != this.mulchElt)
            this.mulchElt.hide();
    },
    
    onMulchClick: function (event) {
        if (watering)
            return;
        if (confirm("Are you sure you want to permanently remove this bouquet from your conservatory?"))
            this.mulch(event);
    },
    
    onCardOver: function (event) {
        $('big_card_sender').innerHTML = this.sender.escapeHTML();
        $('big_card_message').innerHTML = this.message.escapeHTML();
        var bigCard = $('big_card');
        bigCard.style.left = this.card.offsetParent.offsetLeft + "px";
        bigCard.show();
    },
    
    mulch: function (event) {
        if (event.shiftKey)
            new Insertion.Bottom($('garden_content'), "<embed src='/chipper.mp3' hidden='true' autostart='true' loop='false' />");

        new Ajax.Request("/bouquet/mulch/" + this.bouquetId,
            {asynchronous: false,
             method: "POST",
             onSuccess: this.mulchSuccess.bind(this),
             onFailure: this.mulchFailure.bind(this)});
    },
    
    mulchSuccess: function () {
        this.mulchElt.remove();
        this.card.remove();
        $('big_card').hide();
        
        new Insertion.Top(this.element, "<img src='/images/hole.png' style='position: absolute; z-index: 1; left: 131px; top: 246px; width: 0px; height: 0px;' />");
        var hole = this.element.getElementsByTagName("img")[0];
        var imgStyle = this.bouquetImage.style;
        imgStyle.position = "absolute";
        imgStyle.zIndex = 2;
        imgStyle.overflow = "hidden";
        imgStyle.height = "256px";
        imgStyle.top = "0px";
        new Effect.Morph(hole, {style: "width: 170px; height: 38px; left: 45px; top: 230px;", duration: 0.5});
        new Effect.Morph(this.bouquetImage, {style: "height: 0px; top: 256px", duration: 1.5, queue: 'end'});
        new Effect.Morph(hole, {style: "width: 0px; height: 0px; left: 131px; top: 246px;", transition: Effect.Transitions.linear, duration: 0.5, queue: 'end'});
        this.element.style.width = "256px";
        new Effect.Morph(this.element, {style: "width: 0px", queue: 'end',
            afterFinish: this.afterMulch.bind(this)});
    },
    
    mulchFailure: function () {
        alert("Sorry, for some reason we couldn't mulch the bouquet. Please try again later.");
    },
    
    afterMulch: function () {
        bouquets = bouquets.without(this);
        this.element.remove();
        gardenScroller.resize(bouquets.length * 180);
        if (bouquets.length == 0)
            $('watering').hide();
    }
});

function nodeContains(outer, inner) {
    var range = outer.ownerDocument.createRange();
    range.selectNode(outer);
    return range.intersectsNode(inner);
}

function bigCardMouseOut (event) {
    var tg = Event.element(event);
	if (tg.nodeName != 'DIV') return;
	var reltg = (event.relatedTarget) ? event.relatedTarget : event.toElement;
	while (reltg != tg && reltg && reltg.nodeName != 'BODY')
		reltg = reltg.parentNode;
	if (reltg == tg) return;
    $('big_card').hide();
}

var gardenScroller;

function buildGardenScroller(info) {
    var scroller = $('garden_scroller');
    for (var i = 0, n = info.length; i < n; i++) {
        var bouquet = new GardenBouquet(info[i], 256);
        bouquets.push(bouquet);
        scroller.appendChild(bouquet.element);
    }
    $('big_card').hide();
    Event.observe('big_card', "mouseout", bigCardMouseOut.bindAsEventListener());
    
    gardenScroller = new ScrollDiv("garden_content", bouquets.length * 180);
}

function waterGarden(gardenId) {
    if (watering)
        return;
    watering = true;
    waterRequest = new Ajax.Request("/garden/water_all/" + gardenId,
        {method: "POST", onSuccess: waterSuccess, onFailure: waterFailure});
}

function waterSuccess() {
    needyBouquets = eval(waterRequest.transport.responseText);
    $('water_fairy').style.display = "";
    $('water_fairy').style.left = "-100px";
    fairyIndex = -1;
    moveFairy();
}

function moveFairy() {
    if (fairyIndex >= 0 && fairyIndex < bouquets.length
            && needyBouquets.indexOf(bouquets[fairyIndex].bouquetId) != -1) {
        bouquets[fairyIndex].refresh();
    }
    
    fairyIndex++;
    
    var destX = 180 * fairyIndex;
    var options = {mode: 'absolute',
                   x: destX,
                   duration: (destX - $('water_fairy').offsetLeft) / 90};
    if (fairyIndex < bouquets.length) {
        options.afterFinish = moveFairy;
        options.afterUpdate = keepFairyVisible;
    }
    else {
        options.x = Math.max(1000, (bouquets.length + 1) * 180);
        options.afterFinish = finishFairy;
    }
    
    new Effect.Move($('water_fairy'), options);
}

function keepFairyVisible() {
    new Effect.Scroll($('garden_bench'),
        {mode: 'absolute', x: $('water_fairy').offsetLeft - 400, duration: 0.3, fps: 1});
}

function finishFairy() {
    $('water_fairy').style.display = "none";
    watering = false;
}

function waterFailure() {
    watering = false;
    alert("The water fairy is unavailable at the moment...please try again later!");
}

function showWidgetCode() {
    if ($('widget_reveal').style.display == "none")
        new Effect.SlideDown('widget_reveal', {duration: 0.5});
}

function showDailyCode() {
    if ($('daily_widget_reveal').style.display == "none")
        new Effect.SlideDown('daily_widget_reveal', {duration: 0.5});
}

// Arrangement picker

Arrangement = Class.create();
Object.extend(Arrangement.prototype, {
    initialize: function (arrId, arrName, arrImg) {
        var element = this.element = $(document.createElement("div"));
        this.arrId = arrId;
        this.arrImg = arrImg;
        
        element.addClassName("chooser_arrangement");
        
        new Insertion.Bottom(element, "<img src='/images/" + arrImg + ".png' class='chooser_arrangement_image' style='position: absolute; z-index: 3;' />");
        new Insertion.Bottom(element, "<img src='/images/" + arrImg + "_blur.png' class='chooser_arrangement_image' style='position: absolute; z-index: 1;' />");
        this.flowers = element.getElementsByClassName("chooser_arrangement_image");
        new Insertion.Bottom(element, "<div class='chooser_ribbon' style='z-index: 4'></div>");
        this.ribbon = element.getElementsByClassName("chooser_ribbon")[0];
        this.bannerBox = new BannerBox(this.ribbon, "id", arrId.toString(), arrImg);
        this.bannerBox.element.hide();
        this.bannerBox.onChange = this.onBannerChange.bind(this);
        
        Event.observe(this.element, "mouseover", this.onMouseOver.bindAsEventListener(this));
        Event.observe(this.element, "mouseout", this.onMouseOut.bindAsEventListener(this));
        Event.observe(this.element, "click", this.onClick.bindAsEventListener(this));
    },
    
    onMouseOver: function (event) {
        this.bannerBox.underMouse = true;
        if (this.isActive && !Arrangement.ignoreMouse)
            this.bannerBox.element.show();
    },
    
    onMouseOut: function (event) {
        this.bannerBox.underMouse = false;
        if (this.isActive && !Arrangement.ignoreMouse && !this.bannerBox.isChecked())
            this.bannerBox.element.hide();
    },
    
    onClick: function (event) {
        if (Arrangement.ignoreMouse)
            return;
        if (this.isActive) {
            this.bannerBox.element.show();
            this.bannerBox.onClick();
        }
        else {
            swapTiers();
        }
    },
    
    onBannerChange: function (banner) {
        if ($('send_next_button'))
            $('send_next_button').show();
        
        if (!banner.isChecked() && !banner.underMouse)
            banner.element.hide();
    },
    
    fixRibbon: function () {
        this.bannerBox.setBlur(!this.isActive);
        this.bannerBox.element.style.zIndex = this.isActive ? 3 : 1;
        this.ribbon.style.zIndex = this.isActive ? 4 : 2;
    },
    
    setIndex: function (newIndex) {
        this.isActive = (newIndex == 0);
        
        window.setTimeout(this.fixRibbon.bind(this), 500);
        
        var width = [195, 150][newIndex] + "px";
        if (this.element.style.width) {
            new Effect.Morph(this.element, {style: "width:" + width, duration: 1});
            if (this.isActive) {
                doAppear(this.flowers[0], {duration: 1});
                doFade(this.flowers[1], {duration: 1});
            }
            else {
                doAppear(this.flowers[1], {duration: 1});
                doFade(this.flowers[0], {duration: 1});
            }
        }
        else {
            this.element.style.width = width;
            if (this.isActive) {
                $(this.flowers[0]).show();
                $(this.flowers[1]).hide();
            }
            else {
                $(this.flowers[1]).show();
                $(this.flowers[0]).hide();
            }
        }
        
        this.index = newIndex;
    }
});

var tiers;

ChooserTier = Class.create();
Object.extend(ChooserTier.prototype, {
    // index: 0=front, 1=back
    initialize: function (element, index, arrangements) {
        element = $(element);
        this.element = element;
        this.arrangements = arrangements;
        var me = this;
        arrangements.each(function (arr) {
            me.element.appendChild(arr.element);
        });
        new Insertion.Bottom(element, "<div style='clear: both'></div>");
        this.setIndex(index);
    },
    
    setIndex: function (newIndex) {
        this.element.style.position = "absolute";
        var top =  ["120px", "0px" ][newIndex];
        var left = ["-2px" , "74px"][newIndex];
        if (this.element.style.top) {
            new Effect.Morph(this.element, {style: "top:" + top + ";left:" + left, duration: 1});
        }
        else {
            this.element.style.top = top;
            this.element.style.left = left;
        }
        
        if (zIndexBug)
            this.element.style.zIndex = [2, 1][newIndex];
        
        this.arrangements.each(function (arr) {
            arr.setIndex(newIndex);
        });
        this.index = newIndex;
    }
});

function swapTiers() {
    Arrangement.ignoreMouse = true;
    window.setTimeout(function () { Arrangement.ignoreMouse = false; }, 1000);
    tiers[0].setIndex(1 - tiers[0].index);
    tiers[1].setIndex(1 - tiers[0].index);
}

BannerBox = Class.create();
Object.extend(BannerBox.prototype, {
    current: null,
    
    initialize: function (element, name, value, imgSrc) {
        element = $(element);
        this.element = element;
        this.imgSrc = imgSrc;
        element.style.width = "176px";
        element.style.height = "47px";
        new Insertion.Bottom(element, "<img src='/images/" + imgSrc + "_rbbn.png' style='position: absolute;' />");
        new Image().src = "/images/" + imgSrc + "_rbbn_select.png";
        new Insertion.Bottom(element, "<input type='checkbox' name='" + name + "' value='" + value + "' style='display:none;' />");
        this.image = element.getElementsByTagName('img')[0];
        this.button = element.getElementsByTagName('input')[0];
        Event.observe(this.element, "click", this.onClick.bindAsEventListener(this));
        
        if (pngTransparencyHack) {
            this.image.width = 187;
            this.image.height = 58;
        }
    },
    
    isChecked: function () {
        return this.button.checked;
    },
    
    setImgSrc: function (imgSrc) {
        this.imgSrc = imgSrc;
        if (this.isChecked())
            this.setChecked(true);
        else
            this.setChecked(false);
    },
    
    onClick: function (event) {
        if (event)
            Event.stop(event);
        if (BannerBox.prototype.current)
            BannerBox.prototype.current.setChecked(false);
        this.setChecked(true);
        BannerBox.prototype.current = this;
    },
    
    setBlur: function (value) {
        this.blur = value;
        this.setChecked(this.button.checked);
    },
    
    setChecked: function (value) {
        var oldValue = this.button.checked;
        this.button.checked = value;
        this.image.src = this.blur ? "/images/blur_rbbn_select.png" : ("/images/" + this.imgSrc + (value ? "_rbbn_select.png" : "_rbbn.png"));
        if (this.onChange && value != oldValue)
            this.onChange(this);
    }
});
