var vfsBase;
var navBase;
var dealerSpecificFlashMovieParams;
var _state = true;
var bName = navigator.appName; // browser name
// var bVer = parseFloat(navigator.appVersion); // browser version

// For IE, browser version detected
var Browser = {
  Version : function ( ) {
    var version = 999; // we assume a sane browser
    if ( navigator.appVersion.indexOf("MSIE") != -1 ) {
      // bah, IE again, lets downgrade version number
      version = parseFloat(navigator.appVersion.split("MSIE")[1]);
    }
    return version;
  }
};

var containerId = 'BridgeMovie'; // flash container id

/**
 * Get flash point. Need for make brigde with JavaScript & Flash ( ActionScrtip ).
 */
// NOTICE: This function must be EXTERNAL but not a member of some class. This is IE bug.
function getMovie ( ) {
  return document[containerId];
}

/**
 * @class Timer.
 */
function Timer ( ) {
  var _this = this;
  var currentTime = 0;
  this.tim1 = null;
  this.set = false;
  
  /**
   * Resume timer. Alias for start.
   * 
   * @see #start
   */
  this.resume = function ( ) {
    this.start();
  };
  
  /**
   * Start timer.
   */
  this.start = function ( ) {
    this.pause(); // protected failure
    
    this.tim1 = setInterval( function ( ) {
      currentTime += 500;
      if ( currentTime >= _this.time ) {
        _this.stop();
        _this.inputFunction();
      }
    }, 500);
  };
  
  /**
   * Pause timer.
   */
  this.pause = function ( ) {
    clearInterval(this.tim1);
    this.tim1 = null;
  };
  
  /**
   * Stop ( reset ) timer.
   */
  this.stop = function ( ) {
    this.pause();
    currentTime = 0;
    return;
  };
  
  /**
   * Get current timer count in ms.
   * 
   * @return Current Timer Count.
   */
  this.getCurrentTime = function ( ) {
    return (currentTime);
  };
  
  /**
   * Initialized timer.
   * 
   * @param {Number} Timeout.
   * @param {Object} to be execute after timout.
   */
  this.setTimer = function ( time , inputFunction ) {
    this.time = time;
    this.inputFunction = inputFunction;
    this.start();
    this.set = true;
  };
}

/**
 * @class Main rotation class to provide rotate flash and images assets.
 */
