//==============================================================================
//==============================================================================
var PS_INSTANCE = null;

PreviewSliderHorizontal = function(content_type) {
  PS_INSTANCE = this;
  this.content_type = content_type || 'video';

  this.cfg = {
    arrowLeft: '.ps-nav-left',
    arrowRight: '.ps-nav-right',
    sliderContainer: '.ps-images-container',
    slider: '.ps-images',
    sliderLinks: '.ps-images li a',
    stepSize: 200,//positive value in pixels
    maxHeight: 100,//px
    maxWidth: 300,//px
    numImgBefore: 10,//number of images
    numImgAfter: 10,//number of images
    stDelay1: 200//delay (ms = 1/1000s) for mousedown event happend on arrowLeft/arrowRight arrows
  };

  // currently viewed big image has certain order number in a list of previews;
  // that number is zero based
  this.currentImageNumber = 0;
  this.init();
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.init = function()
{
  var cfg = this.cfg;

  this.arrowLeft = $(this.cfg.arrowLeft);
  this.arrowRight = $(this.cfg.arrowRight);
  this.sliderContainer = $(this.cfg.sliderContainer);
  this.slider = $(this.cfg.slider);

  this.inMouseEvent = false; //flag (false,true) if we are in mousedown event
  this.inDir = ''; //related direction of scrolling (left,right)
  this.stID = 0; //setTimeout ID
  this.stepsDone = 0; //number of steps(moves) done last time
  this.isScrollable = true; //flat (false, true) if scroller area really scrollable (content doesn't fit into "viewport")

  this.initImagesList();

  if (this.isScrollable) {
    this.CheckMoreStepsRoomAfterMove();

    this.sliderContainer.mousewheel(PS_INSTANCE.OnMouseWheel);
    this.arrowLeft.bind('mousedown', 'left', PS_INSTANCE.NavArrows_OnMouseEvents);
    this.arrowRight.bind('mousedown', 'right', PS_INSTANCE.NavArrows_OnMouseEvents);
  }
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.initImagesList = function() {
  this.previews = [];
  var cfg = this.cfg;

  if (typeof(PREVIEW_SLIDER_IMAGES) == 'undefined') {
    return;
  }

  //
  // get array of images data, recalculate sizes of images, find currently viewed image order number
  //
  var i,max_i,img,img_sz;
  for (i=0, max_i=PREVIEW_SLIDER_IMAGES.length; i<max_i; i++) {
    img = PREVIEW_SLIDER_IMAGES[i];
    img_sz = this.RecalcSize(img.th, img.tw);
    img.new_th = img_sz[0];
    img.new_tw = img_sz[1];
    this.previews[i] = img;

    if (img.id == CURRENT_IMAGE_ID) {
      this.currentImageNumber = i;
    }
  }

  //
  // add LI items to UL
  //
  var min_i = (this.currentImageNumber - cfg.numImgBefore < 0) ? 0 : this.currentImageNumber - cfg.numImgBefore;
  var max_i = (this.currentImageNumber + cfg.numImgAfter > this.previews.length-1) ? this.previews.length-1 : this.currentImageNumber + cfg.numImgAfter;

  // save min_i and max_i for later usage
  this._min_index = min_i;
  this._max_index = max_i;

  // set new HTML code
  var s_html = this.GetHTML(min_i, max_i);
  this.slider.html(s_html);
  // update width of the slider
  this.slider[0].style.width = this._additional_total_width + 'px';

  //
  // check if area is scrollable
  // and if not scrollable - hide navigation arrows
  //
  // images list total width
  var full_width = parseInt(this.slider[0].clientWidth);
  // available "viewport" width
  var view_width = parseInt(this.sliderContainer[0].clientWidth);

  if (full_width < view_width && this._min_index == 0 && this._max_index == this.previews.length-1) {
    this.isScrollable = false;
    this.arrowLeft[0].style.display = 'none';
    this.arrowRight[0].style.display = 'none';
  }

  //
  // make current image visible as 2nd from the left
  //
  // exception is made for the 1st and 2nd images; when showing 1st or 2nd image
  // modification of scroll area LEFT value isn't required
  //
  var new_left = 0;//default value for left; left value must be initialised in any case;
  var n_curr = this.currentImageNumber;
  var n_prev = n_curr > 0 ? n_curr - 1 : 0;

  if (this.isScrollable && n_curr != 0 && n_curr != 1) {
    var prev_image_offset_left = $('li#_thumb_'+n_prev)[0].offsetLeft;

    // CASE #3 all other cases
    // slider new left value will be equal to previous image offset from left
    new_left = -prev_image_offset_left;
    // however if with this offset we will create empty space at our slider THEN
    // make slider position at the RIGHT end
    var check_var = new_left + full_width;
    if (check_var < view_width) {
      new_left = view_width - full_width;
      // fix for case when full_width of content is less than view_width of "viewport"
      if (new_left > 0)
        new_left = 0;
    }
  }

  this.slider[0].style.left = new_left+'px';

  return;
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.Move = function(dir)
{
  // direction of scrolling either externally defined or through this.inDir
  dir = dir || this.inDir;

  // increase number of steps done
  this.stepsDone++;

  //
  // check if we have dynamically insert images before (if LEFT) or after (if RIGHT) existing LI tags
  //
  this.CheckMoreImagesBeforeMove(dir);

  var step = this.cfg.stepSize;
  var curr_left = parseInt(this.slider[0].style.left);
  var full_width = parseInt(this.slider[0].clientWidth);
  var view_width = parseInt(this.sliderContainer[0].clientWidth);

  var new_left, do_slide = false;

  //
  // calculate new LEFT value
  // when moving LEFT (arrow LEFT clicked)
  //
  if (dir == 'left')
  {
    new_left = curr_left + step;

    if (new_left > 0 && new_left < step)
    {
      new_left = 0;
      do_slide = true; 
    }
    else
    if (new_left <= 0 && curr_left < 0)
    {
      do_slide = true;
    }
  }

  //
  // calculate new LEFT value
  // when moving RIGHT (arrow RIGHT clicked)
  //
  if (dir == 'right')
  {
    new_left = curr_left - step;
    var check_val = new_left + full_width;

    if (check_val >= view_width)
    {
      do_slide = true;
    }
    else
    if (check_val > 0)
    {
      new_left = -full_width + view_width;
      if (new_left != curr_left)
      {
        do_slide = true;
      }
    }
  }

  // do move
  if (do_slide) {
    this.slider[0].style.left = new_left+'px';
  }

  this.CheckMoreStepsRoomAfterMove();

  return;
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.CheckMoreImagesBeforeMove = function(dir)
{
  // if moving LEFT & min index eq 0 then nothing to insert; exit early
  // if moving RIGHT & max index eq length-1 then nothing to insert; exit early
  if ((dir == 'left' && this._min_index == 0) || (dir == 'right' && this._max_index == this.previews.length-1))
    return;

  var cfg = this.cfg;
  var step = this.cfg.stepSize;
  var curr_left = parseInt(this.slider[0].style.left);
  var full_width = parseInt(this.slider[0].clientWidth);
  var view_width = parseInt(this.sliderContainer[0].clientWidth);

  //
  // maximum value for LEFT is 0
  // minimum value for LEFT is -full_width+view_width
  // when LEFT: if we are closer then step*2 to maximum value THEN add to the LEFT cfg.numImgBefore items
  // wehn RIGHT: if we are closer then step*2 to minimum value THEn add to the RIGHT cfg.numImgAfter items
  //

  var do_insert_before = false, do_insert_after = false, check_value, new_min_i, new_max_i;
  //
  // make checks
  // when moving LEFT (arrow LEFT clicked)
  //
  if (dir == 'left')
  {
    check_value = curr_left + step*2;
    if (check_value >= 0)
      do_insert_before = true;
  }

  //
  // make checks
  // when moving RIGHT (arrow RIGHT clicked)
  //
  if (dir == 'right')
  {
    check_value = curr_left - step*2;
    if (check_value <= -full_width + view_width)
      do_insert_after = true;
  }

  if (do_insert_before)
  {
    // calculate new index for images at the LEFT (begin of the list)
    new_min_i = this._min_index-cfg.numImgBefore < 0 ? 0 : this._min_index-cfg.numImgBefore;
    var s_html = this.GetHTML(new_min_i, this._min_index-1);
    this.slider.prepend(s_html);
    this._min_index = new_min_i;
    // update LEFT value, because content from above has been encreased in width by
    // this._additional_total_width value
    this.slider[0].style.left = (curr_left-this._additional_total_width) + 'px';
  }

  if (do_insert_after)
  {
    // calculate new index for images at the RIGHT (end of the list)
    new_max_i = this._max_index+cfg.numImgAfter > this.previews.length-1 ? this.previews.length-1 : this._max_index+cfg.numImgAfter;
    var s_html = this.GetHTML(this._max_index+1, new_max_i);
    this.slider.append(s_html);
    this._max_index = new_max_i;
  }

  return;
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.CheckMoreStepsRoomAfterMove = function() {
  var cfg = this.cfg;
  var curr_left = parseInt(this.slider[0].style.left);
  var full_width = parseInt(this.slider[0].clientWidth);
  var view_width = parseInt(this.sliderContainer[0].clientWidth);

  var do_disable_left = do_disable_right = false;
  var do_enable_left = do_enable_right = false;

  // if moving LEFT then we have to check LEFT border
  if (curr_left == 0 && this._min_index == 0)
    do_disable_left = true;
  else
    do_enable_left = true;

  // if moving RIGHT then we have to check RIGHT border
  var check_var = curr_left + full_width;
  if (check_var == view_width && this._max_index == this.previews.length-1)
    do_disable_right = true;
  else
    do_enable_right = true;

  // arrow LEFT
  if (do_disable_left)
    this.arrowLeft[0].style.display = 'none';
  if (do_enable_left)
    this.arrowLeft[0].style.display = '';

  // arrow RIGHT
  if (do_disable_right)
    this.arrowRight[0].style.display = 'none';
  if (do_enable_right)
    this.arrowRight[0].style.display = '';

  return;
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.RecalcSize = function(orig_h, orig_w)
{
  var max_h = this.cfg.maxHeight;
  var max_w = this.cfg.maxWidth;

  var h = orig_h;
  var w = orig_w;
  // limit image size by maximum height and maximum width
  // first, limit by width
  if (w > max_w)
  {
    w = max_w;
    h = orig_h * max_w/orig_w;
  }
  // now, limit by height
  if (h > max_h)
  {
    w = w * max_h/h;
    h = max_h;
  }

  return [Math.ceil(h), Math.ceil(w)];
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.GetHTML = function(min_i, max_i)
{
  var s1 = '';
  var s2 = '';
  var cfg = this.cfg;
  var total_h = 0;
  var total_w = 0;
  var extra_image_width = 20;//that is margin-left + margin-right around <a><img/></a>

  for (var i = min_i; i <= max_i; i++) {
    // get images
    img = this.previews[i];
    // build html code like this (comment later)
    s2 = (i == this.currentImageNumber) ? ' class="ps-current"' : ' ';

    if (this.content_type == 'video') {
      s3 = 'onclick="changeDemo('+i+');"';
    } else {
      s3 = 'onclick="changeImage('+i+');"';
    }

    s1 += '<li style="width:'+(img.new_tw+extra_image_width)+'px;" '+s2+' id="_thumb_'+i+'">';
    s1 += '<a href="javascript:void(0);" '+s3+' title="">';
    s1 += '<img src="'+img.tu+'" height="'+img.new_th+'" width="'+img.new_tw+'" border="0" alt="" title="" />';
    s1 += '</a>';
    s1 += '<div>'+img.title+'</div>';
    s1 += '</li>\n';

    total_w += extra_image_width + img.new_tw;
  }

  // that temporary variable carries total width of added to list images
  this._additional_total_width = total_w;

  return s1;
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.OnMouseWheel = function(event, delta)
{
  // determine direction
  var increment = (delta > 0);
  var dir = increment ? 'left' : 'right';
  PS_INSTANCE.Move(dir);
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.NavArrows_OnMouseEvents = function(event)
{
  var event_type = event.originalEvent.type;
  var arrow_type = event.data;

  if (arrow_type == 'body')
    PS_INSTANCE.NavArrows_OnMouseUp();
  else
    PS_INSTANCE.NavArrows_OnMouseDown(arrow_type);
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.NavArrows_OnMouseDown = function(arrow_type)
{
  // start scrolling events sequence
  this.inMouseEvent = true;
  // reset number of steps done
  this.stepsDone = 0;
  // set scrolling direction (left,right) by arrow type
  this.inDir = arrow_type;
  // bind to document body mouseup event handler
  $('body').bind('mouseup', 'body', PS_INSTANCE.NavArrows_OnMouseEvents)
  // finally, set timeout for next auto-step
  this.stID = setTimeout(PS_INSTANCE.OnTimeout1, PS_INSTANCE.cfg.stDelay1);
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.NavArrows_OnMouseUp = function()
{
  //
  // DOING ALL THINGS IN THE OPPOSITE ORDER
  //
  // first, clear timeout
  if (this.stID)
  {
    clearTimeout(this.stID);
    this.stID = 0;
  }
  // second, remove event binding from body
  $('body').unbind('mouseup', PS_INSTANCE.NavArrows_OnMouseEvents);
  // third is to do the rest things;
  // cancel scrolling events sequence
  this.inMouseEvent = false;
  // check if any steps are really done; if not any done - make at least one step
  if (!this.stepsDone)
  {
    this.Move();
  }
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PreviewSliderHorizontal.prototype.OnTimeout1 = function()
{
  if (!PS_INSTANCE.inMouseEvent)
    return;

  // do scroll
  PS_INSTANCE.Move();
  // set timeout again
  PS_INSTANCE.stID = setTimeout(PS_INSTANCE.OnTimeout1, PS_INSTANCE.cfg.stDelay1);
};
//==============================================================================
//==============================================================================

