// Arrow to Functions
// Переведите любые пять заданий из предыдущего ДЗ по функциям в синтаксис function
arrow_to_functions: {
  function rgb(r, g, b) {
    let color = '#' + (r > 15 ? r.toString(16) : '0' + r.toString(16)) +
      (g > 15 ? g.toString(16) : '0' + g.toString(16)) +
      (b > 15 ? b.toString(16) : '0' + b.toString(16));
    return color;
  }
  console.log(rgb(5, 5, 5));
  console.log(rgb(13, 35, 456));

  function apartmentSearch(numberOfFloors, numberOfApartmentsOnFloor, apartmentNumber) {
    let apartmentLocation = {
      entrance: null,
      floor: null,
    }
    apartmentLocation.entrance = Math.ceil(apartmentNumber / (numberOfFloors * numberOfApartmentsOnFloor));
    apartmentLocation.floor = Math.ceil(apartmentNumber % (numberOfFloors * numberOfApartmentsOnFloor) /
      numberOfApartmentsOnFloor) || numberOfFloors;
    return apartmentLocation;
  }
  console.log(apartmentSearch(9, 4, 81));

  function capitalize(str) {
    let result = str.trim().slice(0, 1).toUpperCase() + str.trim().slice(1).toLowerCase();
    return result;
  }

  function credentials() {
    let person = {}
    person.name = capitalize(prompt('What is your name?'));
    person.surname = capitalize(prompt('What is your surname?'));
    person.fatherName = capitalize(prompt('What is your middle name?'));
    person.fullName = person.surname + ' ' + person.name + ' ' + person.fatherName;
    return person;
  }
  credentials();

  function newLine(str) {
    let result = str.split('\\n').join('\n');
    return result;
  }
  alert(newLine(prompt("Enter the string. As a newline marker use '\\n'")));

  function promptOr(str, defaultValue) {
    prompt(str) || defaultValue;
  }
  alert(promptOr('Enter something', 'error'));
}

// createPerson
// Создайте функцию createPerson, которая принимает два параметра: name и surname, и возвращает объект с
// ключами name, surname, getFullName. getFullName должна быть функцией, которая работает с объектом через this,
// а так же готова к тому, что в объекте в последствии добавить ключ fatherName
create_person: {
  function createPerson(name, surname) {
    let obj = {
      name,
      surname,
      getFullName() {
        let fullName = this.fatherName ? this.name + ' ' + this.fatherName + ' ' + this.surname
          : this.name + ' ' + this.surname;
        return fullName;
      },
    }
    return obj;
  }

  const a = createPerson("Вася", "Пупкин")
  const b = createPerson("Анна", "Иванова")
  const c = createPerson("Елизавета", "Петрова")


  a.fatherName = 'Иванович'    //Вася Иванович Пупкин
  console.log(a.getFullName()) //Вася Пупкин

  console.log(b.getFullName()) //Анна Иванова
}

