/**********************************************************************************************
* PhotoNotes script v1.0                                                                      *
* Author: DaNCeT (dancet<at>gmail.com)                                                        *
* For usage at: http://www.schoolbord.be                                                      *
*                                                                                             *
* inspired by PhotoNotes script by Dusty Davidson - http://www.dustyd.net                     *
* inspired by YUI Ext Resizable class by Jack Slocum - http://www.yui-ext.com/                *
* but this script is more optimized and uses the YUI and YUI Ext libraries                    *
*                                                                                             *
* Usage, distribution and/or adaption only allowed after explicit authorisation of the author *
**********************************************************************************************/

YAHOO.ext.MyResizable = function(el, config){
    this.el = getEl(el);
    
    if(config && config.wrap){
        config.resizeChild = this.el;
        this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : null);
        this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap';
        this.el.setStyle('overflow', 'hidden');
        this.el.setPositioning(config.resizeChild.getPositioning());
        config.resizeChild.clearPositioning();
        if(!config.width || !config.height){
            var csize = config.resizeChild.getSize();
            
            
            this.el.setSize(csize.width, csize.height);
        }
        if(config.pinned && !config.adjustments){
            config.adjustments = 'auto';
        }
    }
    
    this.proxy = this.el.createProxy({tag: 'div', cls: 'yresizable-proxy', id: this.el.id + '-rzproxy'})
    this.proxy.unselectable();
    
    
    this.overlay = this.el.createProxy({tag: 'div', cls: 'yresizable-overlay', html: '&#160;'});
    this.overlay.unselectable();
    this.overlay.enableDisplayMode('block');
    this.overlay.mon('mousemove', this.onMouseMove, this, true);
    this.overlay.mon('mouseup', this.onMouseUp, this, true);
    
    YAHOO.ext.util.Config.apply(this, config, {
        
        resizeChild : false,
        
        adjustments : [0, 0],
        
        minWidth : 5,
        
        minHeight : 5,
        
        maxWidth : 10000,
        
        maxHeight : 10000,
        
        enabled : true,
        
        animate : false,
        
        duration : .35,
        
        dynamic : false,
        
        handles : false,
        multiDirectional : false,
        
        disableTrackOver : false,
        
        easing : YAHOO.util.Easing ? YAHOO.util.Easing.easeOutStrong : null,
        
        widthIncrement : 0,
        
        heightIncrement : 0,
        
        pinned : false,
        
        width : null,
        
        height : null,
        
        preserveRatio : false,
        
        transparent: false,
        
        minX: 0,
        
        minY: 0,
        
        maxX: 0,
        
        maxY: 0,
        
        draggable: false
    });
    
    if(this.pinned){
        this.disableTrackOver = true;
        this.el.addClass('yresizable-pinned');    
    }
    
    var position = this.el.getStyle('position');
    if(position != 'absolute' && position != 'fixed'){
        this.el.setStyle('position', 'relative');
    }
    if(!this.handles){ 
        this.handles = 's,e,se';
        if(this.multiDirectional){
            this.handles += ',n,w';
        }
    }
    if(this.handles == 'all'){
        this.handles = 'n s e w ne nw se sw';
    }
    var hs = this.handles.split(/\s*?[,;]\s*?| /);
    var ps = YAHOO.ext.MyResizable.positions;
    for(var i = 0, len = hs.length; i < len; i++){
        if(hs[i] && ps[hs[i]]){
            var pos = ps[hs[i]];
            this[pos] = new YAHOO.ext.MyResizable.Handle(this, pos, this.disableTrackOver, this.transparent);
        }
    }
    
    this.corner = this.southeast;
    
    this.activeHandle = null;
    
    if(this.resizeChild){
        if(typeof this.resizeChild == 'boolean'){
            this.resizeChild = YAHOO.ext.Element.get(this.el.dom.firstChild, true);
        }else{
            this.resizeChild = YAHOO.ext.Element.get(this.resizeChild, true);
        }
    }
    
    if(this.adjustments == 'auto'){
        var rc = this.resizeChild;
        var hw = this.west, he = this.east, hn = this.north, hs = this.south;
        if(rc && (hw || hn)){
            rc.setRelativePositioned();
            rc.setLeft(hw ? hw.el.getWidth() : 0);
            rc.setTop(hn ? hn.el.getHeight() : 0);
        }
        this.adjustments = [
            (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
            (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1 
        ];
    }
    
    if(this.draggable){
        this.dd = this.dynamic ? 
            this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
        this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
    }
    
    
    this.events = {
        
        'beforeresize' : new YAHOO.util.CustomEvent(),
        
        'resize' : new YAHOO.util.CustomEvent()
    };
    
    if(this.width !== null && this.height !== null){
        this.resizeTo(this.width, this.height);
    }else{
        this.updateChildSize();
    }
};

YAHOO.extendX(YAHOO.ext.MyResizable, YAHOO.ext.util.Observable, {
    
    resizeTo : function(width, height){
        this.el.setSize(width, height);
        this.updateChildSize();
        this.fireEvent('resize', this, width, height, null);
    },
    
    startSizing : function(e){
        this.fireEvent('beforeresize', this, e);
        if(this.enabled){ 
            this.resizing = true;
            this.startBox = this.el.getBox();
            this.startPoint = e.getXY();
            this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
                            (this.startBox.y + this.startBox.height) - this.startPoint[1]];
            this.proxy.setBox(this.startBox);
            
            this.overlay.setSize(YAHOO.util.Dom.getDocumentWidth(), YAHOO.util.Dom.getDocumentHeight());
            this.overlay.show();
            
            if(!this.dynamic){
                this.proxy.show();
            }
        }
    },
    
    onMouseDown : function(handle, e){
        if(this.enabled){
            e.stopEvent();
            this.activeHandle = handle;
            this.overlay.setStyle('cursor', handle.el.getStyle('cursor'));
            this.startSizing(e);
        }          
    },
    
    onMouseUp : function(e){
        var size = this.resizeElement();
        this.resizing = false;
        this.handleOut();
        this.overlay.hide();
        this.fireEvent('resize', this, size.width, size.height, e);
    },
    
    updateChildSize : function(){
        if(this.resizeChild){
            var el = this.el;
            var child = this.resizeChild;
            var adj = this.adjustments;
            if(el.dom.offsetWidth){
                var b = el.getSize(true);
                child.setSize(b.width+adj[0], b.height+adj[1]);
            }
            
            
            
            
            if(YAHOO.ext.util.Browser.isIE){
                setTimeout(function(){
                    if(el.dom.offsetWidth){
                        var b = el.getSize(true);
                        child.setSize(b.width+adj[0], b.height+adj[1]);
                    }
                }, 10);
            }
        }
    },
    
    snap : function(value, inc, min){
        if(!inc || !value) return value;
        var newValue = value;
        var m = value % inc;
        if(m > 0){
            if(m > (inc/2)){
                newValue = value + (inc-m);
            }else{
                newValue = value - m;
            }
        }
        return Math.max(min, newValue);
    },
    
    resizeElement : function(){
        var box = this.proxy.getBox();
        
        this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
        
        this.updateChildSize();
        this.proxy.hide();
        return box;
    },
    
    constrain : function(v, diff, m, mx){
        if(v - diff < m){
            diff = v - m;    
        } else if(v - diff > mx){
            diff = mx - v; 
        }
        return diff;                
    },
    
    mmConstrain : function(cDiff, diff, m, mx, mxDiff){
        if ((cDiff - diff) < m){
            diff = cDiff - m;    
        }
        if ((cDiff - diff) > mx){
            diff = mx - cDiff; 
        }

        if (diff < mxDiff) {
            diff = mxDiff;
        }

        return diff;                
    },
    
    onMouseMove : function(e){
        if(this.enabled){
            try {
                if (this.maxX && this.maxY) {
                    var useMax = 1;
                } else {
                    var useMax = 0;
                }
                var curSize = this.curSize || this.startBox;
                var x = this.startBox.x, y = this.startBox.y;
                var ox = x, oy = y;
                var w = curSize.width, h = curSize.height;
                var ow = w, oh = h;
                var mw  = this.minWidth, mh = this.minHeight;
                var mxw = this.maxWidth, mxh = this.maxHeight;
                var wi = this.widthIncrement;
                var hi = this.heightIncrement;
                
                var eventXY = e.getXY();
                var diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0]));
                var diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1]));
                
                var mmDiffX = -(this.startPoint[0] - eventXY[0]);
                var mmDiffY = -(this.startPoint[1] - eventXY[1]);
                
                var pos = this.activeHandle.position;
                if (useMax) {
                    // if maxX and/or maxY set (maxHeight and/or maxWidth are optional)
                    switch(pos){
                        case 'east': // works
                            w += mmDiffX;
                            mxDiffX = this.maxX - x;
                            w = Math.min(Math.max(mw, w), mxDiffX);
                            break;
                        case 'south': // works
                            h += mmDiffY;
                            mxDiffY = this.maxY - y;
                            h = Math.min(Math.max(mh, h), mxDiffY);
                            break;
                        case 'southeast': // works
                            w += mmDiffX; 
                            h += mmDiffY;
                            mxDiffY = this.maxY - y;
                            mxDiffX = this.maxX - x;
                            w = Math.min(Math.max(mw, w), mxDiffX);
                            h = Math.min(Math.max(mh, h), mxDiffY);
                            break;
                        case 'north':
                            mxDiffY  = this.minY - y;
                            diffY = this.mmConstrain(h, mmDiffY, mh, mxh, mxDiffY);
                            y += diffY;
                            h -= diffY;
                            break;
                        case 'west':
                            mxDiffX  = this.minX - x;
                            diffX = this.mmConstrain(w, mmDiffX, mw, mxw, mxDiffX);
                            x += diffX;
                            w -= diffX;
                            break;
                        case 'northeast':
                            w += mmDiffX;
                            mxDiffX = this.maxX - x;
                            w = Math.min(Math.max(mw, w), mxDiffX);
                            mxDiffY = this.minY - y;
                            diffY = this.mmConstrain(h, mmDiffY, mh, mxh, mxDiffY);
                            y += diffY;
                            h -= diffY;
                            break;
                        case 'northwest':
                            mxDiffX  = this.minX - x;
                            diffX = this.mmConstrain(w, mmDiffX, mw, mxw, mxDiffX);
                            mxDiffY  = this.minY - y;
                            diffY = this.mmConstrain(h, mmDiffY, mh, mxh, mxDiffY);
                            y += diffY;
                            h -= diffY;
                            x += diffX;
                            w -= diffX;
                            break;
                       case 'southwest':
                            mxDiffX  = this.minX - x;
                            diffX = this.mmConstrain(w, mmDiffX, mw, mxw, mxDiffX);
                            h += mmDiffY;
                            mxDiffY = this.maxY - y;
                            h = Math.min(Math.max(mh, h), mxDiffY);
                            x += diffX;
                            w -= diffX;
                            break;
                    }
                } else {
                    switch(pos){
                        case 'east':
                            w += diffX; 
                            w = Math.min(Math.max(mw, w), mxw);
                            break;
                        case 'south':
                            h += diffY;
                            h = Math.min(Math.max(mh, h), mxh);
                            break;
                        case 'southeast':
                            w += diffX; 
                            h += diffY;
                            w = Math.min(Math.max(mw, w), mxw);
                            h = Math.min(Math.max(mh, h), mxh);
                            break;
                        case 'north':
                            diffY = this.constrain(h, diffY, mh, mxh);
                            y += diffY;
                            h -= diffY;
                            break;
                        case 'west':
                            diffX = this.constrain(w, diffX, mw, mxw);
                            x += diffX;
                            w -= diffX;
                            break;
                        case 'northeast':
                            w += diffX; 
                            w = Math.min(Math.max(mw, w), mxw);
                            diffY = this.constrain(h, diffY, mh, mxh);
                            y += diffY;
                            h -= diffY;
                            break;
                        case 'northwest':
                            diffX = this.constrain(w, diffX, mw, mxw);
                            diffY = this.constrain(h, diffY, mh, mxh);
                            y += diffY;
                            h -= diffY;
                            x += diffX;
                            w -= diffX;
                            break;
                       case 'southwest':
                            diffX = this.constrain(w, diffX, mw, mxw);
                            h += diffY;
                            h = Math.min(Math.max(mh, h), mxh);
                            x += diffX;
                            w -= diffX;
                            break;
                    }
                }
                
                var sw = this.snap(w, wi, mw);
                var sh = this.snap(h, hi, mh);
                if(sw != w || sh != h){
                    switch(pos){
                        case 'northeast':
                            y -= sh - h;
                        break;
                        case 'north':
                            y -= sh - h;
                            break;
                        case 'southwest':
                            x -= sw - w;
                        break;
                        case 'west':
                            x -= sw - w;
                            break;
                        case 'northwest':
                            x -= sw - w;
                            y -= sh - h;
                        break;
                    }
                    w = sw;
                    h = sh;
                }
                
                if(this.preserveRatio){
                    switch(pos){
                        case 'southeast':
                        case 'east':
                            h = oh * (w/ow);
                            h = Math.min(Math.max(mh, h), mxh);
                            w = ow * (h/oh);
                           break;
                        case 'south':
                            w = ow * (h/oh);
                            w = Math.min(Math.max(mw, w), mxw);
                            h = oh * (w/ow);
                            break;
                        case 'northeast':
                            w = ow * (h/oh);
                            w = Math.min(Math.max(mw, w), mxw);
                            h = oh * (w/ow);
                            break;
                        case 'north':
                            var tw = w;
                            w = ow * (h/oh);
                            w = Math.min(Math.max(mw, w), mxw);
                            h = oh * (w/ow);
                            x += (tw - w) / 2;
                            break;
                        case 'southwest':
                            h = oh * (w/ow);
                            h = Math.min(Math.max(mh, h), mxh);
                            var tw = w;
                            w = ow * (h/oh);
                            x += tw - w;
                            break;
                        case 'west':
                            var th = h;
                            h = oh * (w/ow);
                            h = Math.min(Math.max(mh, h), mxh);
                            y += (th - h) / 2;
                            var tw = w;
                            w = ow * (h/oh);
                            x += tw - w;
                           break;
                        case 'northwest':
                            var tw = w;
                            var th = h;
                            h = oh * (w/ow);
                            h = Math.min(Math.max(mh, h), mxh);
                            w = ow * (h/oh);
                            y += th - h;
                             x += tw - w;
                           break;
                            
                    }
                }
                this.proxy.setBounds(x, y, w, h);
                if(this.dynamic){
                    this.resizeElement();
                }
            }catch(e){}
        }
    },
    
    handleOver : function(){
        if(this.enabled){
            this.el.addClass('yresizable-over');
        }
    },
    
    handleOut : function(){
        if(!this.resizing){
            this.el.removeClass('yresizable-over');
        }
    },
    
    
    getEl : function(){
        return this.el;
    },
    
    
    getResizeChild : function(){
        return this.resizeChild;
    }
});


