#include <util/delay.h>
#include "lcd.h"

namespace lcd {
    void command(unsigned char cmnd) {
        LCD_Port = (LCD_Port & 0x0F) | (cmnd & 0xF0); /* sending upper nibble */
        LCD_Port &= ~ (1<<LCD_RS);		/* LCD_RS=0, command reg. */
        LCD_Port |= (1<<LCD_EN);		/* Enable pulse */
        _delay_us(1);
        LCD_Port &= ~ (1<<LCD_EN);

        _delay_us(200);

        LCD_Port = (LCD_Port & 0x0F) | (cmnd << 4);  /* sending lower nibble */
        LCD_Port |= (1<<LCD_EN);
        _delay_us(1);
        LCD_Port &= ~ (1<<LCD_EN);
        _delay_ms(2);
    }

    void put(unsigned char data) {
        LCD_Port = (LCD_Port & 0x0F) | (data & 0xF0); /* sending upper nibble */
        LCD_Port |= (1<<LCD_RS);		/* LCD_RS=1, data reg. */
        LCD_Port|= (1<<LCD_EN);
        _delay_us(1);
        LCD_Port &= ~ (1<<LCD_EN);
        _delay_us(200);

        LCD_Port = (LCD_Port & 0x0F) | (data << 4); /* sending lower nibble */
        LCD_Port |= (1<<LCD_EN);
        _delay_us(1);
        LCD_Port &= ~ (1<<LCD_EN);
        _delay_ms(2);
    }

    void init(void) {
        LCD_DDR = (1<<LCD_EN)|(1<<LCD_RS)|0xF0;			/* Make LCD port direction as o/p */
        _delay_ms(20);			/* LCD Power ON delay always >15ms */
        command(0x02);		/* send for 4 bit initialization of LCD  */
        command(0x28);              /* 2 line, 5*7 matrix in 4-bit mode */
        command(0x0c);              /* Display on cursor off*/
        command(0x06);              /* Increment cursor (shift cursor to right)*/
        command(0x01);              /* Clear display screen*/
        _delay_ms(2);
    }


    void string (char *str) {
        int i;
        for(i=0;str[i]!=0;i++) {		/* Send each char of string till the NULL */
            put(str[i]);
        }
    }

    void string_xy (char row, char pos, char *str) {
        if (row == 0 && pos<16)
            command((pos & 0x0F)|0x80);	/* Command of first row and required position<16 */
        else if (row == 1 && pos<16)
            command((pos & 0x0F)|0xC0);	/* Command of first row and required position<16 */
        string(str);		/* Call LCD string function */
    }

    void clear() {
        command (0x01);		/* Clear display */
        _delay_ms(2);
        command (0x80);		/* Cursor at home position */
    }
} // namespace lcd