// start tinyMCE forward compatability stuff

if(typeof(tinyMCE) == 'undefined') {
  var tinyMCE = {};
//  TinyMCE = tinyMCE;
}

tinyMCE.hasCSSClass = function(n, c) {
	return new RegExp('\\b' + c + '\\b', 'g').test(n.className);
};

tinyMCE.getParentNode = function(n, f, r) {
	while (n) {
		if (n == r)
			return null;

		if (f(n))
			return n;

		n = n.parentNode;
	}

	return null;
};

tinyMCE.getParentElement = function(n, na, f, r) {
  if(!r) {
    r = editDoc;
  }
  var re = na ? new RegExp('^(' + na.toUpperCase().replace(/,/g, '|') + ')$') : 0, v;

	return tinyMCE.getParentNode(n, function(n) {
		return ((n.nodeType == 1 && !re) || (re && re.test(n.nodeName))) && (!f || f(n));
	}, r);
};

// end tinyMCE stuff


var isIE = false;
var isFF = false;
if(window.ActiveXObject) {
  isIE = true;
} else {
  isFF = true;
}

function getAbsPosition(el, doc) {
    if (el.getBoundingClientRect) { // IE
      var r = el.getBoundingClientRect();
      return {
        absLeft: r.left + (doc.body.scrollLeft || doc.documentElement.scrollLeft || 0),
        absTop: r.top + (doc.body.scrollTop || doc.documentElement.scrollTop || 0),
        width: r.right - r.left,
        height: r.bottom - r.top
      };
    }
    else
      if (doc.getBoxObjectFor) { // FF
        var r = doc.getBoxObjectFor(el);
        return {
          absLeft: r.x,
          absTop: r.y,
          width: r.width,
          height: r.height
        };
      }
}
function getImagePosition(el) {
  var doc = editFrame.contentDocument ? editFrame.contentDocument : editFrame.contentWindow.document;
  var elPos = getAbsPosition(el, doc);
  var framePos = getAbsPosition(editFrame, document);
  if(typeof(wemOffset) == 'object') {
    framePos.absLeft = framePos.absLeft - wemOffset.x;
    framePos.absTop = framePos.absTop - wemOffset.y;
  }
  return {
    left: elPos.absLeft + framePos.absLeft - doc.body.scrollLeft,
    top: elPos.absTop + framePos.absTop - doc.body.scrollTop,
    width: elPos.width,
    height: elPos.height
  };
}
function isWidget(el) {
  return (el != null) && (el.tagName == 'IMG') && (el.className == 'fw-widget');
}

function getSelection() {
  var sel = null;
  if(isIE) {
    sel = editFrame.contentWindow.document.selection;
  } else if(isFF) {
    sel = editFrame.contentWindow.getSelection();
  }
  return sel;
}
function getRange(sel) {
  var rng = null;
  if(isIE) {
    rng = sel.createRange();
  } else if(isFF) {
    rng = sel.getRangeAt(0);
  }
  return rng;
}

function getSelectedWidget(el) {
  var elm = null;
  var sel, rng;
  if(isIE) {
    sel = editFrame.contentWindow.document.selection;
    rng = sel.createRange();
    elm = rng.item ? rng.item(0) : rng.parentElement();
    if(!isWidget(elm)) return null;
    return elm;
  } else if(isFF) {
    sel = editFrame.contentWindow.getSelection();
    rng = sel.getRangeAt(0);

    if (!sel || !rng)
      return null;

/*
    //line 76-93 from editor_template_src.js
    var sc = tinyMCE.getParentElement(rng.startContainer, 'SPAN', function (n) {return tinyMCE.hasCSSClass(n, 'fw-widget');});
    var ec = tinyMCE.getParentElement(rng.endContainer, 'SPAN', function (n) {return tinyMCE.hasCSSClass(n, 'fw-widget');});

    if (sc)
      rng.setStartBefore(sc);

    if (ec)
      rng.setEndAfter(ec);

    if (sc || ec) {
      sng.removeAllRanges();
      sng.addRange(r);
    }
*/

    if (!rng.collapsed) {
      // Is selection small
      if (rng.startContainer == rng.endContainer) {
        if (rng.startOffset - rng.endOffset < 2) {
          if (rng.startContainer.hasChildNodes())
          elm = rng.startContainer.childNodes[rng.startOffset];
          if(!isWidget(elm)) return null;
          //          if(elm == el) return el;
          return elm;
          //          elm = rng.startContainer.childNodes[rng.startOffset];
        }
      }
    }
  }
  return null;
}
var active = {
  bar: null,
  el: null,
  w: 5,
  h: 2,
  resizeType: 0,
  restrict: function() {}
//  interval: null
};

