/*
    JavaScript file to control generic Layer Management via the iframe model.
    This file will be loaded on nearly every Target.com page for Quick Info,
    so keep the functionality small and generic. If JS is needed for a specific
    page, put it into it's own .js file.
    @author - zshalla
*/
var layerFrameId = "LayersFrame";
var hiddenLayerFrameId = "hiddenLayersFrame";
var dragFrameId = "dragFrame";
var dragFrameCloseId = "dragFrameClose";
var dragFrameOffset = 50;
var messageFrameId = "messageFrame";
var hostLoc = (location.protocol+"//"+location.host+"/layers/test-layer");

/* <![CDATA[
                                                                                                                        
NOTE/TODO:
In IE, if the iframe is added dynamically, like we do below, and change the target of a form dynamically (like for the Target buybox),
the two can't connect and a new window is opened to display the layer. To get around this, for now we will have to put the
following iframe html directly into pages with these forms submits (detail page, QI layer).
                                                                                                                        
<iframe height="0" frameborder="0" width="0" id="LayersFrame" name="LayersFrame" title="Quick Info"  allowtransparency="true" ></iframe>
                                                                                                                        
]]> */
            function pollLayer(){
                var layer = document.getElementById(messageFrameId);
                var childLoc;
                if(layer){
                    try{
                        var cWindow = layer.contentWindow;
                        childLoc = cWindow.location;
                        var hash = childLoc.hash;
                        var messages = parseHash(hash.substr(1));
                        //alert(message);
                        
                        if(messages.host && messages.host != hostLoc){
                            //we've recieved a message
                            showLayerFromParentJSON({className: messages.className, showClose:1 });
                            passMessageToLayer("host="+hostLoc, messages.host);
                        }else{
                            // if host is the same, we're in the same domain as the layer, so no need to do anything
                        }
                    }catch(e){
                        // we don't have control of the messaging frame
                        //alert(e);
                    }
                }
                setTimeout("pollLayer()", 500);
            }         

pollLayer();


function parseHash(hash){
    var messages = new Object();
    var hashArray = hash.split("&");
    for(message in hashArray){
        var messageArray = hashArray[message].split("=");
        messages[messageArray[0]] = messageArray[1];
    }
    return messages;
}     
                                                                                                                     
function passMessageToLayer(message, host){
      try{
          var loc = host + "#" +message;
          top.messageFrame.location.replace(loc);
      
      }catch (e) { /* This means we don't have control of the message frame. */ }    
} 
                                                                                                                       
function invokeFIATS(asin, zip, element){
    var path = "/gp/store-info/popup-start.html?asin="+asin;
    var top;
    var className = "fiatsSearch";
    if(!isNaN(zip)){
        path += "&zip="+zip;
        className="fiatsResults";
    }
    if(element){
        top = findPosY(element);
    }
    setLayerPath(path);
    // just in case close on click is enabled, disable it, and the showLayer method will turn it back on. Yay race conditions. 
    disableCloseOnClick();
    setTimeout("showLayerFromParentJSON({className:'"+ className +"', top:"+top+"})", 750);
}

function invokeQuickInfo(asin, ref, element){
        var path = "";
        var refPath = "";
        var top;
        if(!asin){
            /*alert("ASIN was null!");*/
            return;
        }
        if(ref){
            refPath ="/ref="+ref;
        }
        if(element){
            top = findPosY(element);
        }
        path += "/mdp/"+asin+refPath;
        setLayerPath(path);
        
        // just in case close on click is enabled, disable it, and the showLayer method will turn it back on. Yay race conditions.
        disableCloseOnClick();
        setTimeout("showLayerFromParentJSON({className:'miniDetail', top:"+top+"})", 750);
}

function findPosY(element){
    return findPos(element).y;
}
                                                                                                                        
function findPos(element){
    var yPos = 0;
    var xPos = 0;
    yPos += element.offsetTop;
    xPos += element.offsetLeft;

    while(element = element.offsetParent){
        yPos += element.offsetTop;
        xPos += element.offsetLeft;
    }
    
    return {x:xPos, y:yPos};
}
                                                                                                                        
function imageMapInvokeQuickInfo(obj,reftag) {
  var destinationLink = "";
  if(obj.destinationLink) {
    destinationLink = obj.destinationLink;
  } else if(obj.href) {
    destinationLink = obj.href;
  }
                                                                                                                        
  var asinRegexp = /\/dp\/(\w*)/;
  var asin_match = destinationLink.match(asinRegexp);
  var asin = asin_match[1];
  invokeQuickInfo(asin,reftag,obj);
                                                                                                                        
  return false;
}
                                                                                                                        
