var Onyx = {
  Transitions: {
    linear: Prototype.K,
    sinoidal: function(pos) {
      return (-Math.cos(pos*Math.PI)/2) + .5;
    },
    reverse: function(pos) {
      return 1-pos;
    },
    flicker: function(pos) {
      var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
      return pos > 1 ? 1 : pos;
    },
    wobble: function(pos) {
      return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
    },
    pulse: function(pos, pulses) {
      return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
    },
    spring: function(pos) {
      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
    },
    none: function(pos) {
      return 0;
    },
    full: function(pos) {
      return 1;
    }
  }
};

Element.addMethods( {
    toHTML: function(element) {
        if (typeof element=='string') element = $(element);
        return Try.these(function() {
                            var xmlSerializer = new XMLSerializer();
                            return  element.nodeType == 4 ? element.nodeValue 
                                                          : xmlSerializer.serializeToString(element);
                         },
                         function() {
                            return element.xml || element.outerHTML || $(element).clone().wrap().up().innerHTML;
                         }) || '';
    },

    getStyles: function(element) {
        element = $(element);
        return $A(element.style).inject({}, function(styles, styleName) {
                                                styles[styleName.camelize()] = element.getStyle( styleName );
                                                return styles;
                                            });
    },

    clone: function(element) {
        var clone = new Element(element.tagName);
        $A(element.attributes).each(function(attribute) { 
                                        if(attribute.name != 'style') clone[attribute.name] = attribute.value; 
                                    });
        clone.setStyle(element.getStyles());
        clone.update(element.innerHTML);
        return clone;
    },
	bringToFront : function(element) {
		element.setStyle({zIndex:'2'});
		return element;
	},
	sendToBack : function(element) {
		element.setStyle({zIndex:'1'});
		return element;
	},
	getHeight : function (element) {
		return element.offsetHeight;	
	},
	getWidth : function (element) {
		return element.offsetWidth;	
	},		
	getCenterHeight : function(element) {	
		return (element.offsetHeight/2);
	},
	getCenterWidth : function(element) {
		return (element.offsetWidth/2);
	},
	isLoaded : function (element) {
		return (element.complete);
	}
});

function popProfile(id, src) {
    if(!src) {
        alert("Call from unknown source");
        src = "";
    }
    var wnd = window.open("/ViewProfile.aspx?id="+id+"&source="+src, "profile_"+id.replace(/\-/g,''), "status=0,toolbar=0,menubar=0,resizable=1,width=600,height=550,scrollbars=1");
    wnd.focus();
}

function popPhotoEdit(memberId,photoId) {
    var wnd = window.open("/MemberPhotoEdit.aspx?memberId="+memberId+"&photoId="+photoId, "photoEdit_"+photoId.replace(/\-/g,''), "status=0,toolbar=0,menubar=0,resizable=1,width=550,height=450,scrollbars=1");
    wnd.focus();
}

function popSendMsg(memberId) {
    var wnd = window.open("/MailBox.aspx?toId="+memberId+"&ex=", "msg_"+memberId.replace(/-/g,''), "status=0,toolbar=0,menubar=0,resizable=0,width=550,height=370,scrollbars=0");
    wnd.focus();
}

function popSendGift(memberId) {
    var wnd = window.open("/SendGift.aspx?toId="+memberId+"&ex=", "gift_"+memberId.replace(/-/g,''), "status=0,toolbar=0,menubar=0,resizable=0,width=660,height=535,scrollbars=0");
    wnd.focus();
}

function nav(url) {
    document.location.href = url;
}

var isEKHAttached = false;

function escKeyHandler(event) {
    if(event.keyCode == Event.KEY_ESC) window.close();
}

function detachEscKeyHandler() {
    Event.stopObserving(document, "keydown", escKeyHandler);
}

function attachEscKeyHandler() {
    Event.observe(document, "keydown", escKeyHandler);
    isEKHAttached = true;
}

function attachReturnKey(element, handler) {
    Event.observe(element, 'keydown', function(event) {
        if(event.keyCode == Event.KEY_RETURN) {
            handler(event);
            Event.stop();
        }
    });
}

function addFriend(atId, callback) {
    new Ajax.Request("/MemberServices.aspx", {
        method: "get",
        parameters: { op: 4, memberId: atId },
        onSuccess: function(transport) {
            var json = transport.responseText.evalJSON(true);
            if(ajaxOperationSuccess(json)) {
                if(json.message) alert(json.message);
                updateNotifications();
                if(Object.isFunction(callback)) callback(json.addRemove, atId);
            }
        },
        onFailure: function(transport) {
            ajaxFailure();
        }
    });
}