YAHOO.ext.MyResizable.positions = {
    n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast' 
};


YAHOO.ext.MyResizable.Handle = function(rz, pos, disableTrackOver, transparent){
    if(!this.tpl){
        
        var tpl = YAHOO.ext.DomHelper.createTemplate(
            {tag: 'div', cls: 'yresizable-handle yresizable-handle-{0}', html: '&#160;'}
        );
        tpl.compile();
        YAHOO.ext.MyResizable.Handle.prototype.tpl = tpl;
    }
    this.position = pos;
    this.rz = rz;
    this.el = this.tpl.append(rz.el.dom, [this.position], true);
    this.el.unselectable();
    if(transparent){
        this.el.setOpacity(0);
    }
    this.el.mon('mousedown', this.onMouseDown, this, true);
    if(!disableTrackOver){
        this.el.mon('mouseover', this.onMouseOver, this, true);
        this.el.mon('mouseout', this.onMouseOut, this, true);
    }
};

YAHOO.ext.MyResizable.Handle.prototype = {
    afterResize : function(rz){
        
    },
    
    onMouseDown : function(e){
        this.rz.onMouseDown(this, e);
    },
    
    onMouseOver : function(e){
        this.rz.handleOver(this, e);
    },
    
    onMouseOut : function(e){
        this.rz.handleOut(this, e);
    }  
};