function imageMapHideQuickInfoHover(obj) {
  if(obj.disableHide) { return; }
  var img = obj;
  if(obj.tagName.toLowerCase() == "area")
  {
    var mapID = obj.parentNode.name;
    img = document.getElementById("hoverImg" + mapID);
  }
  img.style.display="none";
}
                                                                                                                        
function imageMapShowQuickInfoHover(area) {
    
  var coords_str = area.coords;
  var coords = coords_str.split(",");
  var x1 = parseInt(coords[0]);
  var y1 = parseInt(coords[1]);
  var x2 = parseInt(coords[2]);
  var y2 = parseInt(coords[3]);
  var hoverHeight = 19;
  var hoverWidth = 74;
                                                                                                                        
  var width = x2-x1;
  var height = y2-y1;

  var hoverLeft = Math.round(width/2 - hoverWidth/2);
  var hoverTop = height - hoverHeight - 8;
                                                                                                                        
  var top=0;
  var left=0;
                                                                                                                        
  var offsetName = area.offsetParent.tagName;
  //Some browsers report the position of the area relative to the map.
  //others report the position of the area relative to the containing div.
  if(offsetName.toLowerCase() == "map")
  {
    top = area.offsetTop + hoverTop;
    left = area.offsetLeft + hoverLeft;
  } else {
    top = area.offsetTop + y1 + hoverTop;
    left = area.offsetLeft + x1 + hoverLeft;
  }
                                                                                                                        
  var mapID = area.parentNode.name;
  var hoverImg = document.getElementById("hoverImg" + mapID);

  area.disableHide = true;
                                                                                                                        
  hoverImg.style.display="block";
  hoverImg.style.top=top;
  hoverImg.style.left=left;
  hoverImg.onclick = area.onclick;
  hoverImg.onmouseout = area.onmouseout;
  hoverImg.destinationLink = area.href;

  setTimeout(function(){area.disableHide = false;},100);

  return false;
}
                                                                                                                        
                                                                                                                       

function enableCloseOnClick(){
    // close the quickview reveal on any mouse click outside of the popover
    document.onclick = function ( event ) {
        // this is much simpler than previous implementations due to the iframe.
        // since the iframe has it's own document, clicking inside the iframe doesn't activate this.
        
        hideLayerFromParent();
    };
}                                                                                                                         
                                                                                                                        
function disableCloseOnClick(){
    document.onclick = function ( event ) {};
} 

var mouseOffset; 
function drag( event ) {
    event = event || window.event;
    var mousePos = mouseCoords(event);
    //setTimeout("alert('"+mousePos.x+"');", 3000);
    var frame = document.getElementById(layerFrameId);
    var hFrame = document.getElementById(hiddenLayerFrameId);
    var dragFrame = document.getElementById(dragFrameId);
    var dragFrameClose = document.getElementById(dragFrameCloseId);
    var mouseX = mousePos.x - mouseOffset.x;
    var mouseY = mousePos.y - mouseOffset.y;
    frame.style.top = mouseY + "px";
    frame.style.left = mouseX + "px";
    dragFrame.style.top = mouseY + "px";
    dragFrame.style.left = (mouseX + dragFrameOffset) + "px";
    dragFrameClose.style.top = mouseY + "px";
    dragFrameClose.style.left = mouseX + "px";

    if(hFrame){
        hFrame.style.top = mousePos.y - mouseOffset.y + "px";
        hFrame.style.left = mousePos.x - mouseOffset.x + "px";
    }
    disableCloseOnClick();
}
    
function enableDrag(event){
    // drag the layer 
    event = event || window.event;
    /* we increase the height of the drag area during dragging because the bar is narrow,
       and if the mouse is moved downwards too fast, it will fall into the iframe document, 
       and dragging will no longer work. Be temporarily extending the drag box, we make sure
       slow browsers and fast mouse movements won't lose the dragging ability. 
    */
    document.getElementById(dragFrameId).style.height = "200px";
    document.getElementById(dragFrameCloseId).style.height = "200px";
    mouseOffset = getMouseOffset(document.getElementById(dragFrameId), event); 

    //document.getElementById(dragFrameId).onmousemove = drag; 
    document.onmousemove = drag; 
}                                                                                                                         

