var Table = require('../src/table');
var colors = require('colors/safe');

module.exports = function(runTest) {

  function it(name,fn) {
    var result = fn();
    runTest(name,result[0],result[1],result[2]);
  }

  it('use colSpan to span columns - (colSpan above normal cell)',function(){
    function makeTable(){
      var table = new Table({style:{head:[],border:[]}});

      table.push(
        [{colSpan:2,content:'greetings'}],
        [{colSpan:2,content:'greetings'}],
        ['hello','howdy']
      );

      return table;
    }

    var expected = [
        '┌───────────────┐'
      , '│ greetings     │'
      , '├───────────────┤'
      , '│ greetings     │'
      , '├───────┬───────┤'
      , '│ hello │ howdy │'
      , '└───────┴───────┘'
    ];

    return [makeTable,expected];
  });

  it('use colSpan to span columns - (colSpan below normal cell)',function(){
    function makeTable(){
      var table = new Table({style:{head:[],border:[]}});

      table.push(
        ['hello','howdy'],
        [{colSpan:2,content:'greetings'}],
        [{colSpan:2,content:'greetings'}]
      );

      return table;
    }

    var expected = [
        '┌───────┬───────┐'
      , '│ hello │ howdy │'
      , '├───────┴───────┤'
      , '│ greetings     │'
      , '├───────────────┤'
      , '│ greetings     │'
      , '└───────────────┘'
    ];

    return [makeTable,expected];
  });

  it('use rowSpan to span rows - (rowSpan on the left side)',function(){
    function makeTable(){
      var table = new Table({style:{head:[],border:[]}});

      table.push(
        [{rowSpan:2,content:'greetings'},{rowSpan:2,content:'greetings',vAlign:'center'},'hello'],
        ['howdy']
      );

      return table;
    }

    var expected = [
        '┌───────────┬───────────┬───────┐'
      , '│ greetings │           │ hello │'
      , '│           │ greetings ├───────┤'
      , '│           │           │ howdy │'
      , '└───────────┴───────────┴───────┘'
    ];

    return [makeTable,expected];
  });


  it('use rowSpan to span rows - (rowSpan on the right side)',function(){
    function makeTable(){
      var table = new Table({style:{head:[],border:[]}});

      table.push(
        ['hello',{rowSpan:2,content:'greetings'},{rowSpan:2,content:'greetings',vAlign:'bottom'}],
        ['howdy']
      );

      return table;
    }

    var expected = [
        '┌───────┬───────────┬───────────┐'
      , '│ hello │ greetings │           │'
      , '├───────┤           │           │'
      , '│ howdy │           │ greetings │'
      , '└───────┴───────────┴───────────┘'
    ];

    return[makeTable,expected];
  });

  it('mix rowSpan and colSpan together for complex table layouts',function(){
    function makeTable(){
      var table = new Table({style:{head:[],border:[]}});

      table.push(
        [{content:'hello',colSpan:2},{rowSpan:2, colSpan:2,content:'sup'},{rowSpan:3,content:'hi'}],
        [{content:'howdy',colSpan:2}],
        ['o','k','','']
      );

      return table;
    }

    var expected = [
        '┌───────┬─────┬────┐'
      , '│ hello │ sup │ hi │'
      , '├───────┤     │    │'
      , '│ howdy │     │    │'
      , '├───┬───┼──┬──┤    │'
      , '│ o │ k │  │  │    │'
      , '└───┴───┴──┴──┴────┘'
    ];

    return [makeTable,expected];
  });

  it('multi-line content will flow across rows in rowSpan cells',function(){
    function makeTable(){
      var table = new Table({style:{head:[],border:[]}});

      table.push(
        ['hello',{rowSpan:2,content:'greetings\nfriends'},{rowSpan:2,content:'greetings\nfriends'}],
        ['howdy']
      );

      return table;
    }

    var expected = [
        '┌───────┬───────────┬───────────┐'
      , '│ hello │ greetings │ greetings │'
      , '├───────┤ friends   │ friends   │'
      , '│ howdy │           │           │'
      , '└───────┴───────────┴───────────┘'
    ];

    return [makeTable, expected];
  });

  it('multi-line content will flow across rows in rowSpan cells - (complex layout)',function(){
    function makeTable(){
      var table = new Table({style:{head:[],border:[]}});

      table.push(
        [{content:'hello',colSpan:2},{rowSpan:2, colSpan:2,content:'sup\nman\nhey'},{rowSpan:3,content:'hi\nyo'}],
        [{content:'howdy',colSpan:2}],
        ['o','k','','']
      );

      return table;
    }

    var expected = [
        '┌───────┬─────┬────┐'
      , '│ hello │ sup │ hi │'
      , '├───────┤ man │ yo │'
      , '│ howdy │ hey │    │'
      , '├───┬───┼──┬──┤    │'
      , '│ o │ k │  │  │    │'
      , '└───┴───┴──┴──┴────┘'
    ];

    return [makeTable,expected];
  });

  it('rowSpan cells can have a staggered layout',function(){
    function makeTable(){
      var table = new Table({style:{head:[],border:[]}});

      table.push(
        [{content:'a',rowSpan:2},'b'],
        [{content:'c',rowSpan:2}],
        ['d']
      );

      return table;
    }

    var expected = [
        '┌───┬───┐'
      , '│ a │ b │'
      , '│   ├───┤'
      , '│   │ c │'
      , '├───┤   │'
      , '│ d │   │'
      , '└───┴───┘'
    ];

    return [makeTable,expected];
  });

  it('the layout manager automatically create empty cells to fill in the table',function(){
    function makeTable(){
      var table = new Table({style:{head:[],border:[]}});

      //notice we only create 3 cells here, but the table ends up having 6.
      table.push(
        [{content:'a',rowSpan:3,colSpan:2},'b'],
        [],
        [{content:'c',rowSpan:2,colSpan:2}],
        []
      );
      return table;
    }

    var expected = [
        '┌───┬───┬──┐'
      , '│ a │ b │  │'  // top-right and bottom-left cells are automatically created to fill the empty space
      , '│   ├───┤  │'
      , '│   │   │  │'
      , '│   ├───┴──┤'
      , '│   │ c    │'
      , '├───┤      │'
      , '│   │      │'
      , '└───┴──────┘'
    ];

    return [makeTable,expected];
  });

  it('use table `rowHeights` option to fix row height. The truncation symbol will be shown on the last line.',function(){
    function makeTable(){
      var table = new Table({rowHeights:[2],style:{head:[],border:[]}});

      table.push(['hello\nhi\nsup']);

      return table;
    }

    var expected = [
        '┌───────┐'
      , '│ hello │'
      , '│ hi…   │'
      , '└───────┘'
    ];

    return [makeTable,expected];
  });

  it('if `colWidths` is not specified, the layout manager will automatically widen rows to fit the content',function(){
    function makeTable(){
      var table = new Table({style:{head:[],border:[]}});

      table.push(
        [{colSpan:2,content:'hello there'}],
        ['hi', 'hi']
      );

      return table;
    }

    var expected = [
        '┌─────────────┐'
      , '│ hello there │'
      , '├──────┬──────┤'
      , '│ hi   │ hi   │'
      , '└──────┴──────┘'
    ];

    return [makeTable,expected];
  });

  it('you can specify a column width for only the first row, other rows will be automatically widened to fit content',function(){
    function makeTable(){
      var table = new Table({colWidths:[4],style:{head:[],border:[]}});

      table.push(
        [{colSpan:2,content:'hello there'}],
        ['hi',{hAlign:'center',content:'hi'}]
      );

      return table;
    }

    var expected = [
        '┌─────────────┐'
      , '│ hello there │'
      , '├────┬────────┤'
      , '│ hi │   hi   │'
      , '└────┴────────┘'
    ];

    return [makeTable, expected];
  });

  it('a column with a null column width will be automatically widened to fit content',function(){
    function makeTable(){
      var table = new Table({colWidths:[null, 4],style:{head:[],border:[]}});

      table.push(
        [{colSpan:2,content:'hello there'}],
        [{hAlign:'right',content:'hi'}, 'hi']
      );

      return table;
    }

    var expected = [
        '┌─────────────┐'
      , '│ hello there │'
      , '├────────┬────┤'
      , '│     hi │ hi │'
      , '└────────┴────┘'
    ];

    return [makeTable,expected];
  });

  it('feel free to use colors in your content strings, column widths will be calculated correctly',function(){
    function makeTable(){
      var table = new Table({colWidths:[5],style:{head:[],border:[]}});

      table.push([colors.red('hello')]);

      return table;
    }

    var expected = [
        '┌─────┐'
      , '│ ' + colors.red('he') + '… │'
      , '└─────┘'
    ];

    return [makeTable,expected,'truncation-with-colors'];
  });
};

/*

 var expected = [
   '┌──┬───┬──┬──┐'
 , '│  │   │  │  │'
 , '├──┼───┼──┼──┤'
 , '│  │ … │  │  │'
 , '├──┼───┼──┼──┤'
 , '│  │ … │  │  │'
 , '└──┴───┴──┴──┘'
 ];
 */