#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <conio.h>

int const MaxPassAndEmailLen = 64;
using namespace std;

class YahooLogOn
{
private:
    int ErrorID[2];
    char Email[MaxPassAndEmailLen]; // @yahoo.com  + max email len 20 = 30 + \0 = 31
    char PassWord[MaxPassAndEmailLen];
    bool m_AllowEmailletter(const char *ch);
    bool m_NotAllowPasswordLetters(const char *ch);
    bool m_EmailNameCorrect(const char *strname, unsigned int charnum);
    bool m_PassIsCorrect(const char *strpass, unsigned int passlen);
    int m_strcmp(const char *str1, const char *str2);
    void m_tolower(char *str);

public:
    YahooLogOn();
    int GetEmail();
    int GetPassWord();
    unsigned int m_strlen(const char *str);

    void ErrorMsgs() const;

};
///////////////////////////////////////////////
void YahooLogOn::ErrorMsgs() const
{
    switch (ErrorID[0])
    {
    case 1:
        ;
    default:
        cout << "Wellcome to yahoo email ....";
    }

}

YahooLogOn::YahooLogOn()
{
    for (int i = 0; i < MaxPassAndEmailLen; i++) // initilatizing password to zero .
        *(PassWord + i) = '\0';
}
//////////////////////////////////////////////////////////////////////////////

bool YahooLogOn::m_EmailNameCorrect(const char *strname, unsigned int charlen)
{
    unsigned int Found = 0;
    for (int i = 0; i < charlen; i++)
        if (m_AllowEmailletter(strname + i))
            Found++;
    return (Found == charlen);
}
////////////////////////////////////////////

bool YahooLogOn::m_PassIsCorrect(const char *strpass, unsigned int passlen)
{
    unsigned int Found = 0;
    for (int i = 0; i < passlen; i++)
        if (!m_NotAllowPasswordLetters(strpass + i))
            Found++;
    return (Found == passlen);
}
// Return Ture if char form allowed letters in Email name before @yahoo.com or @yahoo.fr .

bool YahooLogOn::m_AllowEmailletter(const char *ch)
{
    return ( (*ch > 95 && *ch < 123) || (*ch > 63 && *ch < 91) || (*ch > 47 && *ch < 58) || (*ch == '_'));
}
//////////////////////////////////////////////////
// return True if contain non allowed pass letters.

bool YahooLogOn::m_NotAllowPasswordLetters(const char *ch)
{
    return ( *ch == '<' || *ch == '>' || *ch == '|' || *ch == ':' || *ch == '"' || *ch == '\'' || *ch=='/' || *ch== 0x60 ); //
}

/*
 * check Email and return apprirate state.
 * return 1 -    Error msg: email too samll or too long // 9(@yahoo.fr)+6(min email len) =  15
 * return 2 -    if @yahoo.com or @yahoo.fr not found.
 *               Er Msg: Plz enter name like example@yahoo.com or example@yahoo.fr *
 * return 3 -    sorry alph letter and numbers and underscore allowed.
 */
int YahooLogOn::GetEmail()
{
    cout << "Email: ";
    cin.getline(Email, MaxPassAndEmailLen);
    m_tolower(Email); // convert email name to lower to prepare it for campare.
    unsigned int i = 0;
    unsigned int EmailLength = m_strlen(Email);

    if (EmailLength < 15 || EmailLength > 30 ) // email between 15 to 30 letter.
        return 1;
    else if (m_strcmp(Email + (EmailLength - 9), "@yahoo.fr") == 0)
    {
        if (!m_EmailNameCorrect(Email, EmailLength - 9))
            return 3;
    }
    else if (m_strcmp(Email + (EmailLength - 10), "@yahoo.com") == 0)
    {
        if (!m_EmailNameCorrect(Email, EmailLength - 10))
            return 3;
    }
    else if (!((m_strcmp(Email + (EmailLength - 9), "@yahoo.fr") == 0)|| (m_strcmp(Email + (EmailLength - 10), "@yahoo.com") == 0)))
        return 3;
    else
        return 0;
}

///////////////////////////////////////////
//return 1 if too small password.
//return 2 contain none allowed characters.

int YahooLogOn::GetPassWord()
{
    cout << "Pass Word: ";
    char ch;
    unsigned int i = 0;

    while((ch=getch()) != '\r')
    {
        putch('*');
        if(i < MaxPassAndEmailLen) *(PassWord+i) = ch;
        i++;
    }

    unsigned int PassLength = m_strlen(PassWord);
    if (PassLength < 10 || PassLength > 30 ) // password to small or to long.
        return 1;
    else if (!m_EmailNameCorrect(PassWord, PassLength))
        return 2;
    else
        return 0;
}
unsigned int YahooLogOn::m_strlen(const char *str)
{
    unsigned int i = 0;
    while (*str++ != '\0')
        i++;
    return i;
}

int YahooLogOn::m_strcmp(const char *s1, const char *s2)
{
    while ((*s1 && *s2) && (*s1++ == *s2++));
    return *(--s1) - *(--s2);
}

void YahooLogOn::m_tolower(char *str) // convert capital letter if found to lower letter by add 32 the diff
{
    while (*str != '\0')
    {
        if ((*str > 64 && *str < 91)) //
            *str = (*str) + 32;
        str++;
    }
}
////////////////////////////// main /////////////////

int main(int argc, char** argv)
{
    YahooLogOn y1;
    switch (y1.GetEmail())
    {
    case 1:
        cout << "Email too samll long.\n";
        break;
    case 2:
        cout << "Email not end with @yahoo.com or @yahoo.fr .\n";
        break;
    case 3:
        cout << "sorry alph letter and numbers and underscore allowed.\n";
        break;
    case 0:
        cout << "congratulation u now connected.\n";
        break;
    default: "Error while connection\n"
        ;
    }
    switch (y1.GetPassWord())
    {
    case 1:
        cout << "pass too samll or long.\n";
        break;
    case 2:
        cout << "sorry < > ' | :. not allowed. \n";
        break;
    case 0:
        cout << "Pass word is correct\n .";
        break;
    default: "Error while connection\n"
        ;
    }
    return 0;
} // end of main