/*var text = document.querySelector('.result');

// var student  = {
//     name : 'Rick',
//     gender : 'Male',
//     dob : 1987,
//     occupation: 'instructor'
// };

var Person = function (name,gender,dob,occupation,experience){

    this.name = name;
    this.gender = gender;
    this.dob = dob;
    this.occupation = occupation;
    this.experience = experience;

    // this.yourSkills = function(){
    //     if(this.experience >= 0){
    //         if(this.experience >= 5){
    //             console.log('Congratulations you are Senior Developer');
    //         }
    //         else{
    //             console.log('Congratulations you are Mid-Level or Junior Developer')
    //         }
    //     }
    //     else{
    //         console.log('No Negative Values Please');
    //     }
    // }

}
Person.prototype.country = 'USA';
Person.prototype.yourSkills =  function(){
        if(this.experience >= 0){
            if(this.experience >= 5){
                console.log('Congratulations you are Senior Developer');
                text.innerHTML  += 'Congratulations you are Senior Developer <br>';
            }
            else{
                console.log('Congratulations you are Mid-Level or Junior Developer');
                text.innerHTML  += 'Congratulations you are Mid-Level or Junior Developer <br>';
            }
        }
        else{
            console.log('No Negative Values Please');
            text.innerHTML  += 'No Negative Values Please <br>';
        }
    }



var student = new Person ('Rick','Male', 1987, 'instructor',2);
var employee = new Person ('David','Male', 1992, 'developer',5);
var teacher = new Person ('Nora','Female', 1990, 'teacher',3);
// console.log(student.name);
// console.log(student.experience);
student.yourSkills();
employee.yourSkills();
teacher.yourSkills();
console.log(student.country);
console.log(employee.country);
console.log(teacher.country);


*/
/* -----------------Object Create Method ---------------------------- */

//1 Prototype
/*
var personCreate = {

    yourSkills:function(){
        if(this.experience >= 0){
            if(this.experience >= 5){
                console.log('Congratulations you are Senior Developer');
               
            }
            else{
                console.log('Congratulations you are Mid-Level or Junior Developer');
               
            }
        }
        else{
            console.log('No Negative Values Please');
            
        }
        
    }
};

var student = Object.create(personCreate);

student.name = 'Samuel';
student.lastName = 'Jackson';
student.dob = 1959;
student.experience = -1;


var teacher = Object.create(personCreate,
    {
        name: {value:'Tom'},
        lastName: {value:'Cruise'},
        dob: {value:1959},
        experience: {value:3},

    });


console.log(student);
console.log(teacher);
*/


/*---------- This Keyword plus Constructor ---------------*/
/*
//global scope 

var Person = function(name, age){
 
    //local scope
    this.name = name;
    this.age = age;
    // console.log(this);
}

//use this keyword globally 
console.log(this);
this.alert('This keyword is coming from the global scope');

//three instances
var rick = new Person('Rick',20);
var sam = new Person('Sam',35);
var andy = new Person('Andy',43);

// console.log(rick);
// console.log(sam);
*/



/*---------- Built In JS constructors ---------------*/
/*
//String
var string = 'Rick';
var stringObj = new String('Sam');
console.log('String Built In Constructor');
console.log(string);
console.log(stringObj);

console.log(typeof(string));
console.log(typeof(stringObj));

if(string ==='Rick'){
    console.log('Yes the name is Rick');
}
else{
    console.log('No the name is not equal Rick');
}

if(stringObj ==='Sam'){
    console.log('Yes the name is Sam');
}
else{
    console.log('No the name is not equal to Sam ');
}

if(stringObj =='Sam'){
    console.log('Yes the name is Sam');
}
else{
    console.log('No the name is not equal to Sam ');
}

console.log('Boolean Built In Constructor');

var bool = true;

var boolObj = new Boolean(true);

console.log(bool);
console.log(boolObj);

console.log(typeof(bool));
console.log(typeof(boolObj));


//Number
var num = 10;

var numObj = new Number(10);

console.log(num);
console.log(numObj);

console.log(typeof(num));
console.log(typeof(numObj));
*/
/*---------- First Class Functions ---------------*/