function blockMember(element, atId, callback) {
    var isBlocked = $(element).readAttribute('isBlocked') == '1';
    if(isBlocked) {
        toggleBlock(element, atId, callback);
    } else {
        new DialogBox.Ask('', { onYes: function() { toggleBlock(element, atId, callback); } });
    }
}

function toggleBlock(element, atId, callback) {
    new Ajax.Request("/MemberServices.aspx", {
        method: "get",
        parameters: { op: 5, memberId: atId },
        onSuccess: function(transport) {
            var json = transport.responseText.evalJSON(true);
            if(ajaxOperationSuccess(json)) {
                if(json.message) alert(json.message);
                $(element).writeAttribute('isBlocked', json.addRemove == 'added');
                if(Object.isFunction(callback)) callback(json.addRemove, atId);
            }
        },
        onFailure: function(transport) {
            ajaxFailure();
        }
    });
}

function sendWink(atId, callback) {
    new Ajax.Request("/MemberServices.aspx", {
        method: "get",
        parameters: { op: 3, memberId: atId },
        onSuccess: function(transport) {
            var json = transport.responseText.evalJSON(true);
            if(ajaxOperationSuccess(json)) {
                if(json.message) alert(json.message);
                updateNotifications();
                if(Object.isFunction(callback)) callback(json.addRemove, atId);
            }
        },
        onFailure: function(transport) {
            ajaxFailure();
        }
    });
}

function DefaultUpdateWink(addRemove,id) {
    $("txtWink"+id).update("");
    $("imgWink"+id).src = "/images/ico-wink-d.png";
    $("lnkWink"+id).onclick = "";
    $("icoWink"+id).writeAttribute("keepVisible", "true");
}

function DefaultUpdateFriend(addRemove,id) {
    if(addRemove == "added") {
        $("txtFriend"+id).update("");
        $("imgFriend"+id).src = "/images/ico-fav-d.png";
        $("icoFriend"+id).writeAttribute("keepVisible", "true");
    }
    else if(addRemove == "removed") {
        $("txtFriend"+id).update("");
        $("imgFriend"+id).src = "/images/ico-fav.png";
        $("icoFriend"+id).writeAttribute("keepVisible");
    }
}

function DefaultUpdateBlock(addRemove,id) {
    if(addRemove == "added") {
        $("txtBlock"+id).update("");
        $("imgBlock"+id).src = "/images/ico-blk-d.png";
        $("icoBlock"+id).writeAttribute("keepVisible", "true");
        isBlocked = true;
    }
    else if(addRemove == "removed") {
        $("txtBlock"+id).update("");
        $("imgBlock"+id).src = "/images/ico-blk.png";
        $("icoBlock"+id).writeAttribute("keepVisible");
        isBlocked = false;
    }
}

function setRating(id, ratingVal, callback) {
    new Ajax.Request("/MemberServices.aspx", {
        method: "get",
        parameters: { op: 1, memberId: id, rating: ratingVal },
        onSuccess: function(transport) {
            if(ajaxOperationSuccess(transport.responseText.evalJSON(true)) && Object.isFunction(callback)) 
                callback(ratingVal, id);
        },
        onFailure: function() {
            ajaxFailure();
        }
    });
}

function exHelp(title) {
    var wnd = window.open("/Help.aspx?ex=&title="+title, "exHelp", "status=0,toolbar=0,menubar=0,resizable=1,width=450,height=500,scrollbars=1");
    wnd.focus();
}

function validateTextLength(txt, counterId, min, max, limit) {
    var counter = $(counterId);
    var len = txt.value.length;
    if( limit && len > max ) 
    {
        txt.value = txt.value.substring(0, max);
        len = max;
    }
    counter.update(len + " / " + max);
    if( len < min || len > max )
        counter.className = "textCounterInvalid";
    else
        counter.className = "textCounterValid";
}

function sanitizeTR(str) {
    var fs = "ĞÜŞİÖÇğüşıöç";
    var rs = "GUSIOCgusioc";
    var outstr = "";
    for(i=0, len=str.length; i < len; i++) {
        var fsi = fs.indexOf(str.charAt(i));
        if(fsi >= 0) outstr += rs.charAt(fsi); else outstr += str.charAt(i);
    }
    return outstr;
}

function ajaxOperationSuccess(json, show) {
    if(!json || !json.status) return false;
    switch(json.status) {
        case "success": return true;
        case "failed": 
            if(show) alert("İşlem başarısız. Lütfen daha sonra yeniden deneyiniz."); 
            return false;
        case "loginRequired": 
            if(show) alert("Sisteme giriş yapmalısınız. Uzun süre işlem yapmadığınız için sistemden otomatik olarak çıkarılmış olabilirsiniz."); 
            return false;
    }
    return false;
}