// createPersonClosure
// Задание в целом, аналогично предыдущему, однако, в объект заносить name, surname, fatherName и age не нужно.
// name и surname должны быть параметрами, переменные age и fatherName объявите через let в теле
// createPersonClosure. Внутри createPersonClosure объявите следующие функции:
// getName
// getSurname
// getFatherName
// getAge
// getFullName
// Эти функции должны возвращать переменные, объявленные в функции createPersonClosure
// Следующие функции:
// setName
// setSurname
// setFatherName
// setAge
// setFullName
// должны принимать один параметр (newName, newSurname и т.п.), проверять его на корректность и менять значение
// переменных, объявленных внутри createPersonClosure.Проверки на корректность:
// имя, фамилия, отчество должно быть строкой с большой буквы
// возраст должен быть числом от 0 до 100.
// Если проверка на корректность не пройдена, функция не должна менять соответстующую переменную.
// Функция setFullName должна разбивать строку по пробелам и заносить части строки в surname, name и fatherName
// Все функции set должны возвращать то значение, которое по итогу попало во внутренюю переменную. То есть если
// новое значение некорректно, то функция возвращает старое значение
// В объекте-результате createPersonClosure должны быть только эти 10 функций (геттеров и сеттеров). В коде
// функций this не используется
create_person_closure: {
  function createPersonClosure(name, surname) {
    let age;
    let fatherName;
    let obj = {
      getName() {
        return name;
      },
      getSurname() {
        return surname;
      },
      getFatherName() {
        return fatherName;
      },
      getAge() {
        return age;
      },
      getFullName() {
        return surname + ' ' + name + ' ' + fatherName;
      },
      setName(newName) {
        if (validateName(newName)) {
          name = newName;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
      },
      setSurname(newSurname) {
        if (validateName(newSurname)) {
          surname = newSurname;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
      },
      setFatherName(newFatherName) {
        if (validateName(newFatherName)) {
          fatherName = newFatherName;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
      },
      setFullName(str) {
        surname = str.split(' ')[0];
        name = str.split(' ')[1];
        fatherName = str.split(' ')[2];
      },
      setAge(newAge) {
        if (newAge >= 0 && newAge <= 100 || newAge == '') {
          age = newAge;
        } else {
          alert('ERROR');
        }
      },
    }

    function validateName(name) {
      return name.charCodeAt(0) >= 65 && name.charCodeAt(0) <= 90 ||
        name.charCodeAt(0) >= 1040 && name.charCodeAt(0) <= 1071 || name == '';
    }

    return obj;
  }

  const a = createPersonClosure("Вася", "Пупкин");
  const b = createPersonClosure("Анна", "Иванова");
  console.log(a.getName());
  console.log(a.setAge(15));
  //a.setAge(150); //не работает
  a.setSurname('Варченко');
  a.setFatherName('Александрович');
  console.log(a.getSurname());
  console.log(a.getFullName());
  b.setFullName("Петрова Анна Николаевна");
  console.log(b.getFatherName()); //Николаевна
}

// createPersonClosureDestruct
// Сделайте набор параметров функции из предыдущего задания объектом, используйте деструктуризацию для
// извлечения параметров.
// Задайте значения по умолчанию
create_person_closure_destruct: {
  function createPersonClosureDestruct(object) {
    let { name = '', surname = '', fatherName = '', age = 0 } = object;
    let obj = {
      getName() {
        return name;
      },
      getSurname() {
        return surname;
      },
      getFatherName() {
        return fatherName;
      },
      getAge() {
        return age;
      },
      getFullName() {
        return surname + ' ' + name + ' ' + fatherName;
      },
      setName(newName) {
        if (validateName(newName)) {
          name = newName;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
      },
      setSurname(newSurname) {
        if (validateName(newSurname)) {
          surname = newSurname;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
      },
      setFatherName(newFatherName) {
        if (validateName(newFatherName)) {
          fatherName = newFatherName;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
      },
      setFullName(str) {
        surname = str.split(' ')[0];
        name = str.split(' ')[1];
        fatherName = str.split(' ')[2];
      },
      setAge(newAge) {
        if (newAge >= 0 && newAge <= 100 || newAge == '') {
          age = newAge;
        } else {
          alert('ERROR');
        }
      },
    }

    function validateName(name) {
      return name.charCodeAt(0) >= 65 && name.charCodeAt(0) <= 90 ||
        name.charCodeAt(0) >= 1040 && name.charCodeAt(0) <= 1071 || name == '';
    }

    return obj;

  }
  function createPerson(name, surname) {
    let obj = {
      name,
      surname,
      getFullName() {
        let fullName = this.fatherName ? this.name + ' ' + this.fatherName + ' ' + this.surname
          : this.name + ' ' + this.surname;
        return fullName;
      },
    }
    return obj;
  }

  const a = createPersonClosureDestruct(createPerson("Вася Пупкин")); // в самом задании выше нам было сказано записать в createPerson 2 параметра, тут же передается строка. Соответсвенно нужно либо переписать функцию createPerson, чтобы она разбивала строку, либо передавать через запятую имя и фамилию
  const b = createPersonClosureDestruct({ name: 'Николай', age: 75 });
  console.log(a.getName());
  console.log(a.getAge());
  console.log(b.getSurname());
}

// isSorted
// Напишите функцию isSorted, которая принимает набор параметров любого размера, и возвращает true, когда все
// параметры - это числа, и каждое из них больше предыдущего параметра.
is_sorted: {
  function isSorted(...params) {
    let result = true;
    for (let i = 0; i < params.length; i++) {
      if (typeof params[i] != 'number' || params[i] > params[i + 1] && params[i + 1] != undefined) {
        result = false;
      }
    }
    return result;
  }

  console.log(isSorted(1, 0, 3, 56, 234, 56, 2, 8, 76));
  console.log(isSorted(1, 2, 3, 5));
  console.log(isSorted(1, 'jrfnejrkfn', 3, 4, 5));
  console.log(isSorted(1));
}

// Test isSorted
// Используя циклический ввод в массив (задание array fill), обеспечьте ввод данных для isSorted
test_is_sorted: {
  let arr = [];
  let answer;
  while (answer = prompt('Enter something')) {
    arr.push(+answer);
  }
  function isSorted(arr) {
    console.log(arr);
    let result = true;
    for (let i = 0; i < arr.length; i++) {
      if (typeof arr[i] != 'number' || arr[i] > arr[i + 1] && arr[i + 1] != undefined) {
        result = false;
      }
    }
    return result;
  }
  console.log(isSorted(arr));
}

// personForm
// Напишите функцию, которая принимает два параметра: родительский DOM-элемент и объект-результат работы
// createPersonClosure (или createPersonClosureDestruct, результаты у обоих этих функций одинаковые) и рисует
// форму, которая позволяет редактировать данные о персоне.
// В начале работы personForm создает 5 полей ввода (имя, фамилия, отчество, возраст, ФИО) в родительском
// DOM-элементе и устанавливает туда значения, прочитанные с помощью getName, getSurname и т.д.
// По событию oninput в любом из полей ввода нужно запускать соответствующий set..... Например при изменении
// поля ввода имени должен запускаться setName(какой-то инпут.value). Функции set... возвращают значение, и
// его нужно занести обратно в input. Таким образом в полях ввода невозможно будет ввести некорректные значения
// (например возраст не сможет выйти за пределы 0-100 лет)
person_form: {
  function createPersonClosure(name, surname) {
    let age;
    let fatherName;
    let obj = {
      getName() {
        return name;
      },
      getSurname() {
        return surname;
      },
      getFatherName() {
        return fatherName;
      },
      getAge() {
        return age;
      },
      getFullName() {
        return surname + ' ' + name + ' ' + fatherName;
      },
      setName(newName) {
        if (validateName(newName)) {
          name = newName;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
        return name;
      },
      setSurname(newSurname) {
        if (validateName(newSurname)) {
          surname = newSurname;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
        return surname;
      },
      setFatherName(newFatherName) {
        if (validateName(newFatherName)) {
          fatherName = newFatherName;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
        return fatherName;
      },
      setFullName(str) {
        let fullNameArray = str.split(' ');
        while (fullNameArray.length < 3) {
          fullNameArray.push(null);
        }
        surname = this.setSurname(fullNameArray[0]);
        name = this.setName(fullNameArray[1]);
        fatherName = this.setFatherName(fullNameArray[2]);
        return fullNameArray.filter(item => item !== null).join(' ');
      },
      setAge(newAge) {
        if (newAge >= 0 && newAge <= 100 || newAge == '') {
          age = newAge;
        } else {
          alert('ERROR');
        }
        return age;
      },
    }

    function validateName(name) {
      return name == null || name.charCodeAt(0) >= 65 && name.charCodeAt(0) <= 90 ||
        name.charCodeAt(0) >= 1040 && name.charCodeAt(0) <= 1071 || name == '';
    }

    return obj;
  }

  const b = createPersonClosure("Анна", "Иванова");
  b.setAge(15);
  b.setFullName("Петрова Анна Николаевна");

  function createForm(domElement, person) {
    let name = document.createElement('input');
    name.value = person.getName();
    domElement.append(name);
    let surname = document.createElement('input');
    surname.value = person.getSurname();
    domElement.append(surname);
    let fatherName = document.createElement('input');
    fatherName.value = person.getFatherName();
    domElement.append(fatherName);
    let age = document.createElement('input');
    age.value = person.getAge();
    domElement.append(age);
    let fullName = document.createElement('input');
    fullName.value = person.getFullName();
    domElement.append(fullName);

    name.oninput = () => {
      name.value = person.setName(name.value);
    }
    surname.oninput = () => {
      surname.value = person.setSurname(surname.value);
    }
    fatherName.oninput = () => {
      fatherName.value = person.setFatherName(fatherName.value);
    }
    age.oninput = () => {
      age.value = person.setAge(age.value);
    }
    fullName.oninput = () => {
      fullName.value = person.setFullName(fullName.value);
      surname.value = fullName.value.split(' ')[0] || '';
      name.value = fullName.value.split(' ')[1] || '';
      fatherName.value = fullName.value.split(' ')[2] || '';
    }
  }
  createForm(document.body, b);
}

get_set_form: {
  function createPersonClosure(name, surname) {
    let age;
    let fatherName;
    let obj = {
      getName() {
        return name;
      },
      getSurname() {
        return surname;
      },
      getFatherName() {
        return fatherName;
      },
      getAge() {
        return age;
      },
      getFullName() {
        return surname + ' ' + name + (fatherName ? ' ' + fatherName : '');
      },
      setName(newName) {
        if (validateName(newName)) {
          name = newName;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
        return name;
      },
      setSurname(newSurname) {
        if (validateName(newSurname)) {
          surname = newSurname;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
        return surname;
      },
      setFatherName(newFatherName) {
        if (validateName(newFatherName)) {
          fatherName = newFatherName;
        } else {
          alert('ERROR. You need write string with big first letter');
        }
        return fatherName;
      },
      setFullName(str) {
        let fullNameArray = str.split(' ');
        while (fullNameArray.length < 3) {
          fullNameArray.push(null);
        }
        surname = this.setSurname(fullNameArray[0]);
        name = this.setName(fullNameArray[1]);
        fatherName = this.setFatherName(fullNameArray[2]);
        return fullNameArray.filter(item => item !== null).join(' ');
      },
      setAge(newAge) {
        if (newAge >= 0 && newAge <= 100 || newAge == '') {
          age = newAge;
        } else {
          alert('ERROR');
        }
        return age;
      },
    }

    function validateName(name) {
      return name == null || name.charCodeAt(0) >= 65 && name.charCodeAt(0) <= 90 ||
        name.charCodeAt(0) >= 1040 && name.charCodeAt(0) <= 1071 || name == '';
    }

    return obj;
  }

  let car;
  {
    let brand = 'BMW', model = 'X5', volume = 2.4
    car = {
      getBrand() {
        return brand
      },
      setBrand(newBrand) {
        if (newBrand && typeof newBrand === 'string') {
          brand = newBrand
        }
        return brand
      },

      getModel() {
        return model
      },
      setModel(newModel) {
        if (newModel && typeof newModel === 'string') {
          model = newModel
        }
        return model
      },

      getVolume() {
        return volume
      },
      setVolume(newVolume) {
        if (newVolume && typeof newVolume === 'number' && newVolume > 0 && newVolume < 20) {
          volume = newVolume
        }
        return volume
      },

      getTax() {
        return volume * 100
      }
    }
  }

  function getSetForm(parent, getSet) {
    const inputs = {}; //реестр

    const updateInputs = () => {
      for (const fieldName in inputs) {
        const getKey = `get` + fieldName;
        if (getKey in getSet) {
          inputs[fieldName].value = getSet[getKey]() || '';
        }
      }
    };

    for (const getSetName in getSet) {
      const getOrSet = getSetName.slice(0, 3);
      const fieldName = getSetName.slice(3);//остальные буквы getSetName - типа "Name" или "FullName"
      const setKey = `set` + fieldName;
      const getKey = `get` + fieldName;
      if (!(fieldName in inputs)) {
        inputs[fieldName] = document.createElement('input');
        parent.append(inputs[fieldName]);
        if (!(setKey in getSet)) {
          inputs[fieldName].disabled = true;
        }
        inputs[fieldName].type = typeof getSet[getKey]();
        inputs[fieldName].placeholder = fieldName;
        inputs[fieldName].oninput = () => {
          inputs[fieldName].value = getSet[setKey](inputs[fieldName].value);
          updateInputs();
        };
      }

    }
    updateInputs();
  }
  getSetForm(document.body, car);
  getSetForm(document.body, createPersonClosure('Анон', "Анонов"));
}