function updateBarPos() {
  var pos = getImagePosition(active.el);
  active.bar.style.top = (pos.top-19) + "px";
  active.bar.style.left = (pos.left+5) + "px";
  active.bar.style.display = "block";
}

function fixFollow(cover, follow) {
  var el = editDoc.getElementById(cover.id);
  if(!el.nextSibling) {
    el.parentNode.appendChild(follow);
  } else {
    el.parentNode.insertBefore(follow, el.nextSibling);
  }
  return el;
}

function fixIEDraggedSelection() {
//  alert('dragged');
  var el = getSelectedWidget();
//  var cover = active.el;
//  var follow = editDoc.getElementById("theWidget");
  clearWidgetSel();
  muListener();
  window.setTimeout(updateBarPos, 1);

//  window.setTimeout(function() {
//    fixFollow(cover, follow);
//  },1);
}

var x = 0;
function fixFFDraggedSelection() {
//  console.log('fixing ' + x++);
//  var cover = active.el;
//  var follow = editDoc.getElementById("theWidget");
  muListener();

//  var el = fixFollow(cover, follow);

//  var elPos = getAbsPosition(el, editDoc);
//  var followPos = getAbsPosition(follow, editDoc);
//  console.log(elPos);
//  console.log(followPos);
//  if(elPos.absTop != followPos.absTop) {
//    if(follow.style.marginTop == "") {
//      follow.style.marginTop = (elPos.absTop - followPos.absTop) + 'px';
//    } else {
//      follow.style.marginTop = (parseInt(follow.style.marginTop) + (elPos.absTop - followPos.absTop)) + 'px';
//    }
//  }

  //  },1);

}

function muListener(e) {
//  var el = e.target;
//  return;
  var el;
//  console.log('muListener');
  el = getSelectedWidget(el);
//  console.log(el);
//console.log(el);
//  console.log(el);
//  console.log(active.el);
//  console.log(el == active.el);
  if(el == null) {
    clearWidgetSel();
    return;
  }

  if(el == active.el) {
    active.restrict();
    return;
  }
  active.w = parseInt(el.style.width || el.width);
  active.h = parseInt(el.style.height || el.height);

  active.el = el;

  updateBarPos();

//  var editEl = document.createElement("DIV");
  var resizeType = 0; //free resize
  if(el.name.indexOf("r1|") >= 0) {
    resizeType = 1; //no resize
  } else if(el.name.indexOf("r2|") >= 0) {
    resizeType = 2; //proportional resize
  } else if(el.name.indexOf("r3|") >= 0) {
    resizeType = 3; //width only
  } else if(el.name.indexOf("r4|") >= 0) {
    resizeType = 4; //height only
  }
  active.resizeType = resizeType;
  if(resizeType > 0) {
    var _restrict;
    if(resizeType == 1) {
      _restrict = function(w, h) {
        el.style.width = active.w + 'px';
        el.style.height = active.h + 'px';
      };
    } else if(resizeType == 2) {
      _restrict = function(w, h) {
//        console.log("restricting to proportions");
        el.style.width = w + 'px';
        el.style.height = (active.h/active.w)*w + 'px';
      };
    } else if(resizeType == 3) {
      _restrict = function(w, h) {
        el.style.width = w + 'px';
        el.style.height = active.h + 'px';
      };
    } else if(resizeType == 4) {
      _restrict = function(w, h) {
//        console.log("restricting to height only");
        window.setTimeout(function() {
          el.style.width = active.w + 'px';
          el.style.height = h + 'px';
        }, 1);
      };
    } else {
      _restrict = function(w,h) {};
    }
    active.restrict = function() {
      var newW = parseInt(el.style.width || el.width);
      var newH = parseInt(el.style.height || el.height);
      if(newW == active.w && newH == active.h) return;
      _restrict(newW, newH);
    };
  }

  if(isIE) {
    Event.observe(el, "dragend", fixIEDraggedSelection, false);
/*
    Event.observe(el, "resizeend", fixIEDraggedSelection, false);
*/
    //in case the mouseover or drag events didn't catch the drag, this interval should do it
//    active.interval = window.setInterval(function() {
//      fixIEDraggedSelection();
//    },500);
  } else if(isFF) {
/*
    Event.observe(editDoc.body, "dragdrop", function(e) {
      console.log('dragged');
    }, false);
    Event.observe(el, "DOMAttrModified", function(e) {
      if(e.attrName != 'style' && e.attrName != 'width' && e.attrName != 'height') {
        return;
      }
      console.log('resized');
    }, false);
*/

    //the mouseover event was just a hack.. replaced by domattrmodified and dragdrop
//    Event.observe(el, "mouseover", fixFFDraggedSelection, false);


    //in case the mouseover or drag events didn't catch the drag, this interval should do it
//    active.interval = window.setInterval(function() {
//      fixFFDraggedSelection();
//    },500);

//    el.setAttribute("_moz_abspos","");
//    el._moz_abspos = "";
  }

//  console.log(el);

  Event.observe(editFrame, "scroll", updateBarPos, false);

  //  el.setAttribute("onDragEnd", "console.log('drag');");
//  el.addEventListener('dragend', function() {console.log('dragend');}, false);
}

