// PATM: 25 July 2011 - 
// moved amplafi.html to separate file. I would think that most of the functions would be handled by jquery library.
if (typeof (amplafi) == "undefined") {
    amplafi = {}
}
if (typeof (amplafi.html) == "undefined") {
    amplafi.html = {
        ie : /MSIE/i.test(navigator.userAgent),

        getElementsByTagNames : function(/* String */tagList, /* String */className, /* DOMNode */parent, fn) {
            // Summary: Finds tags.
            // tagList: Comma separated list of tag names to look for.
            // className: Class that the found nodes should contain.
            parent = parent || document;
            var tagNames = tagList.split(',');
            var resultArray = [];
            for ( var i = 0; i < tagNames.length; i++) {
                var tags = parent.getElementsByTagName(tagNames[i]);
                for ( var j = 0; j < tags.length; j++) {
                    var thisClass = tags[j].className;
                    if (!className || (thisClass && thisClass.indexOf(className) >= 0))
                        resultArray.push(tags[j]);
                }
            }
            if (fn && resultArray.length > 0) {
                return fn(resultArray[0]);
            }
            return resultArray;
        },

        getEventPosition : function(/* Event */e) {
            if (!e) {
                return {
                    x : 10,
                    y : 10
                };
            }
            if (e.pageX || e.pageY) {
                return {
                    x : e.pageX,
                    y : e.pageY
                };
            } else if (e.clientX || e.clientY) {
                return {
                    x : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft,
                    y : e.clientY + document.body.scrollTop + document.documentElement.scrollTop
                };
            }
        },
        /**
         * get element hidden by an overlaying element http://www.vinylfox.com/forwarding-mouse-events-through-layers/
         */
        getUnderlyingElement : function(eventObject, /* current */overlaidElement) {
            // This is the trick! Hide the highlighter to see what the original mouse
            // event would affect.
            var currentDisplay = overlaidElement.style.display;
            var target;
            overlaidElement.style.display = 'none';
            if (document.elementFromPoint) {
                target = document.elementFromPoint(eventObject.clientX, eventObject.clientY);
            } else {
                if (amplafi.html.ie) {
                    target = eventObject.srcElement;
                } else {
                    target = eventObject.explicitOriginalTarget || eventObject.target;
                }
            }
            // only safari seems to give inaccurate position (and only when page is scrolled down)
            overlaidElement.style.display = currentDisplay;
            return target;
        },
        getPosition : function(/* DOMNode */node) {
            var parent = node, offsetLeft = document.body.offsetLeft, offsetTop = document.body.offsetTop, view = amplafi.html
                    .getView(node);
            while (parent && parent != document.body && parent != document.firstChild) {
                offsetLeft += parseInt(parent.offsetLeft);
                offsetTop += parseInt(parent.offsetTop);
                parent = parent.offsetParent;
            };
            return {
                "bottom" : view["bottom"],
                "clientLeft" : node.clientLeft,
                "clientTop" : node.clientTop,
                "left" : view["left"],
                "marginTop" : view["marginTop"],
                "marginLeft" : view["marginLeft"],
                "offsetLeft" : offsetLeft,
                "offsetTop" : offsetTop,
                "position" : view["position"],
                "right" : view["right"],
                "top" : view["top"],
                "zIndex" : view["zIndex"]
            };
        },
        getView : function(/* DOMNode */node, prop) {
            var view = document.defaultView ? document.defaultView.getComputedStyle(node, null) : node.currentStyle;
            prop = prop == "float" ? amplafi.html.ie ? "styleFloat" : "cssFloat" : prop;
            if (prop == "opacity" && amplafi.html.ie) {
                return amplafi.html.getOpacity(node, view);
            } else {
                return typeof prop == "string" ? view[prop] : view;
            }
        },
        getOpacity : function(_styleObject) {
            var styleObject = _styleObject;
            if (!amplafi.html.ie) {
                return styleObject["opacity"];
            } else {
                var alpha = styleObject["filter"].match(/opacity\=(\d+)/i);
                return alpha ? alpha[1] / 100 : 1;
            }
        },
        addStyle : function(/* DOMNode */node, _style) {
            for ( var key in _style) {
                key = key == "float" ? amplafi.html.ie ? "styleFloat" : "cssFloat" : key;
                if (key == "opacity" && amplafi.html.ie) {
                    amplafi.html.setOpacity(node, _style[key]);
                    continue;
                }
                try {
                    node.style[key] = _style[key];
                } catch (e) {
                }
            }
        },
        setOpacity : function(/* DOMNode */node, _value) {
            if (!amplafi.html.ie) {
                return amplafi.html.addStyle(node, {
                    "opacity" : _value
                });
            } else {
                _value *= 100;
                amplafi.html.addStyle(node, {
                    "filter" : "alpha(opacity=" + _value + ")"
                });
            }
        },
        createNode : function(/* String */tagName, /* DOMNode */refNode, attrs, /* String */refType) {
            // Summary: Creates a new dom node
            // refType: By default, the new node is appended as a child of reference node.
            // Use "before" or "after" for the new node to become sibling to refNode.
            var d = refNode.ownerDocument || document;
            var node = d.createElement(tagName);
            if (attrs && attrs['type']) {
                node.setAttribute('type', attrs['type']);
                delete attrs['type'];
            }
            if (refType == "after")
                refNode.parentNode.insertBefore(node, refNode.nextSibling || null);
            else if (refType == "before")
                refNode.parentNode.insertBefore(node, refNode);
            else
                refNode.appendChild(node);

            if (attrs)
                for ( var i in attrs) {
                    if (i == 'options') {
                        for ( var j in attrs[i]) {
                            node.options[node.options.length] = new Option(attrs[i][j], j);
                        }
                    } else if (i == 'className' || i == 'innerHTML' || i == 'onclick') {
                        node[i] = attrs[i];
                    } else if (i == 'style') {
                        amplafi.html.addStyle(node, attrs[i]);
                    } else {
                        node.setAttribute(i, attrs[i]);
                    }
                }
            return node;
        },
        removeNode : function(/* DOMNode */node) {
            if (node)
                node.parentNode.removeChild(node);
        },
        serialize : function(obj) {
            var res = [];
            for ( var k in obj) {
                var useKey;
                if (typeof (k) == "number" || typeof (k) == "string") {
                    useKey = "\"" + k + "\"";
                } else {
                    continue;
                }
                var val = obj[k];
                if (typeof (val) == "object") {
                    val = this.serialize(val);
                } else {
                    val = "\"" + val + "\"";
                }
                res.push(useKey + ":" + val);
            }
            return "{" + res.join(",") + "}";
        },
        addScript : function(src) {
            var e = document.createElement("script");
            e.type = "text/javascript";
            e.src = src;
            document.getElementsByTagName("head")[0].appendChild(e);
        },
        reloadScript : function(name) {
            // Summary: Reloads the first matching script - useful in order to not having to
            // reload the whole page when developing.
            var scripts = document.getElementsByTagName('script');
            for ( var i = 0; i < scripts.length; i++) {
                var node = scripts[i];
                if (node.src.indexOf(name) >= 0) {
                    this.addScript(node.src);
                    return;
                }
            }
        },
        makeFloating : function(/* DOMNode */node, /* DOMNode */handle) {
            // Summary: Floats a node.
            // NOTE: js/amplafi/utils.js contains a copy of this.
            if (!handle)
                handle = node;
            var frameWidth = parseInt(amplafi.html.getView(node, 'width'));
            // allow 7/8 of the width to be dragged out
            var frameWidthOut = frameWidth * 7 / 8;

            var MouseDown = function(e) {
                var ah = amplafi.html;
                if (!ah._FloatNode)
                    return;
                if (ah._over) {
                    var frames = ah._FloatNode.getElementsByTagName('iframe');
                    for ( var i = 0; i < frames.length; i++) {
                        ah.addStyle(frames[i], {
                            visibility : 'hidden'
                        });
                    }
                    if (!ah.ie) {
                        ah._objDiv = ah._FloatNode;
                        ah._X = e.layerX;
                        ah._Y = e.layerY;
                        return false;
                    } else {
                        ah._objDiv = ah._FloatNode.style;
                        ah._X = event.offsetX;
                        ah._Y = event.offsetY;
                    }
                }
            };
            var MouseMove = function(e) {
                var ah = amplafi.html;
                if (ah._objDiv) {
                    if (!ah.ie) {
                        var newLeft = e.pageX - ah._X, newTop = e.pageY - ah._Y;
                        if (newTop < 22)
                            newTop = 22;
                        if (newLeft < -frameWidthOut)
                            newLeft = -frameWidthOut;
                        ah._objDiv.style.left = newLeft + 'px';
                        ah._objDiv.style.top = newTop + 'px';
                        return false;
                    } else {
                        var newLeft = event.clientX - ah._X + document.body.scrollLeft, newTop = event.clientY - ah._Y
                                + document.body.scrollTop;
                        if (newTop < 22)
                            newTop = 22;
                        if (newLeft < -frameWidthOut)
                            newLeft = -frameWidthOut;
                        ah._objDiv.pixelLeft = newLeft;
                        ah._objDiv.pixelTop = newTop;
                        return false;
                    }
                }
            };
            var MouseUp = function() {
                amplafi.html._objDiv = null;
                if (!amplafi.html._FloatNode)
                    return;
                var frames = amplafi.html._FloatNode.getElementsByTagName('iframe');
                for ( var i = 0; i < frames.length; i++) {
                    amplafi.html.addStyle(frames[i], {
                        visibility : ''
                    });
                }
            };

            amplafi.html._FloatNode = node;

            if (!amplafi.html.ie) {
                document.captureEvents(Event.MOUSEDOWN | Event.MOUSEMOVE | Event.MOUSEUP);
            }

            document.onmousedown = MouseDown;
            document.onmousemove = MouseMove;
            document.onmouseup = MouseUp;

            handle.onmouseover = function() {
                amplafi.html._over = true;
            };
            handle.onmouseout = function() {
                amplafi.html._over = false;
            };
        },

        closeFrame : function(success) {
            var ah = amplafi.html;
            var ai = amplafi.insertion;
            ai.popupShown = false;
            if (ah._FloatNode) {
                ah.removeNode(ah._FloatNode);
            }
            if (ai.inProxy && success) {
                var popup = ai.showPopup();
                popup.className = popup.className + " amp_info";
                ah.createNode("div", popup, {
                    innerHTML : ai.messages.mepCreationSuccessful
                });
                ah.addStyle(popup, {
                    width : '200px',
                    left : (document.body.clientWidth / 2 - 100) + 'px'
                });
                var ok = ah.createNode('input', popup, {
                    type : 'button',
                    value : 'OK'
                });
                ok.onclick = function() {
                    // TODO: even though it reloads only on successful flow finish,
                    // consider loading new mep with async request.
                    window.location.reload();
                };
            }
        },

        getDocumentOrderSorter : function() {
            // Summary: Function that can sort nodes according to where their position within the document.
            var sortOrder;
            if (document.documentElement.compareDocumentPosition) {
                sortOrder = function(a, b) {
                    return a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
                };
            } else if (document.documentElement.sourceIndex === 0) {
                sortOrder = function(a, b) {
                    return a.sourceIndex - b.sourceIndex;
                };
            } else {
                sortOrder = function(a, b) {
                    if (a.id && b.id)
                        return a.id > b.id;
                    else
                        return 0;
                };
            }
            return sortOrder;
        },

        rebuildURL : function(path, stripPrefix) {
            // Summary: Makes a url absolute.
            if (stripPrefix && path.indexOf(stripPrefix) == 0) {
                path = path.substring(stripPrefix.length);
            }
            var stripToLastSlash = function(url) {
                var pos = url.lastIndexOf('/');
                return url.substring(0, pos + 1);
            };
            if (path.match(/^https?:/)) {
                return path;
            }
            if (path.indexOf('/') == 0) {
                var l = window.location;
                return l.protocol + '//' + l.host + path;
            }

            var rootPath = stripToLastSlash(window.location.href);

            while (true) {
                if (path.indexOf('../') == 0) {
                    rootPath = stripToLastSlash(rootPath.substring(0, rootPath.length - 1));
                    path = path.substring(3);
                    continue;
                }
                if (path.indexOf('./') == 0) {
                    path = path.substring(2);
                    continue;
                }
                return rootPath + path;
            }
        },

        doGetUrl : function(url, params) {
            // Summary: Builds a url to be used for a get request.
            url = url + '?';
            for ( var key in params) {
                url = url + key + '=' + encodeURIComponent(params[key]) + "&";
            }
            return url;
        },

        doPostHtml : function(url, params) {
            // Summary: Builds html code to be used for a post request.
            var html = [];
            html.push('<form method="post" action="');
            html.push(url);
            html.push('">');
            for ( var key in params) {
                html.push('<input type="hidden" name="');
                html.push(key);
                html.push('" value="');
                html.push(("" + params[key]).replace(/"/g, '&quot;'));
                html.push('">');
            }
            html.push('</form>');
            return html.join('');
        },
        // placeholder for now.
        debug : function(params) {

        },

    };
}

// remaining of file borrowed from dojo  ( to make easier porting)
if (typeof (amplafi.string) == "undefined") {
    // copied from dojo....
    amplafi.string = {
        endsWith: function(str, end, ignoreCase) {
            if (ignoreCase) {
                str = str.toLowerCase();
                end = end.toLowerCase();
            }
            if ((str.length - end.length) < 0) {
                return false;
            } else {
                return str.lastIndexOf(end) == str.length - end.length;
            }
        },
        trim: function(str, wh) {
            if (!str.replace) {
                return str;
            }
            if (!str.length) {
                return str;
            }
            var re = (wh > 0) ? (/^\s+/) : (wh < 0) ? (/\s+$/) : (/^\s+|\s+$/g);
            return str.replace(re, "");
        },
        isBlank: function(str){
            if(!amplafi.lang.isString(str)) {
                return true;
            } else {
                return (amplafi.string.trim(str).length == 0);
            }
        }
    };
}
if (typeof (amplafi.lang) == "undefined") {
    amplafi.lang = {
        find: function(array, value, identity, findLast) {
            var isString = dojo.lang.isString(array);
            if (isString) {
                array = array.split("");
            }
            if (findLast) {
                var step = -1;
                var i = array.length - 1;
                var end = -1;
            } else {
                var step = 1;
                var i = 0;
                var end = array.length;
            }
            if (identity) {
                while (i != end) {
                    if (array[i] === value) {
                        return i;
                    }
                    i += step;
                }
            } else {
                while (i != end) {
                    if (array[i] == value) {
                        return i;
                    }
                    i += step;
                }
            }
            return -1;
        },
        isString: function( it){
            return (typeof it == "string" || it instanceof String);
        },
        remove: function(array, elem){
            var match = -1;
        
            while( (match = this.indexOf(elem)) > -1 ) {
                array.splice(match, 1);
            }
            return array;
        }
    };
}
