msie = parseInt((/msie (\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
if (isNaN(msie)) {
  msie = parseInt((/trident\/.*; rv:(\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
}

if (!isNaN(msie)){
    //console.log('is ie');
    $('body').addClass('isie');
}

(function(a){if(typeof define==='function'&&define.amd){define(['jquery'],a)}else if(typeof exports==='object'){module.exports=a(require('jquery'))}else{a(jQuery)}}(function($){if($.support.cors||!$.ajaxTransport||!window.XDomainRequest){return $}var n=/^(https?:)?\/\//i;var o=/^get|post$/i;var p=new RegExp('^(\/\/|'+location.protocol+')','i');$.ajaxTransport('* text html xml json',function(j,k,l){if(!j.crossDomain||!j.async||!o.test(j.type)||!n.test(j.url)||!p.test(j.url)){return}var m=null;return{send:function(f,g){var h='';var i=(k.dataType||'').toLowerCase();m=new XDomainRequest();if(/^\d+$/.test(k.timeout)){m.timeout=k.timeout}m.ontimeout=function(){g(500,'timeout')};m.onload=function(){var a='Content-Length: '+m.responseText.length+'\r\nContent-Type: '+m.contentType;var b={code:200,message:'success'};var c={text:m.responseText};try{if(i==='html'||/text\/html/i.test(m.contentType)){c.html=m.responseText}else if(i==='json'||(i!=='text'&&/\/json/i.test(m.contentType))){try{c.json=$.parseJSON(m.responseText)}catch(e){b.code=500;b.message='parseerror'}}else if(i==='xml'||(i!=='text'&&/\/xml/i.test(m.contentType))){var d=new ActiveXObject('Microsoft.XMLDOM');d.async=false;try{d.loadXML(m.responseText)}catch(e){d=undefined}if(!d||!d.documentElement||d.getElementsByTagName('parsererror').length){b.code=500;b.message='parseerror';throw'Invalid XML: '+m.responseText;}c.xml=d}}catch(parseMessage){throw parseMessage;}finally{g(b.code,b.message,c,a)}};m.onprogress=function(){};m.onerror=function(){g(500,'error',{text:m.responseText})};if(k.data){h=($.type(k.data)==='string')?k.data:$.param(k.data)}m.open(j.type,j.url);m.send(h)},abort:function(){if(m){m.abort()}}}});return $}));


$(document).ready(function () {
    
    $.support.cors = true;
$.ajaxSetup({ cache: false });
    
    $('.s6-locate').click(function(){
       window.location.href = "/find-an-eye-doctor"; 
    });
    
    
    
    
    var blurElement = {a:20};


//here you pass the filter to the DOM element
function applyBlur()
{
    //TweenMax.set(['#s0-title img'], {webkitFilter:"blur(" + blurElement.a + "px)",filter:"blur(" + blurElement.a + "px)"});  
};
    
    
    t1 = new TimelineMax({});
   // t1.to($('#s0-title'),1,{css:{opacity:1,filter:"blur(0)"}, ease:Power1.easeOut});
   // t1.to(blurElement, 1, {a:0, onUpdate:applyBlur, delay:-1});
    t1.to($('#s0-producttxt'),1,{opacity:1, ease:Power1.easeOut, });
    t1.to($('#s0-productimg'),1,{opacity:1, ease:Power1.easeOut, delay:-1});
   
    t1.to($('#s0-desc'),1,{opacity:1, ease:Power1.easeOut, delay:-2});
    
    t3 = new TimelineMax({paused:true});
    
    var mq = window.matchMedia( "(max-width: 1440px)" );
    var mq2 = window.matchMedia( "(max-height:700px) and (min-width: 1000px)" );
    if (mq2.matches) {
  t3.fromTo($('#s2-claritifill'), 3, {
                top: "75%",
                left: "45%",
                width: "10%",
                height: "5%",
                opacity:0
            }, {
                top: "60%",
                left: "36%",
                width: "28%",
                height: "7%",
                opacity:0.2,

                ease: Power1.easeOut,
                delay:1
            });
} else if (mq.matches){
   t3.fromTo($('#s2-claritifill'), 3, {
                top: "69%",
                left: "45%",
                width: "10%",
                height: "5%",
                opacity:0
            }, {
                top: "57%",
                left: "36%",
                width: "28%",
                height: "7%",
                opacity:0.2,

                ease: Power1.easeOut,
                delay:1
            });
    
    
} else {
  t3.fromTo($('#s2-claritifill'), 3, {
                top: "72%",
                left: "41%",
                width: "15%",
                height: "5%",
                opacity:0
            }, {
                top: "59%",
                left: "36%",
                width: "28%",
                height: "10%",
                opacity:0.2,

                ease: Power1.easeOut,
                delay:1
            });
}
            
    t3.fromTo($('#s2-canvas'), 2, {
                bottom: "-100%"
            }, {
                bottom: "0%",
                ease: Power2.easeOut
            });
    
    
    
    
    sunloop = new TweenMax.to($('#s3-sun'), 80, {
        rotation: 360,
        repeat:-1,
        ease:Power0.easeNone
    });
    
    
    
    t4 = new TimelineMax({});
        
    t4.fromTo($('#s3-lens,#s3-shield'),1,{opacity:0},{opacity:1, ease:Power1.easeOut});
/*
    t4.fromTo($('#s3-arrows'), 2, {
        webkitClipPath:'circle(0% at 70% 30%)'
    }, {
        webkitClipPath:'circle(100% at 70% 30%)',
        ease: Power1.easeInOut,
        repeat:-1
    });
    */
    function s4flushani(){
        $('.s4-pimg').finish();
        $('.s4-limg').finish();
        $('#personname').finish();
        $('#persondesc').finish();
    }
    
    function changep1 (){
        $('#s4-personname').html('Jason, 45');
        $('#s4-persondesc').html('看遠看近也模糊不清, 但不想因佩戴眼鏡而影響他那活躍的生活方式');
    }
    function changep2 (){
        $('#s4-personname').html('Emily, 19');
        $('#s4-persondesc').html('隱形眼鏡新用家, 不想因清潔及貯存月戴隱形眼鏡而煩惱');
    }
    function changep3 (){
        $('#s4-personname').html('Eric, 25');
        $('#s4-persondesc').html('有散光, 需長時間對著電腦工作');
    }
    
    t5 = new TimelineMax({paused:true, repeat:-1, repeatDelay:3});
 
    t5.to($('#s4-p1'),0.5, {autoAlpha:0});
    t5.to($('#s4-personname, #s4-persondesc'),0.5, {autoAlpha:0});
    t5.to($('#s4-p2'),0.3, {autoAlpha:1,onUpdate:changep2});
    t5.to($('#s4-personname, #s4-persondesc'),0.3, {autoAlpha:1});
    t5.to($('#s4-l1'),0.3, {autoAlpha:0, delay:-1});
    t5.to($('#s4-l2'),0.3, {autoAlpha:1 });
    
    t5.to($('#s4-p2'),0.5, {autoAlpha:0, delay:3});
    t5.to($('#s4-personname, #s4-persondesc'),0.5, {autoAlpha:0});
    t5.to($('#s4-p3'),0.3, {autoAlpha:1,onUpdate:changep3});
    t5.to($('#s4-personname, #s4-persondesc'),0.3, {autoAlpha:1});
    t5.to($('#s4-l2'),0.3, {autoAlpha:0, delay:-1}); 
    t5.to($('#s4-l3'),0.3, {autoAlpha:1 });
    
    t5.to($('#s4-p3'),0.5, {autoAlpha:0, delay:3});
    t5.to($('#s4-personname, #s4-persondesc'),0.5, {autoAlpha:0});
    t5.to($('#s4-p1'),0.3, {autoAlpha:1,onUpdate:changep1});
    t5.to($('#s4-personname, #s4-persondesc'),0.3, {autoAlpha:1});
    t5.to($('#s4-l3'),0.3, {autoAlpha:0, delay:-1});
    t5.to($('#s4-l1'),0.3, {autoAlpha:1 });
    
    
    
    
    function cleart7(){
        t6.stop();
        t7.stop();
        $('.s5-coins img').css('opacity','0');
        $('.s5-coins img').css('transform','translateY(0)');
    }
    
    t6 = new TimelineMax({paused:true});
    
    t6.to($("#s5-clariti .c1"),0.3,{y: percentToPixel($("#s5-clariti .c1"), 110) + "px",rotation:-20, opacity:1});
    
    t6.to($("#s5-clariti .c2"),0.3,{y: percentToPixel($("#s5-clariti .c2"), 100) + "px",rotation:-20, opacity:1});
    t6.to($("#s5-clariti .c1"),0.1,{rotation:0});
    t6.to($("#s5-clariti .c3"),0.3,{y: percentToPixel($("#s5-clariti .c3"), 90) + "px",rotation:-20, opacity:1});
    t6.to($("#s5-clariti .c2"),0.1,{rotation:0});
    
    t6.to($("#s5-clariti .c4"),0.2,{y: percentToPixel($("#s5-clariti .c4"), 80) + "px",rotation:-20, opacity:1});
    t6.to($("#s5-clariti .c3"),0.1,{rotation:0});
    t6.to($("#s5-clariti .c5"),0.2,{y: percentToPixel($("#s5-clariti .c5"), 70) + "px",rotation:-20, opacity:1});
    t6.to($("#s5-clariti .c4"),0.1,{rotation:0});
    
    t6.to($("#s5-clariti .c6"),0.3,{y: percentToPixel($("#s5-clariti .c6"), 60) + "px",rotation:-20, opacity:1});
    t6.to($("#s5-clariti .c5"),0.1,{rotation:0});
    t6.to($("#s5-clariti .c7"),0.3,{y: percentToPixel($("#s5-clariti .c7"), 50) + "px",rotation:-20, opacity:1});
    t6.to($("#s5-clariti .c6"),0.1,{rotation:0});
    
    t6.to($("#s5-clariti .c7"),0.1,{rotation:0});
    
    
    
    t7 = new TimelineMax({paused:true});
    
    t7.to($("#s5-trad .c1"),0.3,{y: percentToPixel($("#s5-clariti .c1"), 110),rotation:-20, opacity:1});
    
    t7.to($("#s5-trad .c2"),0.3,{y: percentToPixel($("#s5-clariti .c2"), 100),rotation:-20, opacity:1});
    t7.to($("#s5-trad .c1"),0.1,{rotation:0});
    t7.to($("#s5-trad .c3"),0.3,{y: percentToPixel($("#s5-clariti .c3"), 90),rotation:-20, opacity:1});
    t7.to($("#s5-trad .c2"),0.1,{rotation:0});
    
    t7.to($("#s5-trad .c4"),0.2,{y: percentToPixel($("#s5-clariti .c4"), 80),rotation:-20, opacity:1});
    t7.to($("#s5-trad .c3"),0.1,{rotation:0});
    t7.to($("#s5-trad .c5"),0.2,{y: percentToPixel($("#s5-clariti .c5"), 70),rotation:-20, opacity:1});
    t7.to($("#s5-trad .c4"),0.1,{rotation:0});
    
    t7.to($("#s5-trad .c6"),0.3,{y: percentToPixel($("#s5-clariti .c6"), 60),rotation:-20, opacity:1});
    t7.to($("#s5-trad .c5"),0.1,{rotation:0});
    t7.to($("#s5-trad .c7"),0.3,{y: percentToPixel($("#s5-clariti .c7"), 50),rotation:-20, opacity:1});
    t7.to($("#s5-trad .c6"),0.1,{rotation:0});
    
    t7.to($("#s5-trad .c7"),0.1,{rotation:0});
    
    

    $('#fullpage').fullpage({
        'verticalCentered': false,
        'css3': true,
        anchors: ['livevivid', 'breathable', 'water', 'uv', 'needs', 'value','specs'],
    menu: '#animenu',
        //lockAnchors: true,
        //'navigation': false,
        //'navigationPosition': 'right',
       // 'navigationTooltips': ['fullPage.js', 'Powerful', 'Amazing', 'Simple'],
        fixedElements : '.header__wrapper, .main-nav__wrapper ,#menucontainer',
        afterRender: function(){
            /* d7 bugfix */
    $('.fp-slidesContainer > .fp-slides').unwrap();
    $('.fp-slidesContainer > .fp-slidesContainer').unwrap();
    $('.fp-slides > .fp-slides').unwrap();
    
        },
        'afterLoad': function (anchorLink, index) {
            
            if (index == 6) {

                    t6.play(0, true);
                    t7.play(0, true);
            }
            
        },
        'onLeave': function (index, nextIndex, direction) {
            if(nextIndex == 1){
                t1.restart();
                $('#s1-bubbles').finish();
            }
            
          //  TweenMax.to($('.tg'), 3, {css:{clip:"rect(0px, 700px, 190px, 1px);"},ease:Power1.easeOut});
            if (nextIndex == 2) {

            $('#s1-bubbles').fadeIn(5000);
            $('.tg').delay(1000).fadeIn(1000);
            $('#s1-3x').delay(2000).fadeIn(2000);
            }
            if (index == 2) {
                $('#s1-bubbles').finish();
                $('.tg').finish();
                $('#s1-3x').finish();
                $('#s1-bubbles').fadeOut(100);
                $('.tg').fadeOut(100);
                $('#s1-3x').fadeOut(100);
            }
            
            if (nextIndex == 3) {

                t3.kill();
                t3.restart();
            }

            if (nextIndex == 4) {
                t4.play(0, true);
            }
            
            if(nextIndex == 5){
                t5.play(3,true);
                changep2();
            }
            
            if (index == 5){
                t5.stop();
            }
                
            if(index==6){
                cleart7();
                //$('.s5-coins').hide();
            }
            
    }
    });
/*
    for (i = 0; i < 40; i++) {
      //  $('#s1-bubbles').append('<div class="bubble x' + i + '"></div>');

        scale = Math.floor(Math.random() * (5 - 1 + 1)) + 1;
        opacity = Math.floor(Math.random() * (5 - 1 + 1)) + 1;
        xlength = Math.floor(Math.random() * (30 - 3 + 1)) + 3;
        ylength = Math.floor(Math.random() * (9 - 2 + 1)) + 2;
        delay = Math.floor(Math.random() * (12 - 0 + 1)) + 0;

        $('.x' + i).css({
            '-webkit-transform': 'scale(0.' + scale + ')',
            '-moz-transform': 'scale(0.' + scale + ')',
            'transform': 'scale(0.' + scale + ')',
            'opacity': '0.' + opacity,

            '-webkit-animation': 'moveclouds ' + xlength + 's -' + delay + 's linear infinite , sideWays ' + ylength + 's -' + delay + 's ease-in-out infinite alternate',
            '-moz-animation': 'moveclouds ' + xlength + 's -' + delay + 's linear infinite, sideWays ' + ylength + 's -' + delay + 's ease-in-out infinite alternate',
            '-o-animation': 'moveclouds ' + xlength + 's -' + delay + 's linear infinite, sideWays ' + ylength + 's -' + delay + 's ease-in-out infinite alternate'
        });

    }
    
    for (i = 0; i < 10; i++) {
       // $('#s1-bubbles').append('<div class="bubbleo2 y' + i + '"><div class="o2txt"></div></div>');

        scale = Math.floor(Math.random() * (9 - 6 + 1)) + 6;
        opacity = Math.floor(Math.random() * (9 - 3 + 1)) + 3;
        xlength = Math.floor(Math.random() * (30 - 3 + 1)) + 3;
        ylength = Math.floor(Math.random() * (9 - 2 + 1)) + 2;
        delay = Math.floor(Math.random() * (12 - 0 + 1)) + 0;
/*
        $('.y' + i).css({
            '-webkit-transform': 'scale(0.' + scale + ')',
            '-moz-transform': 'scale(0.' + scale + ')',
            'transform': 'scale(0.' + scale + ')',
            'opacity': '0.' + opacity,

            '-webkit-animation': 'moveclouds ' + xlength + 's -' + delay + 's linear infinite , sideWays ' + ylength + 's -' + delay + 's ease-in-out infinite alternate',
            '-moz-animation': 'moveclouds ' + xlength + 's -' + delay + 's linear infinite, sideWays ' + ylength + 's -' + delay + 's ease-in-out infinite alternate',
            '-o-animation': 'moveclouds ' + xlength + 's -' + delay + 's linear infinite, sideWays ' + ylength + 's -' + delay + 's ease-in-out infinite alternate'
        });

    }
*/
});


var density = 30, density2 = 10,
		speed = 1,
		winWidth = $(window).width(),
		start = {xMin:-180, xMax:-180, yMin:50, yMax:150, scaleMin:0.1, scaleMax:0.25, opacityMin:0.1, opacityMax:0.6},
		mid = {xMin:winWidth * 0.3, xMax:winWidth * 0.5, yMin:75, yMax:400, scaleMin:0.2, scaleMax:0.7, opacityMin:0.2, opacityMax:0.6},
		end = {xMin:winWidth + 50, xMax:winWidth + 50, yMin:20, yMax:600, scaleMin:0.1, scaleMax:0.5, opacityMin:0.1, opacityMax:0.4};
        
        mid2 = {xMin:winWidth * 0.3, xMax:winWidth * 0.5, yMin:75, yMax:400, scaleMin:0.5, scaleMax:1, opacityMin:0.4, opacityMax:0.8},
		end2 = {xMin:winWidth + 50, xMax:winWidth + 50, yMin:20, yMax:600, scaleMin:0.5, scaleMax:1, opacityMin:0.3, opacityMax:0.6};

	function range(map, prop) {
		var min = map[prop + "Min"],
			max = map[prop + "Max"];
		return min + (max - min) * Math.random();
	}

	function spawn(particle, type) {
		var wholeDuration = (10 / speed) * (0.7 + Math.random() * 0.4),
			delay = wholeDuration * Math.random(),
			partialDuration = (wholeDuration + 1) * (0.3 + Math.random() * 0.4);

		//set the starting values
		TweenLite.set(particle, {x:range(start, "x"), y:range(start, "y"), scale:range(start, "scale"), opacity:range(start, "opacity")/*, visibility:"hidden"*/});

		//the y tween should be continuous and smooth the whole duration
		TweenLite.to(particle, wholeDuration, {delay:delay, x:range(end, "x"), ease:Linear.easeNone});

		//now tween the x independently so that it looks more randomized (rather than linking it with scale/opacity changes too)
		TweenLite.to(particle, partialDuration, {delay:delay, y:range(mid, "y"), ease:Power1.easeOut});
		TweenLite.to(particle, wholeDuration - partialDuration, {delay:partialDuration + delay, y:range(end, "y"), ease:Power1.easeIn});
                
                if(type==1){
		//now create some random scale and opacity changes
		partialDuration = wholeDuration * (0.5 + Math.random() * 0.3);
		TweenLite.to(particle, partialDuration, {delay:delay, scale:range(mid, "scale")/*, autoAlpha:range(mid, "opacity")*/, ease:Linear.easeNone});
		TweenLite.to(particle, wholeDuration - partialDuration, {delay:partialDuration + delay, scale:range(end, "scale")/*, autoAlpha:range(end, "opacity")*/, ease:Linear.easeNone, onComplete:spawn, onCompleteParams:[particle,1]});
            }else if(type==2) {
               partialDuration = wholeDuration * (0.5 + Math.random() * 0.3);
		TweenLite.to(particle, partialDuration, {delay:delay, scale:range(mid2, "scale"),/* autoAlpha:range(mid2, "opacity"),*/ ease:Linear.easeNone});
		TweenLite.to(particle, wholeDuration - partialDuration, {delay:partialDuration + delay, scale:range(end2, "scale")/*, autoAlpha:range(end2, "opacity")*/, ease:Linear.easeNone, onComplete:spawn, onCompleteParams:[particle,2]}); 
            }
	}

	$(window).ready(function() {
		var body = $("#s1-bubbles"),
			i, particle;
		for (i = 0; i < density; i++) {
			spawn( $("<div />", {id:"particle"+i}).addClass("bubble").appendTo(body),1);
		}
                for (i = 0; i < density2; i++) {
			spawn( $("<div />", {id:"particle"+i}).addClass("bubbleo2").appendTo(body) , 2);
		}
                $('.bubbleo2').html('<div class="o2txt"></div>');
	});


function gcd (a, b) {
            return (b == 0) ? a : gcd (b, a%b);
        }
        var w = $(window).width();
        var h = $(window).height();
        var r = gcd (w, h);
        console.log ("Dimensions = ", w, " x ", h, "<br>");
        console.log ("Gcd        = ", r, "<br>");
        console.log ("Aspect     = ", w/r, ":", h/r);



$(document).ready(function () {
    
    raw = '';
    districtlist = '';

   $.ajax({
        url: "http://apps.webpuppies.com.sg/coopervision/cvhk/clariti/getarray.php",
        type: "get",
        //contentType: "text/plain; charset=utf-8",
        crossDomain: true,
        dataType: "json",
        success: function (data) {
            raw = data;
            districtlist = _.chain(data).map(function(s) { return s.district }).uniq().value();
            
            //construct option string
            optionstr = '<option value="" selected disabled>請選地區</option>';
            for (var i = 0; i < districtlist.length; i++) {

                optionstr += ("<option value='" + districtlist[i] + "' >" + districtlist[i] + "</option>");
            }
            
            $('#regarea').html(optionstr);
            $('#regarea').prop('disabled', false);
            
        },
        error: function () {
            console.log('ajax error');
           // alert('Error. Please try again.');
        }
    }); 
    
    
    $('#regarea').change(function(){
         
        shoplist = _.where(raw, {district: $(this).val()});
        $("#regshop").prop('disabled', false);
    


        //construct option string
            optionstr = '<option value="" disabled selected>請選專業試戴中心</option>';
            for (var i = 0; i < shoplist.length; i++) {

                optionstr += ("<option value='" + shoplist[i]['id'] + "' >" + shoplist[i]['name'] + "</option>");
            }

            $('#regshop').html(optionstr);
        
        
    });
    
    $('#regshop').change(function(){   

            address = _.where(raw, {id: $(this).val()});
            
            $('#addressarea').html(address[0]['address']);
        
        
    });
    
    /*
    jQuery('#hkregform').parsley().on('form:error', function() {
        
        jQuery.featherlight($('#regerrors'));
    });
    
    */
    
    
});






function percentToPixel(_elem, _perc){
  return (_elem.parent().outerWidth()/100)* parseFloat(_perc);
}



$(document).ready(function () {
    //s2 wave

    var canvas = document.getElementById("s2-canvas");
    var size = {
        width: window.innerWidth,
        height: window.innerHeight
    };

    /*
     * CONFIG
     */

    var options = {
        color: "#dcf0f1",
        waveAmplitude: 50,
        waveRadius: 200,
        waveElasticity: 0.95,
        waveStrength: 0.011,
        waveMouse: 50,
        waveMax: 100,
        waveComeUp: function () {},
        waveRiseSpeed: 15,
        lineWidth: 25,
        waveLength: 100
    };

    /*
     * UTILITIES
     */

    function times(amount, closure) {
        for (var i = 0; i < amount; i++) {
            closure(i);
        }
    }

    function func(name) {
        return function (obj) {
            return obj[name]();
        };
    }


    function rand(min, max) {
        return min + (max - min) * Math.random();
    }

    function bezier(points, context) {

        var a, b, x, y;

        for (var i = 1, length = points.length - 2; i < length; i++) {

            a = points[i];
            b = points[i + 1];

            x = (a.x + b.x) * 0.5;
            y = (a.y + b.y) * 0.5;

            context.quadraticCurveTo(a.x, a.y, x, y);
        }

        a = points[i];
        b = points[i + 1];

        context.quadraticCurveTo(a.x, a.y, b.x, b.y);
    }

    function distance(a, b) {
        var x = b.x - a.x;
        var y = b.y - a.y;

        return Math.sqrt(x * x + y * y);
    }

    function clamp(val, min, max) {
        return val < min ? min : (val > max ? max : val);
    }

    /*
     * GLOBAL CLASSES
     */

    var Mouse = (function () {

        var exports = {
            x: 0,
            y: 0,
            bind: function (canvas) {
                canvas.addEventListener("mousemove", onMouseMove);
                canvas.addEventListener("touchmove", onTouchMove);
            },
            unbind: function (canvas) {
                canvas.removeEventListener("mousemove", onMouseMove);
                canvas.removeEventListener("touchmove", onTouchMove);
            }
        };

        function onMouseMove(event) {
            exports.x = event.pageX;
            exports.y = event.pageY;
        }

        function onTouchMove(event) {
            event.preventDefault();

            exports.x = event.touches[0].pageX;
            exports.y = event.touches[0].pageY;
        }

        return exports;

    })();

    var Stage = {
        width: 1,
        height: 1,
        set: function (values) {
            Stage.width = values.width;
            Stage.height = values.height;
        }
    };

    /*
     * ARCHITECTURE CLASSES
     */

    var Water = function (context) {

        var waves;

        function init() {
            options.waveComeUp = this.start.bind(this);
        }

        this.render = function () {
            context.strokeStyle = options.color;
            context.lineWidth = options.lineWidth;
            context.lineCap = "round";
            context.beginPath();

            waves.forEach(func("render"));

            context.stroke();
        };

        this.setSize = function (width, height) {

            createWaves(height);

            waves.forEach(function (wave) {
                wave.setSize(width, height);
            });

        };

        this.start = function () {
            waves.forEach(func("start"));
        };

        function createWaves(height) {

            waves = [];
            var distance = 50;

            times(height / distance, function (index) {
                waves.push(new Wave(0, index * distance + 10, context, rand(0.08, 0.12) * index));
            });

        }

        init.call(this);

    };

    var Wave = function (originalX, originalY, context, offset) {

        var anchors;
        var width;
        var height;
        var mouseDirection;
        var oldMouse;
        var x;
        var y;

        function init() {
            x = originalX;
            y = originalY;

            anchors = [];
            mouseDirection = {
                x: 0,
                y: 0
            };

            var anchor;
            var current = 0;
            var start = -options.waveAmplitude;
            var target = options.waveAmplitude;
            var delta = offset;
            var step = 0.4;

            times(window.innerWidth / options.waveLength, function () {
                anchor = new Anchor(current, 0, start, target, delta);
                anchor.setOrigin(current + x, y);

                anchors.push(anchor);

                current += 90;
                delta += step;

                if (delta > 1) {
                    times(Math.floor(delta), function () {
                        delta--;
                        start *= -1;
                        target *= -1;
                    });
                }

            });
        }

        this.render = function () {

            update();

            context.save();
            context.translate(x, y);

            context.moveTo(anchors[0].x, anchors[0].y);
            bezier(anchors, context);

            context.restore();
        };

        this.setSize = function (_width, _height) {
            width = _width;
            height = _height;

            var step = _width / (anchors.length - 1);

            anchors.forEach(function (anchor, i) {
                anchor.x = step * i;
                anchor.setOrigin(anchor.x, y);
            });
        };

        this.onAmpChange = function () {
            anchors.forEach(func("onAmpChange"));
        };

        this.start = function () {
            y = height + 300 + originalY * 0.4;
        };

        function update() {
            var targetY = Math.min(y, Mouse.y + originalY);
            y += (targetY - y) / options.waveRiseSpeed;

            updateMouse();

            anchors.forEach(function (anchor) {
                anchor.update(mouseDirection, y);
            });
        }

        function updateMouse() {
            if (!oldMouse) {
                oldMouse = {
                    x: Mouse.x,
                    y: Mouse.y
                };
                return;
            }

            mouseDirection.x = Mouse.x - oldMouse.x;
            mouseDirection.y = Mouse.y - oldMouse.y;

            oldMouse = {
                x: Mouse.x,
                y: Mouse.y
            };
        }

        init.call(this);

    };

    var Anchor = function (x, y, start, target, delta) {

        var spring;
        var motion;
        var origin;

        function init() {
            spring = new Spring();
            motion = new Motion(start, target, delta);
            origin = {};
            this.x = x;
            this.y = y;
        }

        this.update = function (mouseDirection, currentY) {
            origin.y = currentY;

            var factor = getMultiplier();
            var vector = {
                x: mouseDirection.x * factor * options.waveMouse,
                y: mouseDirection.y * factor * options.waveMouse
            };

            if (factor > 0) {
                spring.shoot(vector);
            }

            spring.update();
            motion.update();

            this.y = motion.get() + spring.y;
        };

        this.onAmpChange = function () {
            motion.onAmpChange();
        };

        this.setOrigin = function (x, y) {
            origin.x = x;
            origin.y = y;
        };


        function getMultiplier() {
            var lang = distance(Mouse, origin);
            var radius = options.waveRadius;

            return lang < radius ? 1 - lang / radius : 0;
        }

        init.call(this);

    };

    var Motion = function (start, target, delta) {

        var SPEED = 0.02;
        var half;
        var upper;
        var lower;
        var min;
        var max;

        function init() {
            this.onAmpChange();
        }


        this.setRange = function (a, b) {
            min = a;
            max = b;
        };

        this.update = function () {
            delta += SPEED;

            if (delta > 1) {
                delta = 0;
                start = target;
                target = target < half ? rand(upper, max) : rand(min, lower);
            }
        };

        this.get = function () {
            var factor = (Math.cos((1 + delta) * Math.PI) + 1) / 2;
            return start + factor * (target - start);
        };

        this.onAmpChange = function () {
            min = -options.waveAmplitude;
            max = options.waveAmplitude;
            half = min + (max - min) / 2;
            upper = min + (max - min) * 0.75;
            lower = min + (max - min) * 0.25;
        };


        init.call(this);

    };

    var Spring = function () {

        var px = 0;
        var py = 0;
        var vx = 0;
        var vy = 0;
        var targetX = 0;
        var targetY = 0;
        var timeout;

        function init() {
            this.x = 0;
            this.y = 0;
        }

        this.update = function () {
            vx = targetX - this.x;
            vy = targetY - this.y;
            px = px * options.waveElasticity + vx * options.waveStrength;
            py = py * options.waveElasticity + vy * options.waveStrength;
            this.x += px;
            this.y += py;
        };

        this.shoot = function (vector) {
            targetX = clamp(vector.x, -options.waveMax, options.waveMax);
            targetY = clamp(vector.y, -options.waveMax, options.waveMax);

            clearTimeout(timeout);
            timeout = setTimeout(cancelOffset, 100);
        };

        function cancelOffset() {
            targetX = 0;
            targetY = 0;
        }

        init.call(this);
    };

    var Canvas = function (canvas, size) {

        var context;
        var width, height;
        var animation;

        function init() {

            context = canvas.getContext("2d");

            setTimeout(function () {
                Mouse.bind(canvas);
            }, 1000);

            Stage.set(size);

            animation = new Water(context);

            this.setSize(size.width, size.height);

            animation.start();

            requestAnimationFrame(render);
        }

        function render() {
            context.setTransform(1, 0, 0, 1, 0, 0);
            context.clearRect(0, 0, width, height);

            context.save();
            animation.render();
            context.restore();

            requestAnimationFrame(render);
        }

        this.setSize = function (_width, _height) {

            canvas.width = Stage.width = width = _width;
            canvas.height = Stage.height = height = _height;

            animation.setSize(_width, _height);
        };

        init.call(this);
    };

    /*
     * START
     */

    var app = new Canvas(canvas, size);

    window.addEventListener("resize", function () {
        app.setSize(window.innerWidth, window.innerHeight);
    }, false);


});


(function() {
    var lastTime = 0;
    var vendors = ['webkit', 'moz'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame =
          window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());