function ajaxFailure(transport, show) {
    if(show) {
        alert("Site ile bağlantı kurulamadı. Lütfen İnternet bağlantınızı kontrol edip yeniden deneyiniz.");
        alert(transport.responseText);
    }
}

function setChanged(el, text) {
    $(el).update(text);
    $(el).className = "notSaved";
    new Effect.Appear($(el), {duration:0.3});
}

function setSaved(el, text) {
    $(el).update(text);
    $(el).className = "saved";
    new Effect.Highlight($(el));
    setTimeout("new Effect.Fade($('"+el.id+"'), {duration:0.3});", 3000);    
}

var MultiSelectCheckBox = Class.create({
    initialize: function(container, togglecb, selectionChanged) {
        if($(container) == null) return;
        this.togglecb = $(togglecb);
        this.selectionChanged = selectionChanged;
        this.checkBoxes = $(container).select("input[type='checkbox']").without(this.togglecb);
        var allChecked = true;
        for(i=0, len=this.checkBoxes.length; i < len; ++i) {
            Event.observe(this.checkBoxes[i], "click", this.checkBoxChanged.bind(this));
            if(!this.checkBoxes[i].checked) allChecked = false;
        }
        if(allChecked) this.togglecb.checked = true;
        Event.observe(this.togglecb, "click", this.toggleSelection.bind(this));
    },
    toggleSelection: function(event) {
        var check = this.togglecb.checked;
        if(event.shiftKey) {
            for(i=0, len=this.checkBoxes.length; i < len; ++i)
                this.checkBoxes[i].checked = !this.checkBoxes[i].checked;
        } else {
            for(i=0, len=this.checkBoxes.length; i < len; ++i)
                this.checkBoxes[i].checked = check;
        }
        if(Object.isFunction(this.selectionChanged)) this.selectionChanged();
    },
    isAllChecked: function() {
        var allChecked = true;
        for(i=0, len=this.checkBoxes.length; i < len; ++i)
            if(!this.checkBoxes[i].checked) allChecked = false;
        return allChecked;
    },
    checkBoxChanged: function(event) {
        if(this.isAllChecked())
            this.togglecb.checked = true;
        else
            this.togglecb.checked = false;
    }
});

var Accordion = Class.create({
    initialize: function(container, options) {
        this.options = Object.extend(Object.extend({}, this.DefaultOptions), options || {});
        this.container = $(container);
        var toggles = this.container.select('.'+this.options.classToggleCollapsed);
        for(i=0, len=toggles.length; i < len; ++i) {
            Event.observe(toggles[i], 'click', this.toggleClick.bind(this));
        }
        this.active = null;
    },
    DefaultOptions: {
        classToggleCollapsed: "grCol",
        classToggleExpanded: "grEx",
        classContentCollapsed: "grCCol",
        classContentExpanded: "grCEx",
        scrollToElement: 'pageTop',
        effectExpand: null, // { effect: Effect.SlideDown, options: { duration: 1 } },
        effectCollapse: null // { effect: Effect.SlideUp, options: { duration: 1 } }
    },
    toggleClick: function(event) {
        var toggle = Event.element(event);
        this.expand(toggle);
    },
    _collapsed: function(event) {
        this.active.className = this.options.classToggleCollapsed;
        this.active.next().className = this.options.classContentCollapsed;
    },
    _expanded: function(event, toggle) {
        toggle = $(toggle);
        toggle.className = this.options.classToggleExpanded;
        toggle.next().className = this.options.classContentExpanded;
    },
    expand: function(toggle) {
        var fx = [];
        toggle = $(toggle);
        if(this.active != null) {
            if(this.options.effectCollapse != null) {
                fx.push(new this.options.effectCollapse.effect(this.active.next(), 
                                                               Object.extend(this.options.effectCollapse.options, 
                                                                             { afterFinish: this._collapsed.bindAsEventListener(this) } )));
            } else {
                this._collapsed();
            }
        }
        if(toggle == this.active) {
            this.active = null;
            return;
        }
        if(this.options.effectExpand != null) {
            fx.push(new this.options.effectExpand.effect(toggle.next(), 
                                                         Object.extend(this.options.effectExpand.options, 
                                                                       { afterFinish: this._expanded.bindAsEventListener(this, toggle) } )));
        } else {
            this._expanded(event, toggle);
        }
        if(fx.length > 0)
            new Effect.Parallel(fx);
        this.active = toggle;
        if(this.options.scrollToElement != null)
            new Effect.ScrollTo(this.options.scrollToElement, {duration: 0.5});
        return this;
    }
});

var DialogBoxCurrent = null;