function nl2br(text){
    text = escape(text);	
    if (text.indexOf('%0D%0A') > -1) {
        re_nlchar = /%0D%0A/g ;	
    } else if (text.indexOf('%0A') > -1) {
        re_nlchar = /%0A/g ;
    } else if (text.indexOf('%0D') > -1) {
        re_nlchar = /%0D/g ;
    }
    return unescape( text.replace(re_nlchar,'<br />') );
}

function br2nl(text){
    text = text.replace(/<br \/>/g, '\n');
    text = text.replace(/<br\/>/g, '\n');
    text = text.replace(/<br>/g, '\n');
    return text;
}

function strip_nlbr(text){
    text = text.replace(/<br \/>/g, '');
    text = text.replace(/<br\/>/g, '');
    text = text.replace(/<br>/g, '');
    text = escape(text);
    re_nlchar = '';
    if (text.indexOf('%0D%0A') > -1) {
        re_nlchar = /%0D%0A/g ;	
    } else if (text.indexOf('%0A') > -1) {
        re_nlchar = /%0A/g ;
    } else if (text.indexOf('%0D') > -1) {
        re_nlchar = /%0D/g ;
    }
    if (re_nlchar != '') {
        text = text.replace(re_nlchar,'');
    }
    return unescape( text );
}

