const boost::shared_ptr<ribi::TextCanvas> ribi::ToggleButtonWidget::ToTextCanvas(
    const int width, const int height
) const noexcept
{
    const boost::shared_ptr<TextCanvas> canvas {
        new TextCanvas(width,height)
    };
    assert(width  == 6 && "For now");
    assert(height == 4 && "For now");


    if (GetToggleButton()->IsPressed())
    {
        canvas->PutText(0,0," ____ ");
        canvas->PutText(0,1,"|    |");
        canvas->PutText(0,2,"|____|");
    }
    else
    {
        canvas->PutText(0,0," ____ ");
        canvas->PutText(0,1,"|    |");
        canvas->PutText(0,2,"|____|");
        canvas->PutText(0,3,"|____|");
    }
    return canvas;
}
void ribi::MysteryMachine::Update() noexcept
{
  const int back = static_cast<int>(GetDialBack()->GetDial()->GetPosition() * 16.0) % 3;
  const int front = static_cast<int>(GetDialFront()->GetDial()->GetPosition() * 16.0) % 3;
  int top = (GetToggleButton()->GetToggleButton()->IsPressed()
    ? (1 + front - back + 3) % 3
    : -1);
  assert(front >= 0);
  assert(front  < 3);
  assert(back >= 0);
  assert(back  < 3);
  assert(top >= -1); //-1 denotes off
  assert(top  < 3);
  m_led_front_1->GetLed()->SetIntensity(front == 0 ? 1.0 : 0.0);
  m_led_front_2->GetLed()->SetIntensity(front == 1 ? 1.0 : 0.0);
  m_led_front_3->GetLed()->SetIntensity(front == 2 ? 1.0 : 0.0);
  m_led_back_1->GetLed()->SetIntensity(back == 0 ? 1.0 : 0.0);
  m_led_back_2->GetLed()->SetIntensity(back == 1 ? 1.0 : 0.0);
  m_led_back_3->GetLed()->SetIntensity(back == 2 ? 1.0 : 0.0);
  m_led_top_front->GetLed()->SetIntensity( top == 0 ? 1.0 : 0.0);
  m_led_top_middle->GetLed()->SetIntensity(top == 1 ? 1.0 : 0.0);
  m_led_top_back->GetLed()->SetIntensity(  top == 2 ? 1.0 : 0.0);
}
const boost::shared_ptr<ribi::DrawCanvas> ribi::ToggleButtonWidget::ToDrawCanvas(
    const int width_in, const int height_in) const noexcept
{
    boost::shared_ptr<DrawCanvas> canvas {
        new DrawCanvas(width_in,height_in,CanvasColorSystem::invert)
    };
    //Pressed
    //
    //
    //
    //
    //
    //
    //
    //         ```.  -.```
    // `.-:-:.`-``.  -.``-`.:-:-.`
    ///M:.                     .:M/
    //oM:.                     .:Mo <- y1 = y2 - 2.0
    //`---::---`.``. .``.`---::--:-
    //`h:.    ` ```. .``` `    .:d- <- y2 = 5/6
    //  .-:-:-`-``. . .``-`-:-:-.
    //       ` ```. . .``` `



    //Toggled:

    //         ```.  -.```
    // `.-:-:.`-``.  -.``-`.:-:-.`
    ///M:.                     .:M/  <- y1 = 1/6
    //oM:.                     .:Mo
    //.---::---`.``. .``.`---::---.
    //..      ` ```. .``` `      ..
    //..                         ..
    //..                         ..
    //..                         ..
    //..                         ..
    //`.                         --
    //`h:.                     .:d- <- y2 = 5/6
    //  .-:-:-`-``. . .``-`-:-:-.
    //       ` ```. . .``` `

    const double left = 1.0;
    const double top  = 1.0;
    const double right  = static_cast<double>(width_in ) - 2.0;
    const double bottom = static_cast<double>(height_in) - 2.0;
    const double height = bottom - top;
    const double height_1_6 = height / 6.0;
    const double y2 = top + (height * 5.0 / 6.0);
    const double y1 = GetToggleButton()->IsPressed() ? y2 - 2.0 : top + (height * 1.0 / 6.0);

    const double pi = boost::math::constants::pi<double>();
    //Below
    canvas->DrawArc(
        left,
        y2 - height_1_6,
        right,
        y2 + height_1_6,
        0.5 * pi * boost::units::si::radian,
        1.0 * pi * boost::units::si::radian
    );
    //Draw top
    canvas->DrawEllipse(
        left,
        y1 - height_1_6,
        right,
        y1 + height_1_6
    );
    canvas->DrawLine(
        left,
        y1,
        left,
        y2
    );
    canvas->DrawLine(
        right,
        y1,
        right,
        y2
    );
    return canvas;
}