var DialogBox = Class.create({
    initialize: function(wnd, container, staticContent) {
        this.wnd = $(wnd);
        this.container = $(container);
        this.staticContent = staticContent || null;
        this.options = { parameters: { }, 
                         replace: [], 
                         width: 450, 
                         escapeCalls: null, 
                         onShow: Prototype.emptyFunction, 
                         onClose: Prototype.emptyFunction };
        this.result = null;
    },
    show: function(page, options) {
        this.options = Object.extend(this.options, options || {});
        var instance = this;
        if(this.staticContent != null) {
            var c = this.staticContent;
            for(i = 0, len = this.options.replace.length; i < len; ++i) {
                c = c.replace("$"+this.options.replace[i]+"$", eval("options."+this.options.replace[i]));
            }
            while(c.indexOf('\n') >= 0)
                c = c.replace('\n', '<br>');
            this.container.update(c);
            this.showDialog(this.options.width);
        } else if(page != null) {
            new Ajax.Updater(this.container, page, { evalScripts: true, parameters: this.options.parameters, 
                                                     onComplete: function(transport) {
                                                        instance.showDialog();
                                                     } 
                                                   });
        }
    },
    showDialog: function() {
        var instance = this;
        var cx = (document.viewport.getWidth() - this.options.width) / 2;
        var h = this.wnd.getDimensions().height;
        this.wnd.setStyle({left: cx + "px", top: (-h) + "px", width: this.options.width + "px", display: 'block'});
        DialogBoxCurrent = this;
        new Effect.Move(this.wnd, 
                        { x: cx, 
                          y: -200, 
                          mode: 'absolute', 
                          transition: Effect.Transitions.spring, 
                          duration: 1.0,
                          afterFinish: function() {
                            instance.options.onShow(instance);
                          }
                        });
        if(this.options.escapeCalls != null) {
            Event.observe(document, "keydown", function(event) { 
                if(event.keyCode == Event.KEY_ESC) {
                    instance.close(instance.options.escapeCalls);
                    Event.stop(event);
                }
            });
        }
    },
    close: function(callbackName) {
        this.wnd.hide();
        if(!Object.isUndefined(eval("this.options.on"+callbackName))) 
            eval("this.options.on"+callbackName)(this, callbackName);
        this.options.onClose(this, callbackName);
        return false;
    }
});

//
// new DialogBox.Ask("Question HTML",
//                   { onYes: function() { alert('Yes Selected'); },
//                     onNo: function() { alert('No Selected'); } });
//
// Call DialogBoxCurrent.close('Yes') and DialogBoxCurrent.Close('No') to trigger named handler functions
//
DialogBox.Ask = function(question, options) {
    if(isEKHAttached) detachEscKeyHandler();
    new DialogBox("dialogWnd", "dialogContainer", '<table border="0" cellspacing="0" cellpadding="0" width="100%"> \
<tr><td style="padding: 8px 16px 0px 8px; vertical-align:top;"><img src="/images/ico-qmark.png" alt="" /></td> \
    <td style="padding: 8px 8px 8px 8px; color: #fff;">$q$</td></tr> \
<tr><td colspan="2" style="text-align:center; padding:16px 0px 0px 0px;"> \
        <button id="butYes" onclick="return DialogBoxCurrent.close(\'Yes\');" class="formControl" style="width:60px;">Evet</button>&nbsp; \
        <button id="butNo" onclick="return DialogBoxCurrent.close(\'No\');" class="formControl" style="width:60px;">Hayır</button></td></tr> \
</table>').show(null, Object.extend({ replace: ['q'], 
                                      q: question, 
                                      width: 400,
                                      escapeCalls: 'No',
                                      onClose: function() { if(isEKHAttached) attachEscKeyHandler(); } 
                                    }, options));
};