var updateCurrentWidget = function() {};

function editWidget() {
//  var newVal = prompt("enter new value", active.el.name);
//  if(newVal == null) newVal = active.el.name;
//  active.el.setAttribute("name", newVal);
  var el = active.el;
  var wid = -1;
  if(el == null) return -1;
  var index = el.name.indexOf('r'+active.resizeType+'|');
  if(index < 1) return -1;
  wid = el.name.substring(0,index);
  index = index + ('r'+active.resizeType+'|').length;
  var params = el.name.substring(index);
  if(params.indexOf('&') != 0) {
    params = '&' + params;
  }
  openWidgetBank(wid, params);
  updateCurrentWidget = function(newValues) {
    if(newValues == null) return;
    el.setAttribute("name", newValues);
  };
//  active.el.src = "http://images.freewebs.com/Images/External/SignupBanner/button_startnow_x.png";
}


function repaint() {
  var s, b, ex;

  if (!isFF)
    return;

  try {
    s = getSelection();
//    b = s.getBookmark(true);
//    editDoc.body.style.display = 'none';
    editDoc.execCommand('selectall', false, null);
    getSelection().collapseToStart();
//    editDoc.body.style.display = 'block';
//    s.moveToBookmark(b);
  } catch (ex) {
    // Ignore
  }
}

function removeWidget() {
  active.el.parentNode.removeChild(active.el);
  clearWidgetSel();
  repaint();
}
function clearWidgetSel() {
//  console.log('clearing');
//  if(active.interval != null) {
//    window.clearInterval(active.interval);
//    active.interval = null;
//  }
  Event.stopObserving(editFrame, "scroll", updateBarPos, false);
  active.bar.style.display = "none";
/*
  if(active.bar != null) {
    document.body.removeChild(active.bar);
  }
  active.bar = null;
*/
  if(active.el != null) {
    active.restrict = function() {};
    if(isIE) {
      Event.stopObserving(active.el, "dragend", fixIEDraggedSelection, false);
    } else if(isFF) {
      Event.stopObserving(active.el, "mouseover", fixFFDraggedSelection, false);
    }
    active.el = null;
  }
}

function waitListen(e) {
  window.setTimeout(function(){muListener(e)},1);
}

/*
var WidgetParser = {

};
*/
var editFrame = null;
var editDoc = null;
function initWidgetParser() {
  editFrame = $("previewArea") || $("design");
  var watchEl;
  var doc = editFrame.contentDocument ? editFrame.contentDocument : editFrame.contentWindow.document;
  editDoc = doc;

  active.bar = $("widgetToolbar");
//  console.log(active.bar);

  if(isIE) {
    watchEl = doc;
  } else {
      watchEl = editFrame.contentWindow;
  }
  Event.observe(watchEl,'mousedown',waitListen, false);

  Event.observe(watchEl, "keyup", clearWidgetSel, false);
//  editFrame.contentWindow.addEventListener('keyup', clearWidgetSel, false);

  /*
  if(isFF) {
    var ss = doc.createElement("style");
    ss.type = "text/css";
    ss.innerHTML = '.fw-widget-cover{position:absolute;display:block;}.fw-widget{overflow:hidden;}';
    doc.getElementsByTagName("HEAD")[0].appendChild(ss);
  }
*/
}