/*
1. Everything in Js is considered as Object so Functions are Objects and they 
behave like that
2. In order functions to be an Object, the function must be or is an instance of the Object Type
3. We can pass function as an argument to another function
4. We can store the functions and its result in a variable
Ex: var result = myTest();
5. We can return a function from inside another function
*/
/*
console.log('Calculate the Age from our Current Year:2020');
var ageArray = [2005,1987,2013,2000,1999,2007];
// console.log(ageArray);

function initialFunction(array, func){
    var valuesArray =[];
    for(var i = 0; i< ageArray.length; i++){
        valuesArray.push(func(array[i]));
    }

    return valuesArray;
}

function callBackFunction(item){
    //console.log(item);
return 2020 - item;

}

var result1 = initialFunction(ageArray,callBackFunction);
console.log(result1);


//Example 2
console.log('Calculate the max value from two arrays');

var array1 = [155,788,33,187,556];
var array2 = [205,77,65,188,505];
//result array3 = [205,788,65,188,556];


function functionOne(arr1,arr2,func){
    var array3 = [];
    for(var i = 0; i< arr1.length; i++){
        array3.push(func(arr1[i],arr2[i]));
    }

    return array3; 
}

function functionTwo(item1, item2){
    if(item1>= item2){
        return item1;
    }
    else{
        return item2;
    }
}

var result2 = functionOne(array1,array2,functionTwo);
console.log(result2);

//Example 3
console.log('Calculate the Age From Array of Birthday strings, With Date Function');
var dob = ['10-8-2005','9-29-1987','04-02-1995','05-25-1959','05-18-2000'];

function firstDateFunction(array, func){

    var resultArray = [];
    for(var i = 0; i< array.length; i++){
        resultArray.push(func(array[i]));
    }
    return resultArray;
}

function calculateAge(item){
    //console.log(item);
    var today = new Date();
    var birthday = new Date(item);
    // console.log(today);
    // console.log(birthday);

    var age = today.getFullYear() - birthday.getFullYear();
    return age;
}

var result3 = firstDateFunction(dob,calculateAge);
console.log(result3);
*/

/*---------- Functions that Return Functions They are Called Returning Functions---------------*/
/*

function whereDoYouLive(place){

  
    if(place ==='Melbourne'){
        return function(yourName){
            console.log('My Name Is: '+yourName+ ' and i live in '+ place);
        }
    }
    else if(place ==='California'){
        return function(yourName){
            console.log('In What Suburb of: '+place+ ' do you live in '+ yourName +' ?');
        }
    }
    else{
        return function(yourName){
            console.log('Can you please: '+yourName+ ' tell me what is interesting in your city?');
        }
    }
}

var whereAreYouFrom = whereDoYouLive('Melbourne');
whereAreYouFrom('Rick');

var whereAreYouFrom1 = whereDoYouLive('California');
whereAreYouFrom1('Sam');

var whereAreYouFrom2 = whereDoYouLive('Brazil');
whereAreYouFrom2('Jackson');

//
whereDoYouLive('California')('Nora');
*/

/****************Immediately Invoked Function Expression IIFE **********************/
/*
(function (){
    
    var random = Math.random()*10;
    console.log(random);
})();

(function (name){
    
    console.log('Hi there Mr ' + name);
})('Rick');


(function(number){
    var random = Math.random()*10;
    var roundNum = Math.round(random);
    if(roundNum >= number){
       var result = roundNum - number;
        console.log('The result is ' + result + ' ; Solution:' + roundNum + ' - ' +number + ' = ' +result);
    }
    else{
        console.log('The round number is ' + roundNum + ' Because the number passed from the function is bigger than the round number := ' + roundNum + ' < '+ number);
    }
})(5);

*/
/****************Closures **********************/