function Rotate ( ) {
  /**
   * Initializate rotate.
   * @param {String} jsonString String in JSON format that provide main info about assets.
   * @param {Number} [timeout=5] Timeout for showing images in seconds, not need for flash.
   * @param {Number} [fade=0.5] FadeOut/FadeIn time of transition beetwen assets in seconds.
   * @param {String} [positionOfControl="bottomright"]
   * Position of control panel ( play/pause, back, next ). Valid values: topleft, topright, bottomleft, bottomright.
   * @param {String} [toolTipText="Click to view details"] Tooltip text showing onmouse over action.
   */
  this.initRotate = function ( jsonString , timeout , fade , positionOfControl ,
      toolTipText ) {
    var _this = this; // alias
    // IE bug. First we must show control panel container, later hide it.
    
    YAHOO.util.Dom.setStyle('assetControlButton', 'display', 'none');
    
    // need to count assets loop cycles
    this.loopCount = 0;
    this.forwardCount = 1;
    this.backHistory = 0;
    this.skipHistory = false;
    this.isFirstLoop = true;
    this.nextClicked = true;
    
    // Set default variable if there's no input params {
    if ( !timeout ) {
      timeout = 5;
    }
    if ( !fade ) {
      fade = 0.5;
    }
    this.positionOfControl = (positionOfControl === null) ? "bottomright" : positionOfControl;
    this.toolTipText = (toolTipText === null) ? "Click to view details" : toolTipText;
    this.timeout = timeout * 1000;
    // Need to be divided by 2 for fadein/fadeout params
    this.fade = fade * 1000 / 2;
    // }
    
    // Initialized timer
    this.timer = new Timer(); // Image timer
    this.timer2 = new Timer(); // FadeIn/FadeOut Timer
    
    // Number of assets
    this.assetsCount = jsonString.assets.length;
    
    var containerHTML = [];
    this._width = [];
    this._height = [];
    this._flash = [];
    this._url = [];
    
    // for all assets
    for ( i = 0 ; i < this.assetsCount ; i++ ) {
      // Our flash id container name, by throught will give access to make a point
      // Create variables from JSON string {
      var _url = vfsBase + eval('("' + jsonString.assets[i].url + '")');
      var _name = eval('("' + jsonString.assets[i].name + '")');
      this._height[i] = eval('(' + jsonString.assets[i].height + ')');
      this._width[i] = eval('(' + jsonString.assets[i].width + ')');
      this._flash[i] = eval('(' + jsonString.assets[i].flash + ')');
      var _link = eval('("' + jsonString.assets[i].link + '")');
      var _title = eval('("' + jsonString.assets[i].title + '")');
      var _openInNewWindow = eval('("' + jsonString.assets[i].openInNewWindow + '")');
      var _campaignFlashParams = eval('("' + jsonString.assets[i].campaignFlashParams + '")');
      
      // if flash params is avaible, change url. Only for flash.
      if ( this._flash[i] ) {
        _url += "?baseUrl=" + navBase;
        if ( _campaignFlashParams ) {
          _url += "&" + _campaignFlashParams;
        }
        _url += "&" + dealerSpecificFlashMovieParams;
      }
      // if asset is flash, make content
      if ( this._flash[i] ) {
        // For IE
        if ( bName == "Microsoft Internet Explorer" ) {
          containerHTML[i] = "<object id='" + containerId + "' width='" + this._width[i] + "' height='" + this._height[i] + "' classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0'><param name='movie' value='" + _url + "' /><param name='wmode' value='transparent' /><param name='allowScriptAccess' value='always' /></object>";
        } else {
          // For W3C-compatible
          containerHTML[i] = "<embed name='" + containerId + "' src='" + _url + "' quality='high' width='" + this._width[i] + "' height='" + this._height[i] + "'allowScriptAccess='always' type='application/x-shockwave-flash' wmode='transparent' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed>";
        }
      } else {
        // if asset is image, make content
        // image does't have link then no need to provide href and tool tip
        if ( _link === null || _link === "" ) {
          containerHTML[i] = "<img src='" + _url + "' alt='" + _name + "' />";
        } else {
          // open in new window is true then linked target should open in new window 
          // otherwise it should open in same window
          var _target = (_openInNewWindow == "true") ? "target='_blank'" : "target='_self'";
          if(_link.indexOf(navBase) == -1){
            containerHTML[i] = "<a href='" + _link + "' " + _target + "><img src='" + _url + "' alt='" + _name + "' title='" + this.toolTipText + "' onclick='onClickFireOmnitureForReferralExit(\"dc: referral: exit\",\"home\");'/></a>";
          }
          else{
            containerHTML[i] = "<a href='" + _link + "' " + _target + "><img src='" + _url + "' alt='" + _name + "' title='" + this.toolTipText + "' /></a>";
          }
        }
      }
    }
    this.container = containerHTML;
    // Make event bind for control panel
    YAHOO.util.Event.on('ctiNext', 'click', function ( ) {
      _this.rotateControl('next');
    });
    YAHOO.util.Event.on('ctiBack', 'click', function ( ) {
      _this.rotateControl('prev');
    });
    
    // Pause flash animation
    function pause ( ) {
      YAHOO.util.Dom.get('ctiPlay').src = vfsBase + "/common/images/play.gif";
      // If asset is image, set pause for timer
      _state = false;
      if ( !_this._flash[_this.currentCount] ) {
        _this.timer.pause();
        _this.timer2.pause();
      } else {
        YAHOO.util.UserAction.click("pause"); // Hack for IE
      }
    }
    
    // Play/Resume flash animation
    function play ( ) {
      YAHOO.util.Dom.get('ctiPlay').src = vfsBase + "/common/images/pause.gif";
      // If asset is image, set pause for timer
      _state = true;
      if ( !_this._flash[_this.currentCount] ) {
        _this.timer.resume();
        _this.timer2.resume();
      } else {
        YAHOO.util.UserAction.click("play"); // Hack for IE
      }
    }
    
    // Instanse once toggle function ( play/pause )
    // play
    YAHOO.util.Event.on('ctiPlay', 'click', function ( ) {
      if ( _state ) {
        pause();
        return;
      } else {
        play();
        return;
      }
    });
    
    YAHOO.util.Event.on('assetElem', 'mouseover', pause);
    YAHOO.util.Event.on('assetElem', 'mouseout', play);
    
    // Finaly, start rotate from first asset ( 0 )
    this.beginRotate(0);
  };
  
  /**
   * Start rotate.
   * 
   * @param {String} count Begin rotate asset number.
   */
  this.beginRotate = function ( count ) {
    var _this = this; // alias
    // Check limits
    count >= this.assetsCount ? count = 0 : true;
    count < 0 ? count = this.assetsCount - 1 : true;
    _state = true;
    this.currentCount = count; // write current asset number
    ++this.loopCount;
    // calculating first loop or not
    this.isFirstLoop = (this.loopCount > this.assetsCount) ? false : true;
    
    // Control history
    if ( !this.skipHistory ) {
      if ( this.forwardCount <= this.assetsCount ) {
        // for the first loop back or previous button should be disable
        // after the first loop back button should appear
        if ( this.isFirstLoop ) {
          YAHOO.util.Dom.setStyle('ctiBack', 'display', 'none');
          YAHOO.util.Dom.setStyle('ctiBackDisabled', 'display', 'inline');
        } else {
          YAHOO.util.Dom.setStyle('ctiBack', 'display', 'inline');
          YAHOO.util.Dom.setStyle('ctiBackDisabled', 'display', 'none');
        }
      } else {
        this.skipHistory = true;
        YAHOO.util.Dom.setStyle('ctiBack', 'display', 'inline');
        YAHOO.util.Dom.setStyle('ctiBackDisabled', 'display', 'none');
      }
    }
    
    if ( this.assetsCount > 1 ) {
      // Set timeout, hack for FF 1.5.x & FF 2.x.x & IE
      // Not need in FF 3.x.x
      setTimeout(
          function ( ) {
            _this.fadeIn();
            YAHOO.util.Dom.get('assetElem').innerHTML = _this.container[_this.currentCount];
            _this.setControlPanel();
            // If asset is image, set timeouts
            if ( !_this._flash[_this.currentCount] ) {
              // Timeout to go next asset
              _this.timer.setTimer(_this.timeout, function ( ) {
                _this.rotateControl("next");
              });
              // Timeout for fadeout effect
              
              _this.timer2.setTimer(_this.timeout - _this.fade, function ( ) {
                _this.fadeOut();
              });
            }
          }, 1);
      // For one asset there is no rotate & Control Panel
    } else {
      setTimeout(
          function ( ) {
            _this.fadeIn();
            YAHOO.util.Dom.get('assetElem').innerHTML = _this.container[_this.currentCount];
            if ( _this._flash[_this.currentCount] ) {
              _this.setControlPanel();
            }
          }, 1);
    }
  };
  
  /**
   * FadeIn effect.
   */
  this.fadeIn = function ( ) {
    var _this = this; // alias
    // change the item count to insert image for transition element
    var imgCount;
    if ( _this.isFirstLoop && _this.currentCount === 0 ) {
      imgCount = 0;
    } else {
      if ( _this.nextClicked ) {
        if ( _this.currentCount === 0 ) {
          imgCount = _this.assetsCount - 1;
        } else {
          imgCount = _this.currentCount - 1;
        }
      } else {
        if ( _this.currentCount == _this.assetsCount - 1 ) {
          imgCount = 0;
        } else {
          imgCount = _this.currentCount + 1;
        }
      }
    }
    
    // set the transition image
    // for removing flickering in between images
    if ( !_this._flash[imgCount] ) {
      YAHOO.util.Dom.get('layer').innerHTML = _this.container[imgCount];
    } else {
      YAHOO.util.Dom.get('layer').innerHTML = "";
    }
    YAHOO.util.Dom.setStyle('layer', 'opacity', 1);
    YAHOO.util.Dom.setStyle('layer', 'z-index', '5');
    var myAnim = new YAHOO.util.Anim('layer', {
      opacity : {
        to : 0
      }
    }, this.fade / 1000, YAHOO.util.Easing.easeOut);
    myAnim.animate();
    // Restore layer to default after animate effect
    setTimeout( function ( ) {
      YAHOO.util.Dom.setStyle('layer', 'z-index', '-2');
    }, _this.fade);
  };
  
  /**
   * @function FadeOut effect.
   */
  this.fadeOut = function ( ) {
    var _this = this; // alias
    // make the background transparent to avoid flickering in IE
    YAHOO.util.Dom.setStyle('layer', 'background-color', 'transparent'); //
    
    // change the item count to insert image for transition element
    var imgCount;
    if ( _this.currentCount == _this.assetsCount - 1 ) {
      imgCount = 0;
    } else {
      imgCount = _this.currentCount + 1;
    }
    
    // set the transition image
    // for removing flickering in between images
    if ( !_this._flash[imgCount] ) {
      YAHOO.util.Dom.get('layer').innerHTML = _this.container[imgCount];
    } else {
      YAHOO.util.Dom.get('layer').innerHTML = "";
    }
    YAHOO.util.Dom.setStyle('layer', 'z-index', '5');
    var myAnim = new YAHOO.util.Anim('layer', {
      opacity : {
        to : 1
      }
    }, this.fade / 1000, YAHOO.util.Easing.easeOut);
    
    myAnim.animate();
  };
  
  /**
   * Set control panel in some position.
   */
  this.setControlPanel = function ( ) {
    // Set visible control panel & set it in valid position
    
    if ( this.positionOfControl == "topleft" ) {
      YAHOO.util.Dom.setStyle('assetControlButton', 'top', "0px");
      YAHOO.util.Dom.setStyle ( 'assetControlButton', 'top', "0px" );
      YAHOO.util.Dom.setStyle ( 'assetControlButton', 'left', "0px" );
      YAHOO.util.Dom.get('ctiNext').src = vfsBase + "/common/images/nextCurve.gif";
      YAHOO.util.Dom.get('ctiBack').src = vfsBase + "/common/images/back.gif";
      YAHOO.util.Dom.get('ctiBackDisabled').src = vfsBase + "/common/images/backDisabled.gif";
    } else if ( this.positionOfControl == "topright" ) {
      YAHOO.util.Dom.setStyle ( 'assetControlButton', 'top', "0px" );
      YAHOO.util.Dom.setStyle ( 'assetControlButton', 'right', "0px" );
      YAHOO.util.Dom.get('ctiNext').src = vfsBase + "/common/images/next.gif";
      YAHOO.util.Dom.get('ctiBack').src = vfsBase + "/common/images/backCurve.gif";
      YAHOO.util.Dom.get('ctiBackDisabled').src = vfsBase + "/common/images/backDisabledCurve.gif";
    } else if ( this.positionOfControl == "bottomleft" ) {
      YAHOO.util.Dom.setStyle ( 'assetControlButton', 'bottom', "0px" );
      YAHOO.util.Dom.setStyle ( 'assetControlButton', 'left', "0px" );
      YAHOO.util.Dom.get('ctiNext').src = vfsBase + "/common/images/nextCurve.gif";
      YAHOO.util.Dom.get('ctiBack').src = vfsBase + "/common/images/back.gif";
      YAHOO.util.Dom.get('ctiBackDisabled').src = vfsBase + "/common/images/backDisabled.gif";
    } else {
      YAHOO.util.Dom.setStyle ( 'assetControlButton', 'bottom', "0px" );
      YAHOO.util.Dom.setStyle ( 'assetControlButton', 'right', "0px" );
      YAHOO.util.Dom.get('ctiNext').src = vfsBase + "/common/images/next.gif";
      YAHOO.util.Dom.get('ctiBack').src = vfsBase + "/common/images/backCurve.gif";
      YAHOO.util.Dom.get('ctiBackDisabled').src = vfsBase + "/common/images/backDisabledCurve.gif";
    }
    YAHOO.util.Dom.get('ctiPlay').src = vfsBase + "/common/images/pause.gif";
    YAHOO.util.Dom.setStyle('assetControlButton', 'display', 'block');
  };
  
  /**
   * Rotate control. Manipulate rotate movie.
   * 
   * @param action Rotate action. Valid values: next, back.
   */
  this.rotateControl = function ( action ) {
    // If previos asset was image, so reset Timer
    this.timer.stop();
    this.timer2.stop();
    if ( action == "next" ) {
      ++this.forwardCount;
      ++this.backHistory;
      this.nextClicked = true;
      this.beginRotate(this.currentCount + 1);
    } else if ( action == "prev" ) {
      --this.forwardCount;
      --this.backHistory;
      this.nextClicked = false;
      this.beginRotate(this.currentCount - 1);
    }
  };
}
var rotate = new Rotate();