document.write('<div id="widgetToolbar" style="position:absolute;background-color:#eee;display:none;top:-30;left:0;"><img src="http://images.freewebs.com/Images/SiteManager/edit.gif" style="cursor:pointer;" onclick="editWidget();">\
                <img src="http://images.freewebs.com/Images/SiteManager/delete.gif" style="cursor:pointer;" onclick="removeWidget();"></div>');







	/**
	 * Stores the selection/caret position in IE for later restoration in new DIV HTML.
	 * This is used when a new paragraph is initialized for editing.
	 */
var selObj = {};
   function storeSelectionIE() {
		var r, tr, e, idx, nl, i, d = editDoc;
     //my vars

    if (isIE) {
			r = d.selection.createRange();

			if (r.item) {
				e = r.item(0);

				selObj.itemName = e.nodeName;
				nl = d.getElementsByTagName(e.nodeName);
				for (i=0; i<nl.length; i++) {
					if (e == nl[i]) {
						selObj.itemIndex = i;
						break;
					}
				}
			} else {
				tr = r.duplicate();
				tr.collapse(true);
        selObj.startOffset = Math.abs(tr.move('character', -999999999));

				tr = r.duplicate();
				tr.collapse(false);
				selObj.endOffset = Math.abs(tr.move('character', -999999999));
			}
		}
  }

	/**
	 * Restores the selection/caret position in IE.
	 * This is used when a new paragraph is initialized for editing.
	 *
	 * @param {Paragraph} para Reference to paragraph where selection should be restored.
	 */
	function restoreSelectionIE() {
		var r, d = editDoc, b = d.body, nl, ex, te;

		try {
			if (isIE) {
        if (selObj.itemIndex != null) {
          r = b.createControlRange();
					nl = d.getElementsByTagName(selObj.itemName);

					if (nl.length > selObj.itemIndex) {
						r.addElement(nl[selObj.itemIndex]);
						r.select();
					}
				} else {
          r = d.selection.createRange();
					r.moveToElementText(b);
					r.collapse(true);
          r.moveStart('character', selObj.startOffset);
          r.moveEnd('character', selObj.endOffset - selObj.startOffset);
          r.select();
        }
			}
		} catch (ex) {
			// Might be thrown if the node no longer exists or a unselectable element is selected
		}
    return r;
  }


function focusOnEditFrame() {
  if(isIE) {
      editFrame.contentWindow.focus();
  }
}

function insertWidget(code) {
//  closeWidgetBank();
  if(isIE) {
    focusOnEditFrame();
    restoreSelectionIE().pasteHTML(code);
  } else {
    editDoc.execCommand("inserthtml", false, code);
  }
//  window.close();
//  d.contentWindow.focus();
}

var wbPopover;
function openWidgetBank(widgetID, params) {
  if(arguments.length == 0 && active.el != null) {
    editWidget();
    return;
  }

  if(isIE) {
    focusOnEditFrame();
    storeSelectionIE();
  }

  var href = '/MembersB/WidgetBank/index.jsp';
  if(arguments.length > 0) {
      href += '?widgetID=' + widgetID + params;
  }

//  console.log(href);
//  wbPopover = new Popover(href, {height:500, width:755, heading:'Widget Bank', showLoading:false, closeButton:true, dragable:true, hideShutter:false});
  wbPopover = new Popover(href, {height:500, width:755, heading:'<img src=\"http://images.freewebs.com/Images/Base/PopoverR/header_logo.gif\">', showLoading:false, closeButton:true, dragable:true, hideShutter:true, closeButton:(isIE?closeWidgetBank:true), helpButton:'http://support.freewebs.com/?q=widgetbank'});
  wbPopover.show();
}
function closeWidgetBank() {
  wbPopover.hide();
  restoreSelectionIE();
}