var Slider = Class.create({
    initialize: function(wnd, container, width) {
        this.wnd = $(wnd);
        this.container = $(container);
        if(this.container == null || this.wnd == null) return;
        this.width = width;
        this.items = $A(new Array());
        this.effect = null;
        this.container.setStyle({position: 'relative', left: (this.width + 10)+'px'});
        Event.observe(this.wnd, 'mouseover', this.stop.bind(this));
        Event.observe(this.wnd, 'mouseout', this.go.bind(this));
        this.setUpdateTimer();
    },
    update: function() {
        var instance = this;
        new Ajax.Request("/MemberServices.aspx", {
            method: "get",
            parameters: { op: 10 },
            onSuccess: function(transport) {
                var json = transport.responseText.evalJSON(true);
                if(ajaxOperationSuccess(json) && json.count > 0) {
                    for(i = 0; i < json.count; ++i) {
                        instance.addMember(eval("json.item"+i));
                    }
                }
                instance.setUpdateTimer();
            },
            onFailure: function(transport) {
                instance.setUpdateTimer();
            }
        });
    },
    setUpdateTimer: function() {
        setTimeout(this.update.bind(this), 60000);
        this.cleanUp();
    },
    getItem: function(sliderId) {
        for(i=0, len=this.items.length;i < len; ++i) {
            if(this.items[i].sliderId == sliderId) return this.items[i];
        }
        return null;
    },
    removeItem: function(item) {
        new Effect.Shrink(item.element, {duration:0.3, afterFinish: function() {item.element.remove();}});
        this.items = this.items.without(item);
    },
    cleanUp: function() {
        for(i=this.items.length-1;i >= 0; --i) {
            if(this.items[i].life.getTime() < new Date().getTime()) this.removeItem(this.items[i]);
        }
        if(this.effect != null && this.effect.state == "running") {
            this.stop(); this.go();
        }
    },
    addMember: function(item) {
        if(this.container == null || this.wnd == null || this.getItem(item.sliderId) != null) return;
        
        var instance = this;
        item.life = eval(item.life);
        item.life = new Date(item.life.getTime() + (item.life.getTimezoneOffset() * 60000));
        item.element = new Element( "div", { "class": "sliderMember", "id": "slider_"+item.sliderId, style:"display:none" });
        item.element.update("<table border='0' cellpadding='0' cellspacing='0' width='100%'>"+
                            "<tr><td style='width:80px'><img src='"+item.thumbnail+"'></td>"+
                            "<td class='sliderMemberInfo'>"+item.text+"</td></tr></table>");
        item.element.writeAttribute("sliderId", item.sliderId);
        if(this.items.length == 0) this.container.update();
        this.items.push(item);
        this.container.setStyle({width: ((170 * this.items.length)+this.width)+"px"});
        this.container.insert({bottom: item.element});
        Event.observe(item.element, "click", function() { popProfile(item.itemId, 'Slider'); });
        new Effect.Appear(item.element, {duration:0.4, afterFinish: function() { instance.stop(); instance.go(); }});
    },
    run: function(speed) {
        if(this.container == null || this.wnd == null) return;
        
        var toX = -(this.container.getWidth()-this.width);
        var fromX = this.container.positionedOffset().left;
        speed = speed || 50;
        var dur = (fromX - toX) / speed;
        //console.log("delta: %d, speed: %d, duration: %d", fromX - toX, speed, dur);
        this.effect = new Effect.Move(this.container, { x: toX, 
                                                        mode: 'absolute', 
                                                        duration: dur,
                                                        fps: 100,
                                                        transition: Effect.Transitions.linear,
                                                        afterFinish: this.restart.bind(this)});
    },
    restart: function() {
        this.container.setStyle({left:(this.width + 10)+"px"});
        this.run();
    },
    stop: function(event) {
        if(this.effect != null) this.effect.cancel();
    },
    go: function(event) {
        this.run();
    }
});

var MemberSelector = Class.create({
    initialize: function(nickTextBox, thumbnailContainer, infoContainer, callback) {
        this.nickTextBox = $(nickTextBox);
        this.thumbnail = $(thumbnailContainer);
        this.infoContainer = $(infoContainer);
        this.callback = callback;
        Event.observe(this.nickTextBox, "blur", this.updateThumbnail.bind(this));
        this.updateThumbnail();
    },
    updateThumbnail: function(event) {
        if(this.nickTextBox.value == "") {
            this.thumbnail.update("<br><br>Alıcı adını yazınız.");
            this.infoContainer.update();
            return;
        }
        var instance = this;
        new Ajax.Request("/MemberServices.aspx", {
            method: "get",
            parameters: { op: 9, nick: this.nickTextBox.value },
            onSuccess: function(transport) {
                var json = transport.responseText.evalJSON(true);
                if(json.status && json.status == "success") {
                    instance.thumbnail.update("<img src='"+json.tn+"'>");
                    instance.infoContainer.update("<b>"+json.nick+"</b>, "+json.age+", "+json.gender+", "+json.city);
                    if(Object.isFunction(instance.callback)) instance.callback(json.memberId);
                } else {
                    if(json.message) {
                        instance.thumbnail.update(json.message);
                    } else {
                        instance.thumbnail.update("<br><br>Alıcı adını yazınız.");
                    }
                    instance.infoContainer.update();
                }
            },
            onFailure: function(transport) {
                instance.thumbnail.update();
                instance.infoContainer.update();
            }
        });
    }
});