//its difficult to understand closures so this is a very important lecture
/*
Simple Definition for Closure Functions
    The Inner function that is nested inside another function have access to the variables and 
    parameters of its outer function, even if the outer function has returned and finished its cycle.

    Further Explanation:
    This is because the variable object is in memory from
    the first function therefore the scope chain will stay intact and that
    means the variables and parameters from the first function will still be accessible
    long after the first function completed its execution. That means the execution context of
    the first function is gone. In short the Scope Chain stays intact.
    
    *****Closure Functions is not done by us but by the JavaScript*****
    Closure functions can be reused many times
    
*/
/*
 function daysToBirthday(yourBirthday, name){
     //parameters of outer function
     var prefix,suffix;
     prefix = 'Wow! ';
     suffix =' days you have until your birthday!';

    return function(todaysDate){
        //set start date
        var startDate = todaysDate;
        //set end date
        var endDate = yourBirthday;
        //calculate the difference
        var timeDiff = (new Date(endDate)) - (new Date(startDate));
        //convert the milliseconds to days
        //var days = timeDiff / (1000*60*60*24);
        //Math.round
        var days = Math.round(timeDiff / (1000*60*60*24));
        console.log(prefix + name + ' , ' + days + suffix);
    }
 }

 var birthdayRick = daysToBirthday('09/29/2020','Rick');//mm/dd/yyyy
 birthdayRick('06/25/2020');

 var birthdaySam = daysToBirthday('12/25/2020','Sam');//mm/dd/yyyy
 birthdaySam('06/25/2020');
*/

/******************  Call , Apply and Bind Methods *********************/

/*These methods allow us to call a function and set 'this' keyword manually' */

var andrew = {
    name: 'Andrew',
    lastName : 'Marin',
    dob : 1987,
    occupation : 'banker',

    calculateAge : function(greeting, timeOfDay){
        var today = new Date();
        var currentYear = today.getFullYear();
        //the actual age
        var age = currentYear - this.dob;
        //formal greeting
        if(greeting ==='formal' && timeOfDay ==='morning'){
            console.log(
                'Good Morning ' + this.name +
                ', I have few details about , so you\'re ' + age +
                ' old, your last name is '+ this.lastName +
                ' and you\'re ' + this.occupation
            );
        }
        else if(greeting ==='formal' && timeOfDay ==='afternoon'){
            console.log(
                'Good Afternoon ' + this.name +
                ', I have few details about , so you\'re ' + age +
                ' old, your last name is '+ this.lastName +
                ' and you\'re ' + this.occupation
            );
        }

        //informal greeting
        if(greeting ==='informal' && timeOfDay ==='morning'){
            console.log(
                ' Hey Good Morning ' + this.name +
                ' , can you please check if these details matches you! Age: ' + age +
                ' Last Name: '+ this.lastName +
                ' and you\'re ' + this.occupation
            );
        }
        else if(greeting ==='informal' && timeOfDay ==='afternoon'){
            console.log(
                ' Hey Good afternoon ' + this.name +
                ' , can you please check if these details matches you! Age: ' + age +
                ' Last Name: '+ this.lastName +
                ' and you\'re ' + this.occupation
            );
        }
    }
}


console.log('Printing out Andrew Details');
andrew.calculateAge('formal','morning');

//elisabeth
var elisabeth = {
    name: 'Elisabeth',
    lastName : 'Moss',
    dob : 1982,
    occupation : 'actress'
}
//call method
console.log('Call Method for Elisabeth');
andrew.calculateAge.call(elisabeth,'informal','afternoon');
//apply method the arguments must be an array

// andrew.calculateAge.apply(elisabeth,['informal','afternoon']);

//bind method, allows you to preset parameters
console.log('Bind Method for Andrew');
var andrewBinding  = andrew.calculateAge.bind(andrew,'formal');
andrewBinding('morning');
andrewBinding('afternoon');

//bind method, allows you to preset parameters
console.log('Bind Method for Elisabeth');
var elisabethBinding  = andrew.calculateAge.bind(elisabeth,'informal');
elisabethBinding('morning');
elisabethBinding('afternoon');