function disableDrag(){
    setTimeout("enableCloseOnClick()", 750);
    //document.getElementById(dragFrameId).onmousemove = function ( event ) {};
    document.getElementById(dragFrameId).style.height = "";
    document.getElementById(dragFrameCloseId).style.height = "";
    document.onmousemove = function ( event ) {};  
}                                                                                                                         

function mouseCoords(ev){ 
    if(ev.pageX || ev.pageY){ 
        return {x:ev.pageX, y:ev.pageY}; 
    } 
    return { 
        x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, 
        y:ev.clientY + document.body.scrollTop  - document.body.clientTop 
    }; 
} 
  
function getMouseOffset(target, ev){ 
    ev = ev || window.event; 

    var docPos    = findPos(document.getElementById(layerFrameId)); 
    var mousePos  = mouseCoords(ev); 
    return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y}; 
} 
                                                                                                                        
                                                                                                                        
function setLayerPath(path){
    setLayerURL(location.protocol + "//" + location.host + path);
}
                                                                                                                        
function setLayerURL(url){
    var frame = document.getElementById(layerFrameId);
    //clear the iframe to force reload
    frame.src = "";
    frame.src = url;
    //showLayerFromParent();
}

function clearLayer(){
    setLayerPath("/gp/iframe.html");
}
                                                                                                                        
function hideLayerFromParent(){
    var frame = document.getElementById(layerFrameId);
    var hFrame = document.getElementById(hiddenLayerFrameId);
    var dragFrame = document.getElementById(dragFrameId);
    var dragFrameClose = document.getElementById(dragFrameCloseId);
    //to take care of legacy showFrame method
    frame.width=null;
    frame.height=null;
    frame.style.zIndex="";
    // set the frame class to hidden
    frame.className = "hidden";
    // reset the iframe to initial spacer content
    clearLayer();
    //hide the dragging frame
    if(dragFrame){
        dragFrame.className = frame.className;
        /*dragFrame.style.top = frame.style.top;
        dragFrame.style.left = frame.style.left;*/
        dragFrame.style.zIndex = "";
    }
    if(dragFrameClose){
        dragFrameClose.className = frame.className;
        dragFrameClose.style.zIndex = "";
    }
    if(hFrame) {
        hFrame.className = "hidden";
        if(hFrame.width){
            //indicates the old display method was used
            hFrame.width="0px";
            hFrame.height="0px";
            hFrame.style.zIndex=-1;
            hFrame.style.display="none";
        }
    }
    disableCloseOnClick();
    hideCloseButton();
}
                                                                                                                        
function showLayerFromParentJSON(json){
    var frame = document.getElementById(layerFrameId);
    var hFrame = document.getElementById(hiddenLayerFrameId);
    var dragFrame = document.getElementById(dragFrameId);
    var dragFrameClose = document.getElementById(dragFrameCloseId);
    //var hFrame = new Object();
    if(json.className){
        if(json.className.match("hidden")){
            /*if the class is hidden, we need to hide the rest of the pieces as well.*/
            hideLayerFromParent();
            return;
        }
        frame.className = json.className;
        // position in the middle of the page
        var left = 0;
        var width = frame.offsetWidth;
        if(window.innerWidth){
            left = (window.innerWidth - width) /2;
        }else{
            left = (document.body.offsetWidth - width) /2;
        }
        frame.style.left = left +"px";
        
    }
    
    if(json.top){
        //caluculate the top
        var top = new Number(json.top);                         // top is the top of the iframe
        if(frame.offsetHeight){
            top -= parseInt(frame.offsetHeight)/2;
        }
        var height = parseInt(frame.offsetHeight);  // height is the height of the frame
        var bottom = top + height;                  // bottom is the bottom of the frame
        
        //find the vertical positioning
        var scrollTop = document.body.scrollTop;    // scrollTop is the top of viewport
        if (scrollTop == 0){
            if (window.pageYOffset)
                scrollTop = window.pageYOffset;
            else
                scrollTop = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : 0;
        }
        
        var scrollBottom = scrollTop;               // scrollBottom is the bottom of the viewport
        if(window.innerHeight){
            scrollBottom += window.innerHeight;
        }else{
            scrollBottom += document.body.offsetHeight;
        }
        
               
        // make sure the layer appears in the viewport, with preference given to having the top appearing in the viewport
        if(bottom > scrollBottom){
            top = scrollBottom - height;
        }
        if(top < scrollTop){
            top = scrollTop;
        }
        
        //set the top
        if(top >= 0){
           frame.style.top = top + "px";
        }
    }
    setTimeout("enableCloseOnClick()", 750);
    
    if(json.showClose){
        showCloseButton();
    }
    
    //position the dragging frame
    if(dragFrame){
        dragFrame.className = frame.className;
        dragFrame.style.top = frame.style.top;
        var left = frame.style.left;
        if(!left) {
            left="0";
        }
        dragFrame.style.left =  (parseInt(left) + dragFrameOffset) + "px";
        dragFrame.style.zIndex = 10;
    }
    if(dragFrameClose){
        dragFrameClose.className = frame.className;
        dragFrameClose.style.top = frame.style.top;
        dragFrameClose.style.left = frame.style.left;
        dragFrameClose.style.zIndex = 10;
    }
    if(hFrame){
        hFrame.className = frame.className;
        hFrame.style.top = frame.style.top;
        hFrame.style.left = frame.style.left;
        hFrame.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';
        hFrame.style.display = "";
        hFrame.style.zIndex = 2;
    }
    
}