var MemberPreview = Class.create({
    initialize: function(element, id, tn, options, source) {
        this.memberId = id;
        this.thumbnailUrl = tn;
        this.source = source;
        this.options = Object.extend(Object.extend({}, this.DefaultOptions), options || {});
        this.element = $(element);
        this.effect = null;
        this.hideTimer = null;
        this.handlerMouseOver = this.mouseOver.bind(this);
        this.handlerMouseOut = this.mouseOut.bind(this);
        this.handlerMouseOverPreview = this.mouseOverPreview.bind(this);
        this.handlerMouseOutPreview = this.mouseOutPreview.bind(this);
        var pv = $("mp");
        pv.absolutize();
        Event.observe(this.element, "mouseover", this.handlerMouseOver);
    },
    DefaultOptions: {
        showName: false,
        showLinks: false,
        holdPosition: "top-left",
        effect: Effect.SlideDown,
        effectDuration: 0.2,
        effectOptions: {},
        hideTimeout: 0.4,
        previewSize: { width: 180, height: 180 }
    },
    mouseOver: function(event) {
        this.clearHideTimer();
        var instance = this;
        var pv = $("mp");
        this.cancelEffect();
        var pos = this.element.cumulativeOffset();
        var sz = this.element.getDimensions();
        pv.writeAttribute("memberId", this.memberId);
        pv.update("<a href='javascript:;' onclick='popProfile(\""+this.memberId+"\", \""+this.source+"\");'><img src='"+this.thumbnailUrl+"' border='0'></a>");
        var valign = (this.options.holdPosition.split("-")[0] || "bottom");
        var halign = (this.options.holdPosition.split("-")[1] || "right");
        var x = pos.left + sz.width;
        var y = pos.top + sz.height;
        if(valign == "top") y = pos.top; else if(valign == "middle") y = pos.top + (sz.height/2) - (this.options.previewSize.height/2);
        if(halign == "left") x = pos.left; else if(halign == "center") x = pos.left + (sz.width/2) - (this.options.previewSize.width/2);
        pv.setStyle({left: x + "px", 
                     top: y + "px",
                     width: this.options.previewSize.width + "px",
                     height: this.options.previewSize.height + "px"});
        pv.hide();
        pv.setOpacity(1.0);
        this.effect = new this.options.effect(pv, Object.extend({ duration: instance.options.effectDuration, afterFinish: function() { pv.style.display = "block"; }}, this.options.effectOptions));
        Event.observe(this.element, "mouseout", this.handlerMouseOut);
        Event.observe(pv, "mouseover", this.handlerMouseOverPreview);
        Event.observe(pv, "mouseout", this.handlerMouseOutPreview);
    },
    mouseOut: function(event) {
        //console.log("mouseOut");
        this.setHideTimer();
    },
    mouseOverPreview: function(event) {
        this.clearHideTimer();
    },
    mouseOutPreview: function(event) {
        //console.log("mouseOutPreview(element:%s)", Event.findElement(event).id);
        this.setHideTimer();
    },
    setHideTimer: function() {
        this.hideTimer = setTimeout(this.hidePreview.bind(this), this.options.hideTimeout * 1000);
        //console.log("timer %d is set", this.hideTimer);
    },
    clearHideTimer: function() {
        if(this.hideTimer == null) return;
        //console.log("clear timer %d", this.hideTimer);
        if(this.hideTimer) clearTimeout(this.hideTimer);
        this.hideTimer = null;
    },
    hidePreview: function() {
        this.clearHideTimer();
        var pv = $("mp");
        if(pv.readAttribute("memberId") != this.memberId) { return; }
        if(this.cancelEffect()) { pv.hide(); return; }
        this.effect = new Effect.Fade(pv, {duration:0.1});
        Event.stopObserving(this.element, "mouseout", this.handlerMouseOut);
        Event.stopObserving(pv, "mouseover", this.handlerMouseOverPreview);
        Event.stopObserving(pv, "mouseout", this.handlerMouseOutPreview);
    },
    cancelEffect: function() {
        if(this.effect && this.effect.state != "finished") {
            this.effect.cancel();
            return true;
        }
        return false;
    }
});

var PanelWindow = Class.create({
    initialize: function(idExt) {
        this.idSuffix = idExt;
        this.mainDiv = $("pwnd_"+idExt);
        this.heading = $("pwndHeading_"+idExt);
        this.content = $("pwndContent_"+idExt);
        this.expanded = this.heading.src.indexOf("-x.png") > 0;
        Event.observe(this.heading, "click", this.headingClick.bind(this));
    },
    headingClick: function(event) {
        if(this.expanded) {
            var instance = this;
            new Effect.SlideUp(this.content, {
                duration: 0.3,
                afterFinishInternal: function(effect) {
                    instance.heading.src = instance.heading.src.replace(/-x.png/g, ".png");
                    instance.content.hide();
                }});
            this.expanded = false;
        } else {
            this.heading.src = this.heading.src.replace(/.png/g, "-x.png");
            var instance = this;
            new Effect.SlideDown(this.content, {
                duration: 0.3,
                afterFinishInternal: function(effect) {
                    instance.content.show();
                }});
            this.expanded = true;
        }
        updatePanelUIState(this.idSuffix, this.expanded);
    }
});