var PhotoNotes = {
    
    admin:           0,
    debug:           0,
    debugDiv:        'noteDebugger',
    containerDiv:    'noteContainer',
    image:           'noteImage',
    notelist:        'noteList',
    notecount:       'noteCount',
    notes:           [],
    lng_save:        'Opslaan',
    lng_cancel:      'Annuleer',
    lng_delete:      'Verwijder',
    lng_defNoteTxt:  'Note...',
    txtareaId:       'noteTxtArea',
    noteidId:        'noteId',
    saveNoteHandler: '',
    editNoteHandler: '',
    delNoteHandler:  '',
    
    init : function(){

        // container which holds all notes and the image
        var containerEl = getEl(this.containerDiv);
        // image were adding notes at
        var imageEl     = getEl(this.image);

        // set container to get image dimensions
        if (imageEl.dom.width) {
            widthImg  = imageEl.dom.width;
        } else {
            widthImg  = imageEl.getWidth();
        }
        if (imageEl.dom.height) {
            heightImg  = imageEl.dom.height;
        } else {
            heightImg  = imageEl.getHeight();
        }
        
        heightImg = imageEl.dom.height;
        containerEl.setWidth(imageEl.getWidth());
        containerEl.setHeight(heightImg);
        containerEl.setRelativePositioned(10);
        containerEl.setLeftTop(0, 0);

        imageEl.setAbsolutePositioned(9);
        
        // add button actions
        if (this.admin) {
            if (getEl('btnAddNote')) {
                getEl('btnAddNote').on('click', function(){
                    getEl('btnAddNote').swallowEvent('click');
                    PhotoNotes.newNote();
                });
            }
        }  
        if (getEl('btnShowAll')) {
            getEl('btnShowAll').on('click', function(){
                getEl('btnShowAll').swallowEvent('click');
                PhotoNotes.showAllNotes();
            });
        }
        if (getEl('btnHideAll')) {
            getEl('btnHideAll').on('click', function(){
                getEl('btnHideAll').swallowEvent('click');
                PhotoNotes.hideAllNotes();
            });
        }
    },
    appendToDebug : function(html){
        if (this.debug && getEl(this.debugDiv)) {
            debugEl = getEl(this.debugDiv);
            debugObj = { 
                    tag:  'p',
                    html : html
                };
            if (debugEl.dom.firstChild) {
                YAHOO.ext.DomHelper.insertBefore(debugEl.dom.firstChild, debugObj);
            } else {
                YAHOO.ext.DomHelper.append(debugEl.dom, debugObj);
            }
        }
    },
    newNote : function(){
        if ( getEl('noteEditContainer') ) {
            return 0;
        }

        if ( !getEl('noteNewContainer') ) {
            
            getEl('btnAddNote').swallowEvent('click');
            
            var containerEl = getEl(this.containerDiv);
    
            var noteContainerEl = YAHOO.ext.DomHelper.insertBefore(containerEl.dom.firstChild, { 
                    tag: "div",
                    id:  "noteNewContainer"
                }, true);
            noteContainerEl.setAbsolutePositioned(15);
            noteContainerEl.setLeftTop(0, 0);
            noteContainerEl.setStyle('overflow', 'visible');

            var noteEl = YAHOO.ext.DomHelper.append(noteContainerEl.dom, { 
                    tag: "div",
                    id:  "noteNew"
                }, true);
            noteEl.setRelativePositioned(16);
            noteEl.setLeftTop(0, 0);
                
            var noteResizer = new YAHOO.ext.MyResizable('noteNew', {
                wrap:true,
                pinned:true,
                width: 50,
                height: 50,
                minWidth: 30,
                minHeight: 30,
                handles: 'all',
                draggable:true,
                dynamic:true
            });
            
            // set max drag movement
            var maxLeft  = 5;
            var maxUp    = 5;
            maxRight = containerEl.getWidth() - maxLeft - noteEl.getWidth();
            maxDown  = containerEl.getHeight() - maxUp - noteEl.getHeight();
            noteResizer.dd.setXConstraint(maxLeft, maxRight);
            noteResizer.dd.setYConstraint(maxUp, maxDown);
            
            // set max resizing
            noteResizer.minX      = containerEl.getX() - 5;
            noteResizer.minY      = containerEl.getY() - 5;
            noteResizer.maxX      = containerEl.getX() + containerEl.getWidth()  + 5;
            noteResizer.maxY      = containerEl.getY() + containerEl.getHeight() + 5;
            this.appendToDebug('<b>init drag limits<\u002fb><br />maxLeft: '+maxLeft+'<br />maxRight: '+maxRight+'<br />maxUp: '+maxUp+'<br />maxDown: '+maxDown+'<br /><b>init resize limits<\u002fb><br />minX: '+noteResizer.minX+'<br />minY: '+noteResizer.minY+'<br />maxX: '+noteResizer.maxX+'<br />maxY: '+noteResizer.maxY+'<br />maxWidth: '+noteResizer.maxWidth+'<br />maxHeight: '+noteResizer.maxHeight+'<hr />');
            
            var noteResizerEl = noteResizer.getEl();
            noteContainerEl.dom.insertBefore(noteResizerEl.dom, noteContainerEl.dom.firstChild);
            
            resizeEl = getEl('noteNew-rzwrap');
            resizeEl.setStyle('z-index',  '16');
            
            var formEl = YAHOO.ext.DomHelper.append(noteContainerEl.dom, { 
                    tag:  'div',
                    id:   'noteNew-formContainer'
                }, true);
            formEl.setRelativePositioned(16);
            formEl.setStyle('overflow', 'visible');
            formEl.setStyle('padding-left', '5px');
            formEl.setStyle('padding-top', '5px');
            
            this.appendNewNoteFormTo(formEl.dom);
            
            /* animate showing of elements */
            resizeEl.show(true);
            formEl.show(true);

            /* event actions */
            // during resize
            noteResizer.on('beforeresize', function() { 
                formEl.hide();
            });
            noteResizer.on('resize', function() { 
                // set max drag movement
                maxRight = containerEl.getWidth() - maxLeft - noteEl.getWidth();
                maxDown  = containerEl.getHeight() - maxUp - noteEl.getHeight();
                noteResizer.dd.setXConstraint(maxLeft, maxRight);
                noteResizer.dd.setYConstraint(maxUp, maxDown);
                
                PhotoNotes.appendToDebug('<b>reset drag limits<\u002fb><br />maxLeft: '+maxLeft+'<br />maxRight: '+maxRight+'<br />maxUp: '+maxUp+'<br />maxDown: '+maxDown+'<hr />');
    
                formEl.setX(resizeEl.getX());
                formEl.setY(resizeEl.getY()+resizeEl.getHeight());
                formEl.show();
            });

            // during drag
            noteResizer.dd.startDrag = function(e){
                formEl.hide();
            };
            // after drag
            noteResizer.dd.endDrag = function(e) {
                formEl.setX(resizeEl.getX());
                formEl.setY(resizeEl.getY()+resizeEl.getHeight());
                formEl.show();
            };

            // button events
            if (getEl('btnCancelNote')) {
                getEl('btnCancelNote').on('click', function(){
                    getEl('btnCancelNote').swallowEvent('click');
                    PhotoNotes.cancelNote('noteNew');
                });
            }
            if (getEl('btnSaveNote')) {
                getEl('btnSaveNote').on('click', function(){
                    PhotoNotes.saveNote('noteNew');
                });
            }
        } else {
            getEl('noteNew-rzwrap').show(true);
            getEl('noteNew-formContainer').show(true);
        }
    },
    editNote : function(id){
        if ( getEl('noteNewContainer') ) {
            return 0;
        }

        if ( !getEl('noteEditContainer') ) {
            
            var editEl = getEl(id);
            editEl.swallowEvent('click');
            
            var containerEl = getEl(this.containerDiv);
    
            var noteContainerEl = YAHOO.ext.DomHelper.insertBefore(containerEl.dom.firstChild, { 
                    tag: "div",
                    id:  "noteEditContainer"
                }, true);
            noteContainerEl.setAbsolutePositioned(15);
            noteContainerEl.setLeftTop(0, 0);
            noteContainerEl.setStyle('overflow', 'visible');

            var noteEl = YAHOO.ext.DomHelper.append(noteContainerEl.dom, { 
                    tag: "div",
                    id:  'noteEdit'
                }, true);
            noteEl.setRelativePositioned(16);
            noteEl.setLeftTop((editEl.getX()-containerEl.getX()-5), (editEl.getY()-containerEl.getY()-5));
                
            var noteResizer = new YAHOO.ext.MyResizable('noteEdit', {
                wrap:      true,
                pinned:    true,
                width:     editEl.getWidth() + (2*5),
                height:    editEl.getHeight()+ (2*5),
                minWidth:  20,
                minHeight: 20,
                handles:   'all',
                draggable: true,
                dynamic:   true
            });
            
            // set max drag movement
            var maxLeft  = (noteEl.getX() - containerEl.getX()) - 1;
            var maxUp    = (noteEl.getY() - containerEl.getY()) - 1;
            maxRight = containerEl.getWidth() - maxLeft - noteEl.getWidth() - 2;
            maxDown  = containerEl.getHeight() - maxUp - noteEl.getHeight() - 2;
            noteResizer.dd.setXConstraint(maxLeft, maxRight);
            noteResizer.dd.setYConstraint(maxUp, maxDown);
            
            // set max resizing
            noteResizer.minX      = containerEl.getX() - 5;
            noteResizer.minY      = containerEl.getY() - 5;
            noteResizer.maxX      = containerEl.getX() + containerEl.getWidth()  + 5;
            noteResizer.maxY      = containerEl.getY() + containerEl.getHeight() + 5;
            this.appendToDebug('<b>init drag limits<\u002fb><br />maxLeft: '+maxLeft+'<br />maxRight: '+maxRight+'<br />maxUp: '+maxUp+'<br />maxDown: '+maxDown+'<br /><b>init resize limits<\u002fb><br />minX: '+noteResizer.minX+'<br />minY: '+noteResizer.minY+'<br />maxX: '+noteResizer.maxX+'<br />maxY: '+noteResizer.maxY+'<br />maxWidth: '+noteResizer.maxWidth+'<br />maxHeight: '+noteResizer.maxHeight+'<hr />');
            
            var noteResizerEl = noteResizer.getEl();
            noteContainerEl.dom.insertBefore(noteResizerEl.dom, noteContainerEl.dom.firstChild);
            
            resizeEl = getEl('noteEdit-rzwrap');
            resizeEl.setStyle('z-index',  '16');
            
            var formEl = YAHOO.ext.DomHelper.append(noteContainerEl.dom, { 
                    tag:  'div',
                    id:   'noteEdit-formContainer'
                }, true);
            formEl.setRelativePositioned(16);
            formEl.setX(resizeEl.getX());
            formEl.setY(resizeEl.getY()+resizeEl.getHeight());
            formEl.setStyle('overflow', 'visible');
            formEl.setStyle('padding-left', '5px');
            formEl.setStyle('padding-top', '5px');
            
            this.appendEditNoteFormTo(formEl.dom, id);
            
            /* animate showing of elements */
            resizeEl.show(true);
            formEl.show(true);

            /* event actions */
            // during resize
            noteResizer.on('beforeresize', function() { 
                formEl.hide();
            });
            // after resize
            noteResizer.on('resize', function() { 
                // set max drag movement
                maxRight = containerEl.getWidth() - maxLeft - noteEl.getWidth() - 2;
                maxDown  = containerEl.getHeight() - maxUp - noteEl.getHeight() - 2;
                noteResizer.dd.setXConstraint(maxLeft, maxRight);
                noteResizer.dd.setYConstraint(maxUp, maxDown);
                
                PhotoNotes.appendToDebug('<b>reset drag limits<\u002fb><br />maxLeft: '+maxLeft+'<br />maxRight: '+maxRight+'<br />maxUp: '+maxUp+'<br />maxDown: '+maxDown+'<hr />');
    
                formEl.setX(resizeEl.getX());
                formEl.setY(resizeEl.getY()+resizeEl.getHeight());
                formEl.show();
            });

            // during drag
            noteResizer.dd.startDrag = function(e){
                formEl.hide();
            };
            // after drag
            noteResizer.dd.endDrag = function(e) {
                formEl.setX(resizeEl.getX());
                formEl.setY(resizeEl.getY()+resizeEl.getHeight());
                formEl.show();
            };

            // button events
            if (getEl('btnCancelNote')) {
                getEl('btnCancelNote').on('click', function(){
                    PhotoNotes.cancelNote(id);
                });
            }
            if (getEl('btnSaveNote')) {
                getEl('btnSaveNote').on('click', function(){
                    PhotoNotes.saveNote('noteEdit');
                });
            }
            if (getEl('btnDeleteNote')) {
                getEl('btnDeleteNote').on('click', function(){
                    PhotoNotes.deleteNote();
                });
            }
            editEl.hide();
        } else {
            getEl('noteEdit-rzwrap').show(true);
            getEl('noteEdit-formContainer').show(true);
        }
    },
    showNoteCount : function(){
        if (getEl(this.notecount)) {
            getEl(this.notecount).dom.innerHTML = this.notes.length;
        }
    },
    appendNewNoteFormTo : function(formEl){
        textareaObj = { 
                tag:   'textarea',
                id:    this.txtareaId,
                name:  this.txtareaId,
                html : this.lng_defNoteTxt
            };
        saveBtnObj = { 
                tag:   'button',
                id:    'btnSaveNote',
                html : this.lng_save
            };
        cancelBtnObj = { 
                tag: 'button',
                id:  'btnCancelNote',
                html : this.lng_cancel
            };
        YAHOO.ext.DomHelper.append(formEl, textareaObj, true);
        YAHOO.ext.DomHelper.append(formEl, cancelBtnObj, true);
        YAHOO.ext.DomHelper.append(formEl, saveBtnObj, true);
    },
    appendEditNoteFormTo : function(formEl, note) {
        i = 0;
        found = 0;
        while ((i < this.notes.length) && (!found)) {
            if (this.notes[i].id == note) {
                found = 1;
            } else {
                i = i + 1;
            }
        }
        textareaObj = { 
                tag:   'textarea',
                id:    this.txtareaId,
                name:  this.txtareaId,
                html : br2nl(this.notes[i].text)
            };
        noteidObj = { 
                tag:   'input',
                type:  'hidden',
                id:    this.noteidId,
                name:  this.noteidId,
                value: this.notes[i].id
            };
        saveBtnObj = { 
                tag:   'button',
                id:    'btnSaveNote',
                html :  this.lng_save
            };
        cancelBtnObj = { 
                tag:   'button',
                id:    'btnCancelNote',
                html : this.lng_cancel
            };
        deleteBtnObj = { 
                tag:   'button',
                id:    'btnDeleteNote',
                html : this.lng_delete
            };
        YAHOO.ext.DomHelper.append(formEl, textareaObj);
        YAHOO.ext.DomHelper.append(formEl, noteidObj);
        YAHOO.ext.DomHelper.append(formEl, cancelBtnObj);
        YAHOO.ext.DomHelper.append(formEl, saveBtnObj);
        YAHOO.ext.DomHelper.append(formEl, deleteBtnObj);
    },
    addNote : function(id, left, top, width, height, text){
        if ((id == '') || (getEl('note'+id))) {
            i = 1;
            while ( getEl('note'+i) ) {
                i = i + 1;
            }
            id = 'note'+i;
        } else {
            id = 'note'+id;
        }
        
        var thisNote = {'text': text, 'id': id};
        
        this.notes.push( thisNote );
        
        var containerEl = getEl(this.containerDiv);

        var noteEl = YAHOO.ext.DomHelper.insertBefore(containerEl.dom.firstChild, { 
                tag:     "div",
                id:      id, 
                cls:     "photoNote noteShown",
                title :  strip_nlbr(text),
                onclick: "void(0);"
            }, true);
        noteEl.setAbsolutePositioned(11);
        noteEl.setLeft(left);
        noteEl.setTop(top);
        noteEl.setWidth(width);
        noteEl.setHeight(height);
        noteEl.on('mouseover', function(){
                PhotoNotes.highlightNote(id);
            });
        noteEl.on('mouseout', function(){
                PhotoNotes.unHighlightNote(id);
            });
        if (this.admin) {
            noteEl.on('click', function(){
                    PhotoNotes.editNote(id);
                });
        }
        if ((this.noteList != '') && (getEl(this.notelist))) {
            this.appendToNoteList(getEl(this.notelist).dom, thisNote);
        }
        this.showNoteCount();

        return id;
    },
    updateNote : function(id, left, top, width, height, text) {
        i = 0;
        found = 0;
        while ((i < this.notes.length) && (!found)) {
            if (this.notes[i].id == id) {
                found = 1;
            } else {
                i = i + 1;
            }
        }
        if (found) {
            this.notes[i] = {'text': text, 'id': id};
            noteEl = getEl(id);
            noteEl.show();
            noteEl.dom.title = strip_nlbr(text);
            noteEl.setLeft(left);
            noteEl.setTop(top);
            noteEl.setWidth(width);
            noteEl.setHeight(height);
            
            if ((this.noteList != '') && (getEl(this.notelist))) {
                if (getEl('link_' + id)) {
                    getEl('link_' + id).dom.innerHTML = nl2br(text);
                }
            }
        }
    },
    appendToNoteList : function(notelist, thisNote){
        if ( notelist ) {
            linkEl = YAHOO.ext.DomHelper.append(notelist, { 
                tag:         "p",
                id:          "link_" + thisNote.id,
                html:        thisNote.text,
                onclick:     "PhotoNotes.showNote('"+thisNote.id+"');" ,
                onmouseover: "PhotoNotes.highlightNote('"+thisNote.id+"');",
                onmouseout:  "PhotoNotes.unHighlightNote('"+thisNote.id+"');"
            }, true);
            linkEl.addClass('viewNoteLink');
        }
        
    },
    highlightNote : function(id){
        var noteEl = getEl(id);
        noteEl.addClass('noteHighlighted');
    },
    unHighlightNote : function(id){
        var noteEl = getEl(id);
        noteEl.removeClass('noteHighlighted');
    },
    showNote : function(id){
        linkEl = getEl('link_'+id);
        if (linkEl) {
            linkEl.addClass('noteLinkHighlighted');
            linkEl.dom.onclick = function(){PhotoNotes.hideNote(id);};
        }

        noteEl = getEl(id);
        noteEl.show(true);
        noteEl.removeClass('noteHidden');
        noteEl.addClass('noteShown');
    },
    hideNote : function(id){
        linkEl = getEl('link_'+id);
        if (linkEl) {
            linkEl.removeClass('noteLinkHighlighted');
            linkEl.dom.onclick = function(){PhotoNotes.showNote(id);};
        }

        noteEl = getEl(id);
//        noteEl.hide(true);
        noteEl.removeClass('noteShown');
        noteEl.addClass('noteHidden');
    },
    hideAllNotes : function(){
        var containerEl = getEl(this.containerDiv);
        noteArr = containerEl.getChildrenByClassName('photoNote');
        for(var i = 0; i < noteArr.length; i++){
            this.hideNote(noteArr[i].id);
        }
    },
    showAllNotes : function(){
        var containerEl = getEl(this.containerDiv);
        noteArr = containerEl.getChildrenByClassName('photoNote');
        for(var i = 0; i < noteArr.length; i++){
            this.showNote(noteArr[i].id);
        }
    },
    cancelNote : function(which){
        if (which != 'noteNew') {
            if (getEl(which)) {
                getEl(which).show();
            }
            which = 'noteEdit';
        }
        if ( getEl(which+'Container') ) {
            getEl(which+'Container').remove();
        }
        if ( getEl(which+'-rzwrap-rzproxy') ) {
            getEl(which+'-rzwrap-rzproxy').remove();
        }
        arr = YAHOO.util.Dom.getElementsByClassName('yresizable-overlay', 'div', 'body');
        for (var i = 0; i < arr.length; i++) {  
            document.body.removeChild(arr[i]);            
        }
    },
    deleteNote : function(){
        if (this.delNoteHandler == '') {
            alert('no delNoteHandler function defined');
        } else {
            noteidEl = document.getElementById(this.noteidId);
            which    = noteidEl.value;
            note = getEl(which);
            if (!noteidEl) {
                alert('Please specify what note to delete');
            } else if (!note) {
                alert('Note not found');
            } else {
                toEval = this.delNoteHandler+'(\''+which+'\');';
                result = eval(toEval);
                if (result) {
                    i     = 0;
                    found = 0;
                    while ((i < this.notes.length) && (!found)) {
                        if (this.notes[i].id == which) {
                            found = 1;
                        } else {
                            i = i + 1;
                        }
                    }
                    if (found) {
                        this.notes.splice(i, 1);
                    }
                    getEl(which).remove();
                    getEl('link_'+which).remove();
                    this.showNoteCount();
                    this.cancelNote(which);
                }
            }
        }
    },
    saveNote : function(which){
        if (this.saveNoteHandler == '') {
            alert('no saveNoteHandler function defined');
        } else {
            res = getEl('btnSaveNote').swallowEvent('click');

            note = getEl(which);
            if (!note) {
                alert('Please specify what kind of note to save (Edit/New)');
            } else {
                containerEl = getEl(this.containerDiv);
                noteLeft    = note.getX() - containerEl.getX();
                noteTop     = note.getY() - containerEl.getY();
                noteWidth   = note.getWidth();
                noteHeight  = note.getHeight();
                noteText    = getEl(this.txtareaId).dom.value;
                
                var noteidEl = document.getElementById(this.noteidId);

                if ( noteidEl ) {
                    // editing note
                    var noteId = noteidEl.value;
                    toEval = this.editNoteHandler+'(\''+noteId+'\','+noteLeft+','+noteTop+','+noteWidth+','+noteHeight+');';
                    result = eval(toEval);
                    if (result) {
                        this.updateNote(noteId, noteLeft, noteTop, noteWidth, noteHeight, noteText);
                        this.showNote(noteId);
                        this.cancelNote(which);
                    }
                } else {
                    // new note
                    toEval = this.saveNoteHandler+'('+noteLeft+','+noteTop+','+noteWidth+','+noteHeight+');';
                    result = eval(toEval);
                    if (result) {
                        noteAdded = this.addNote(result, noteLeft, noteTop, noteWidth, noteHeight, noteText);
                        this.showNote(noteAdded);
                        this.cancelNote(which);
                    }
                }
            }
        }
    }
};
