﻿/// <reference path="jquery-1.3.vsdoc.js" />
/* 
@project TimeLine
@name jquery.timeline.js
@created 2008-12-23
@version 0.1 (alpha release)
@author Konrad Pociask - konradpociask@gmail.com
@require ui.core.js, ui.slider.js, timeline.css
@description  jQuery plugin to display TimeLine
*/

/*
  Basic steps:
  
  1. Create xhtml like this:
  
    <div class="timeline">
        <ul id="ulYears" class="years">
            ...
            <li>1960</li>
            <li>1961</li>
            <li>1962</li>
            ...
        </ul>
        <div class="sliderDetailAxis"></div>
        <div class="sliderDetail">
            <div class="ui-slider-handle">&nbsp;</div>
            <div class=" ui-slider-handle">&nbsp;</div>
        </div>
        <div class="sliderMasterAxis"></div>
        <div class="sliderMaster">
            <div class=" ui-slider-handle">&nbsp;</div>
        </div>
    </div>

  2. Init the plugin by calling Init function with three arguments: 
  - container (object) for whole TimeLine (there might be only one timeline in it),
  - containers (objects) for selected dates values:
  
        InitSlider(a_oContainer, a_oFrom, a_oTo));
      
  3. If you hide TimeLine the you must call this method:
        DestroySliders(a_oContainer);
*/

// Consts
var m_sTimeLineClass = '.timeline';
var m_sYearsClass = '.years';
var m_sSliderDetailClass = '.sliderDetail';
var m_sSliderMasterClass = '.sliderMaster';
var m_iYearStart = 1960;
var m_iYearStop = 2009;
var m_iMinDetail = 0;
var m_iMaxDetail = 500;
var m_iMinMaster = 0;
var m_iMaxMaster;
var m_iSteppingDetail = 50;
var m_iSteppingMaster = 50;
var m_iYearPeriodsInView = (m_iMaxDetail - m_iMinDetail) / m_iSteppingDetail;   // = 10;

function InitSliders(a_oContainer, a_oFrom, a_oTo) {
    var oTimeLine;
    var oYears;
    var oFrom = a_oFrom;
    var oTo = a_oTo;
    var oSliderDetail;
    var oSliderMaster;

    var sFrom = $(oFrom).val();
    var sTo = $(oTo).val();

    oTimeLine = $(m_sTimeLineClass, a_oContainer)
    oYears = $(m_sYearsClass, oTimeLine);
    m_iMaxMaster = oYears.innerWidth() - oTimeLine.outerWidth();

    // Calculating HandleMasters appropriate position
    var iPosMaster = GetPositionMasterFromDates(sFrom, sTo);

    var iPos1 = GetPositionFromDate(sFrom, iPosMaster);
    var iPos2 = GetPositionFromDate(sTo, iPosMaster);

    if (iPos1 < m_iMinDetail) {
        iPos1 = m_iMinDetail;
    }

    if (iPos2 > m_iMaxDetail || iPos2 == m_iMinDetail) {
        iPos2 = m_iMaxDetail;
    }

    if (iPos1 > iPos2) {
        if ((iPos1 + m_iSteppingDetail) > m_iMaxDetail) {
            iPos1 = iPos2 - m_iSteppingDetail;
        }
        else {
            iPos2 = iPos1 + m_iSteppingDetail;
        }
    }

    // Init Slider Detail   
    oSliderDetail = $(m_sSliderDetailClass, oTimeLine);

    $(oSliderDetail).slider(
    {
        animate: true,
        min: m_iMinDetail,
        max: m_iMaxDetail,
        values: [iPos1, iPos2],
        range: true,
        slide: function(ev, ui) {
            SetDatesObjects(oSliderMaster, oSliderDetail, oFrom, oTo);
        }
    });

    // Init Slider Master
    oSliderMaster = $(m_sSliderMasterClass, oTimeLine);

    $(oSliderMaster).slider(
    {
        animate: true,
        min: 0,
        max: m_iMaxMaster,
        slide: function(ev, ui) {
            oYears.css('left', '-' + ui.value + 'px');
            SetDatesObjects(oSliderMaster, oSliderDetail, oFrom, oTo);
        },
        stop: function(ev, ui) {
            oYears.animate({ 'left': '-' + ui.value + 'px' }, 500, 'linear');
            SetDatesObjects(oSliderMaster, oSliderDetail, oFrom, oTo);
        }
    });

    $(oSliderMaster).slider("value", iPosMaster);

    SetDatesObjects(oSliderMaster, oSliderDetail, oFrom, oTo);
}