var TextWaterMark = Class.create({
    initialize: function(textbox, text, options) {
        this.control = $(textbox);
        this.control.watermark = this;
        this.watermark = text;
        this.options = Object.extend(Object.extend({}, this.DefaultOptions), options || {});
        Event.observe(this.control, "focus", this.onFocus.bind(this));
        Event.observe(this.control, "blur", this.onBlur.bind(this));
        this.setWaterMark();
    },
    DefaultOptions: {
        textColor: 'black',
        waterMarkColor: 'gray',
        waterMarkCleared: null,
        waterMarkSet: null
    },
    onFocus: function(event) {
        this.clearWaterMark();
    },
    onBlur: function(event) {
        this.setWaterMark();
    },
    clearWaterMark: function() {
        if(this.control.value == this.watermark) {
            this.control.value = "";
            this.control.style.color = this.options.textColor;
            if(this.options.waterMarkCleared != null) this.options.waterMarkCleared(this.control);
        }
    },
    setWaterMark: function() {
        if(this.control.value == "") {
            this.control.value = this.watermark;
            this.control.style.color = this.options.waterMarkColor;
            if(this.options.waterMarkSet != null) this.options.waterMarkSet(this.control);
        }
    }
});

var ThumbRoller = Class.create({
    initialize: function(scroller,container,mainPhoto,params) {
        $(container).update("");
        this.scroller = $(scroller);
        this.container = $(container);
        this.mainPhoto = $(mainPhoto);
        for(i = 0, len = params.length-1; i < len; i++) {
            var te = new Element("img", { "class": "pvTn", "src": params[len]+"/40x40/"+params[i]+".jpg" });
            te.observe("click", this.thumbClick.bind(this));
            $(container).insert({bottom:te});
        }
    },
    
    thumbClick: function(event) {
        var te = Event.element(event);
        this.mainPhoto.src = te.src.replace(/40x40/, "180x180");
    }
});

PhotoEditMove = Class.create({
    initialize: function(container, width, height, inputX, inputY) {
        this.container = $(container);
        this.lastX = -1;
        this.lastY = -1;
        var tokens = this.container.style.backgroundPosition.split(" ");
        if(tokens.length != 2) return;
        this.x = parseInt(tokens[0]);
        this.y = parseInt(tokens[1]);
        this.w = width;
        this.h = height;
        this.inputX = $(inputX);
        this.inputY = $(inputY);
        if(!this.container) return;
        this.container.observe("mousedown", this.mouseDown.bind(this));
    },
    
    mouseDown: function(event) {
        if(!Event.isLeftClick(event)) return;
        var element = Event.element(event);
        if(element == null) return;
        this.lastX = Event.pointerX(event);
        this.lastY = Event.pointerY(event);
        element.observe("mousemove", this.mouseMove.bind(this));
        element.observe("mouseup", this.mouseUp.bind(this));
        Event.stop(event);
    },
    
    mouseUp: function(event) {
        var element = Event.element(event);
        if(element == null) return;
        element.stopObserving("mousemove");
        element.stopObserving("mouseup");
        Event.stop(event);
    },
    
    mouseMove: function(event) {
        var element = Event.element(event);
        if(element == null) return;
        if(!Event.isLeftClick(event)) {
            element.stopObserving("mousemove");
            element.stopObserving("mouseup");
        }
        var x = Event.pointerX(event);
        var y = Event.pointerY(event);
        var dx = 0, dy = 0;
        if(this.lastX != -1) {
            dx = x - this.lastX;
            dy = y - this.lastY;
        }
        this.lastX = x;
        this.lastY = y;
        
        this.x += dx;
        this.y += dy;
        if(this.x > 0) this.x = 0;
        if(this.x + this.w < 180) this.x = 180 - this.w;
        if(this.y > 0) this.y = 0;
        if(this.y + this.h < 180) this.y = 180 - this.h;
        this.container.style.backgroundPosition = this.x + "px " + this.y + "px";
        this.inputX.value = this.x;
        this.inputY.value = this.y;
        Event.stop(event);
    }
});