function showLayerFromParent(width, height,zindex, top){
    var frame = document.getElementById(layerFrameId);
    var hFrame = document.getElementById(hiddenLayerFrameId);
    var w = width ? width : "600";
    var h = height ? height : "1000";
    var z = zindex ? zindex : 5;
    try{
        var frameDoc;
        if(frame.contentDocument) {
            frameDoc = frame.contentDocument;
        }
        else if(frame.contentWindow) {
            frameDoc = frame.contentWindow.document;
        }
        else if(frame.document) {
            frameDoc = frame.document;
        }
        if(frameDoc && frameDoc.body) {
            frameDoc.body.style.backgroundColor = "transparent";
        }
    }catch(err){}
                                                                                                                        
    frame.width= w + "px";
    frame.height= h + "px";
    frame.style.zIndex= z;
    // position in the middle of the page
    var left = 0;
    if(window.innerWidth){
        left = (window.innerWidth - w) /2;
    }else{
        left = (document.body.offsetWidth - w) /2;
    }
    // position central to button clicked
    if(!top){
        if(frame.style.top){
            top = parseInt(frame.style.top);
        }else{
            top = "200";
        }
    }else{
        top -= h/2;
    }
    frame.style.left = left +"px";
    if(top > 0){
        frame.style.top = top + "px";
    }
    if(hFrame) {
        hFrame.width = w + "px";
        hFrame.height = h + "px";
        hFrame.style.zIndex = z-1;
        hFrame.style.top = frame.style.top;
        hFrame.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';
        if(left>0) {
            hFrame.style.left = frame.style.left;
        }
        hFrame.style.display = "";
    }
}

YAHOO.util.Event.addListener(window, 'load', QIattachEventKeyUp);

function QIattachEventKeyUp(){
    var classNameSearch = "quickInfoLink"; // class name we're searching for

    ///////////////

    var classSearchFunction = function(element) {
        return element.className.indexOf(classNameSearch) != 1;
    };

    //  10-30ms in FF3
    var QIs = YAHOO.util.Dom.getElementsBy(classSearchFunction, "span");

    // attach the onkeyup event listeners
    YAHOO.util.Event.addListener(QIs, "keyup", QIonKeyUp);
}

function QIonKeyUp(event){
   var key;
   if (event.which) {
       // non-IE
       key = event.which;
   } else if(event.keyCode) {
       // IE
       key = event.keyCode;
   }
   if(key == 13) {  // enter key
       var QI = event.srcElement || event.target;
       window.location = QI.href; // redirect
   }
}

function QIonreadystatechange(e){
    if(document.getElementById(layerFrameId).readyState == 'complete'){
        showCloseButton();
    } else {
        hideCloseButton();
    }
}
                                                                                                                                                             
function hideCloseButton(){
    var button = YAHOO.util.Dom.getElementsByClassName('close', 'a', dragFrameCloseId);
    YAHOO.util.Dom.removeClass(button, 'close');
    YAHOO.util.Dom.addClass(button, 'hidden');
}
                                                                                                                                                             
function showCloseButton(){
    var button = YAHOO.util.Dom.getElementsByClassName('hidden', 'a', dragFrameCloseId);
    YAHOO.util.Dom.removeClass(button, 'hidden');
    YAHOO.util.Dom.addClass(button, 'close');
}