function DestroySliders(a_oContainer) {
    $(m_sSliderMasterClass, a_oContainer).slider('destroy');
    $(m_sSliderDetailClass, a_oContainer).slider('destroy');
}

function SetDatesObjects(a_oSliderMaster, a_oSliderDetail, a_oFrom, a_oTo) {
    var fPosMaster = $(a_oSliderMaster).slider('value') / m_iSteppingMaster;
    var iPosMaster = parseInt(fPosMaster);
    
    var fPosDet1 = $(a_oSliderDetail).slider('values', 0) / m_iSteppingDetail;
    var fPosDet2 = $(a_oSliderDetail).slider('values', 1) / m_iSteppingDetail;
    var iPosDet1 = parseInt(fPosDet1);
    var iPosDet2 = parseInt(fPosDet2);
    var iMonth1 = (Math.round((fPosMaster - iPosMaster + fPosDet1 - iPosDet1) * 12) + 1);
    var iMonth2 = (Math.round((fPosMaster - iPosMaster + fPosDet2 - iPosDet2) * 12) + 1);

    if (iMonth1 > 12) {
        iMonth1 = iMonth1 - 12;
        iPosDet1 = iPosDet1 + 1;
    }

    if (iMonth2 > 12) {
        iMonth2 = iMonth2 - 12;
        iPosDet2 = iPosDet2 + 1;
    }

    var sMonth1 = iMonth1.toString();
    var sMonth2 = iMonth2.toString();

    if (sMonth1.length == 1) {
        sMonth1 = '0' + sMonth1;
    }
    if (sMonth2.length == 1) {
        sMonth2 = '0' + sMonth2;
    }

    $(a_oFrom).val("01-" + sMonth1 + "-" + (m_iYearStart + iPosMaster + iPosDet1));
    $(a_oTo).val("01-" + sMonth2 + "-" + (m_iYearStart + iPosMaster + iPosDet2));
}

// Convert date from string value to handle position
// Date Format - "dd-MM-yyyy"
// If a_sDate is "" or a_iMasterHandlePosition is null then return m_iMinDetail otherwise return appropriate handle position (int)
function GetPositionFromDate(a_sDate, a_iMasterHandlePosition) {
    if (a_sDate != "" && a_iMasterHandlePosition != null) {
        var iYear = parseInt(a_sDate.substring(6, 10));
        var iMonth = GetMonthFromDate(a_sDate);
        var iYearStartActual = Math.round(a_iMasterHandlePosition / m_iSteppingMaster) + m_iYearStart;
        return Math.round((iYear - iYearStartActual + (iMonth - 1) / 12) * m_iSteppingDetail);
    }
    else {
        return m_iMinDetail;
    }
}

// Return master handle position
// Date Format - "dd-MM-yyyy"
function GetPositionMasterFromDates(a_sFrom, a_sTo) {
    if (a_sFrom != "") {
        var iYear1 = parseInt(a_sFrom.substring(6, 10));
        var iMonth1 = GetMonthFromDate(a_sFrom);
    }
    else {
        iYear1 = m_iYearStart;
        iMonth1 = 0;
    }
    
    if (a_sTo != "") {
        var iYear2 = parseInt(a_sTo.substring(6, 10));
        var iMonth2 = GetMonthFromDate(a_sTo);
    }
    else {
        iYear2 = iYear1;
        iMonth2 = 0;
    }
    
    var iYearSum = iYear1 + iYear2;
    
    var iMonthSum = iMonth1 + iMonth2;
    if (iMonthSum > 12)
    {
        iMonthSum = iMonthSum - 12;
        iYearSum = iYearSum + 1;
    }
    
    var fYearAvg = iYearSum / 2;
    var fMonthAvg = iMonthSum / 2;

    var iPosMaster = parseInt(fYearAvg - m_iYearPeriodsInView / 2 - m_iYearStart + fMonthAvg / 12) * m_iSteppingMaster;

    if (iPosMaster < 0) {
        return m_iMinMaster;
    }
    else if (iPosMaster > m_iMaxMaster) {
        return m_iMaxMaster
    }
    else {
        return iPosMaster;
    }
}

// Return month number from date (int)
// Date Format - "dd-MM-yyyy"
function GetMonthFromDate(a_sDate) {
    var sMonth = a_sDate.substring(3, 5);
    if (sMonth.charAt(0) == '0') {
        sMonth = sMonth.charAt(1);
    }
    return parseInt(sMonth);
}