var ChkListHandler = Class.create({
    initialize: function(container, options) {
        this.options = Object.extend(Object.extend({}, this.DefaultOptions), options || {});
        this.containerElement = $(container);
        this.chkBoxes = new Array();
        this.hasLocker = false;
        var elements = this.containerElement.select("input[type='checkbox']");
        this.lockedOn = null;
        for(i = 0, len = elements.length; i < len; i++) {
            var element = elements[i];
            if(element.tagName == "INPUT") {
                if((element.parentNode.tagName == "TD" || element.parentNode.tagName == "SPAN") && 
                   (element.id.endsWith("_"+this.options.selectAnyIndex) || $(element.parentNode).readAttribute("lockOthers") == "true")) {
                    $(element.parentNode).writeAttribute("lockOthers", "true");
                    element.lockOthers = "true";
                    this.hasLocker = true;
                    if(element.checked) this.lockedOn = element;
                }
                Event.observe(element, "click", this.chkClicked.bind(this));
                this.chkBoxes.push(element);
                var lbl = element.next();
                if(lbl != null && lbl.tagName == "LABEL")
                    lbl.addClassName("clNormal");
            }
        }
        this.refreshStyle();
        return this;
    },
    DefaultOptions: {
        selectAnyIndex: ""        
    },
    refreshStyle: function() {
        if(this.lockedOn != null)
            this.lockOthers(this.lockedOn);
        this.hilightChecked();
    },
    
    chkClicked: function(event) {
        var chk = Event.element(event);
        if(!Object.isUndefined(chk.lockOthers) && chk.lockOthers == "true")
            this.lockOthers(chk);
        else if(this.hasLocker) {
            this.lockOthers(null);
            for(i = 0, len = this.chkBoxes.length; i < len; i++) {
                if(this.chkBoxes[i].lockOthers != undefined)
                    this.chkBoxes[i].checked = false;
            }
        }
        this.hilightChecked();
    },
    
    lockOthers: function(lockElement) {
        this.lockedOn = lockElement;
        for(i = 0, len = this.chkBoxes.length; i < len; i++) {
            var chk = this.chkBoxes[i];
            var lbl = chk.next();
            if(lbl == null || lbl.tagName != "LABEL") continue;
            if(lockElement == null || lockElement == chk || !lockElement.checked) {
                lbl.removeClassName("clDisabled");
                if(lockElement == chk) lbl.removeClassName("clChecked");
            } else if(lockElement.checked) {
                chk.checked = false;
                lbl.addClassName("clDisabled").removeClassName("clChecked");
            }
        }
    },
    
    hilightChecked: function() {
        for(i = 0, len = this.chkBoxes.length; i < len; i++) {
            var chk = this.chkBoxes[i];
            var lbl = chk.next(); 
            if(lbl == null || lbl.tagName != "LABEL") continue;
            if(chk.checked) {
                lbl.addClassName("clChecked");
            } else if(this.lockedOn == null) {
                lbl.removeClassName("clChecked");
            }
        }
    },
    
    checkAll : function() {
        for(i = 0, len = this.chkBoxes.length; i < len; i++) {
            var chk = this.chkBoxes[i];
            chk.checked = true;
        }
        this.refreshStyle();
    },
    
    uncheckAll : function() {
        for(i = 0, len = this.chkBoxes.length; i < len; i++) {
            var chk = this.chkBoxes[i];
            chk.checked = false;
        }
        this.refreshStyle();
    },
            
    setItemWidth: function(width) {
        for(i = 0, len = this.chkBoxes.length; i < len; i++) {
            var chk = this.chkBoxes[i];
            if(chk.parentNode.tagName == "TD" || chk.parentNode.tagName == "SPAN")
                $(chk.parentNode).insert({bottom: "<br><img src='/images/spacer.gif' height='0' width='"+width+"'>"});
        }
        return this;
    }
});

function updateNotifications() {
    new Ajax.Request("/MemberServices.aspx", {
        method: "get",
        parameters: {op:6},
        onSuccess: function(transport) {
            var json = transport.responseText.evalJSON(true);
            if(ajaxOperationSuccess(json)) {
                if(json.message) alert(json.message);
                if(json.msg) updateCap("msg", json.msg);
                if(json.gifts) updateCap("gifts", json.gifts);
                if(json.winks) updateCap("winks", json.winks);
                if(json.friends) updateCap("friends", json.friends);
                if(json.credits) updateCap("credits", json.credits);
            }
        },
        onFailure: function(transport) {
            ajaxFailure();
        }
    });
}

function updatePanelUIState(panelSuffix, isExpanded) {
    new Ajax.Request("/UIState.aspx", {
        method: "get",
        parameters: { panel: panelSuffix, expanded: isExpanded },
        onSuccess: function(transport) {
        },
        onFailure: function(transport) {
        }
    });
}

function updateCap(key,value) {
    var cl = $("capLeft_"+key);
    var cv = $("capValue_"+key);
    var cr = $("capRight_"+key);
    var oldValue = cv.innerHTML;
    var color = cl.readAttribute("color");
    if(value == "0")
        color = "gray";
    cl.src = "/images/caps-"+color+"-l.png";
    cr.src = "/images/caps-"+color+"-r.png";
    cv.style.background = "url(/images/caps-"+color+"-filler.png) repeat-x";
    cv.update(value);
}
