/* wconfig_path.cc
 * This file belongs to Worker, a file manager for UN*X/X11.
 * Copyright (C) 2006-2023 Ralf Hoffmann.
 * You can contact me at: ralf@boomerangsworld.de
 *   or http://www.boomerangsworld.de/worker
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "wconfig_path.hh"
#include "wconfig.h"
#include "wcpath.hh"
#include "worker.h"
#include "worker_locale.h"
#include "aguix/button.h"
#include "aguix/solidbutton.h"
#include "aguix/cyclebutton.h"
#include "simplelist.hh"

PathPanel::PathPanel( AWindow &basewin, WConfig &baseconfig ) : WConfigPanel( basewin, baseconfig )
{
  banknr = 0;
  pbs = NULL;
  rows = _baseconfig.getRows();

  maxbank = _baseconfig.getPaths()->size()/rows;

  extmode = false;
  m_mode = 0;
  selindex = -1;
}

PathPanel::~PathPanel()
{
  delete [] pbs;
}

int PathPanel::create()
{
  Panel::create();

  char bankstr[ A_BYTESFORNUMBER( int ) ];
  unsigned int i2;

  AContainer *ac1 = setContainer( new AContainer( this, 1, 5 ), true );
  ac1->setMinSpace( 5 );
  ac1->setMaxSpace( 5 );
  
  addMultiLineText( catalog.getLocale( 712 ),
                    *ac1,
                    0, 0,
                    NULL, NULL );

  AContainer *ac1_2 = ac1->add( new AContainer( this, 2, 1 ), 0, 1 );
  ac1_2->setMinSpace( 5 );
  ac1_2->setMaxSpace( 5 );
  ac1_2->setBorderWidth( 0 );

  AContainer *ac1_2_1 = ac1_2->add( new AContainer( this, 1, rows ), 0, 0 );
  ac1_2_1->setMinSpace( 0 );
  ac1_2_1->setMaxSpace( 0 );
  ac1_2_1->setBorderWidth( 0 );
  
  pbs = new Button*[rows];
  for ( i2 = 0; i2 < rows; i2++ ) {
    pbs[i2] = (Button*)ac1_2_1->add( new Button( _aguix,
                                                 0, 0,
                                                 "", 0 ),
                                     0, i2, AContainer::CO_INCW );
    pbs[i2]->connect( this );
  }

  AContainer *ac1_2_2 = ac1_2->add( new AContainer( this, 1, 5 ), 1, 0 );
  ac1_2_2->setMinSpace( 0 );
  ac1_2_2->setMaxSpace( 0 );
  ac1_2_2->setBorderWidth( 0 );

  AContainer *ac1_2_2_1 = ac1_2_2->add( new AContainer( this, 4, 1 ), 0, 0 );
  ac1_2_2_1->setMinSpace( 5 );
  ac1_2_2_1->setMaxSpace( 5 );
  ac1_2_2_1->setBorderWidth( 0 );

  sprintf( bankstr, "%2d", banknr + 1 );
  
  ac1_2_2_1->add( new Text( _aguix, 0, 0, catalog.getLocale( 68 ) ), 0, 0, AContainer::CO_FIX );
  bnrt = (Text*)ac1_2_2_1->add( new Text( _aguix, 0, 0, bankstr ), 1, 0, AContainer::CO_FIX );
  ac1_2_2_1->add( new Text( _aguix, 0, 0, "/" ), 2, 0, AContainer::CO_FIX );

  sprintf( bankstr, "%2d", maxbank );
  maxbankt = (Text*)ac1_2_2_1->add( new Text( _aguix, 0, 0, bankstr ), 3, 0, AContainer::CO_FIX );

  nextbb = (Button*)ac1_2_2->add( new Button( _aguix, 0, 0, catalog.getLocale( 69 ), 0 ),
                                  0, 1, AContainer::CO_FIX );
  nextbb->connect( this );
  
  prevbb = (Button*)ac1_2_2->add( new Button( _aguix, 0, 0, catalog.getLocale( 70 ), 0 ),
                                  0, 2, AContainer::CO_FIX );
  prevbb->connect( this );
  
  newbb = (Button*)ac1_2_2->add( new Button( _aguix, 0, 0, catalog.getLocale( 71 ), 0 ),
                                 0, 3, AContainer::CO_FIX );
  newbb->connect( this );

  delbb = (Button*)ac1_2_2->add( new Button( _aguix, 0, 0, catalog.getLocale( 72 ), 0 ),
                                 0, 4, AContainer::CO_FIX );
  delbb->connect( this );

  AContainer *ac1_3 = ac1->add( new AContainer( this, 3, 1 ), 0, 2 );
  ac1_3->setMinSpace( 0 );
  ac1_3->setMaxSpace( 0 );
  ac1_3->setBorderWidth( 0 );

  copyb = (Button*)ac1_3->add( new Button( _aguix, 0, 0, catalog.getLocale( 73 ), 0 ),
                               0, 0, AContainer::CO_INCW );
  copyb->connect( this );
  swapb = (Button*)ac1_3->add( new Button( _aguix, 0, 0, catalog.getLocale( 74 ), 0 ),
                               1, 0, AContainer::CO_INCW );
  swapb->connect( this );
  delb = (Button*)ac1_3->add( new Button( _aguix, 0, 0, catalog.getLocale( 75 ), 0 ),
                              2, 0, AContainer::CO_INCW );
  delb->connect( this );

  sbsb = (SolidButton*)ac1->add( new SolidButton( _aguix, 0, 0, "", "button-special1-fg", "button-special1-bg", false ),
                                 0, 3, AContainer::CO_INCW );

  AContainer *ac1_4 = ac1->add( new AContainer( this, 2, 1 ), 0, 4 );
  ac1_4->setMinSpace( 5 );
  ac1_4->setMaxSpace( 5 );
  ac1_4->setBorderWidth( 0 );

  ac1_4->add( new Text( _aguix, 0, 0, catalog.getLocale( 227 ) ), 0, 0, AContainer::CO_FIX );
  cyb = (CycleButton*)ac1_4->add( new CycleButton( _aguix, 0, 0, 100, 0 ), 1, 0, AContainer::CO_INCW );
  cyb->connect( this );

  cyb->addOption( catalog.getLocale( 228 ) );
  cyb->addOption( catalog.getLocale( 229 ) );
  cyb->resize( cyb->getMaxSize(), cyb->getHeight() );
  ac1_4->readLimits();

  if ( extmode == true ) cyb->setOption( 1 );
  else cyb->setOption( 0 );

  contMaximize( true );
  sbsb->setText( catalog.getLocale( 76 ) );
  showPathBank();

  addKeyCallBack( this, AWindow::KEYCB_WHENVISIBLE );
  return 0;
}

int PathPanel::saveValues()
{
  return 0;
}

void PathPanel::showPathBank()
{
  WCPath *p1;
  int id = _baseconfig.getPaths()->initEnum();
  if ( ( banknr >= 0 ) && ( banknr < ( _baseconfig.getPaths()->size() / (int)rows ) ) ) {
    for ( unsigned int i = 0; i < rows; i++ ) {
      p1 = (WCPath*)_baseconfig.getPaths()->getElementAt( id, i + banknr * rows );
      if ( ( p1 != NULL ) && ( p1->getCheck() == true ) ) {
        pbs[i]->setText( 0, p1->getName() );
        pbs[i]->setFG( 0, p1->getFG() );
        pbs[i]->setBG( 0, p1->getBG() );
      } else {
        pbs[i]->setText( 0, "" );
        pbs[i]->setFG( 0, 1 );
        pbs[i]->setBG( 0, 0 );
      }
    }
  }
  _baseconfig.getPaths()->closeEnum( id );
}

void PathPanel::run( Widget *elem, const AGMessage &msg )
{
  List *paths = _baseconfig.getPaths();
  unsigned int i2;

  if ( _need_recreate == true ) return;

  if ( msg.type == AG_BUTTONCLICKED ) {
    if ( msg.button.button == nextbb ) {
      if ( ( banknr + 1 ) < maxbank ) {
	banknr++;
	showPathBank();
        updateBankStr();
      }
    } else if ( msg.button.button == prevbb ) {
      if ( banknr > 0 ) {
	banknr--;
	showPathBank();
        updateBankStr();
      }
    } else if ( msg.button.button == newbb ) {
      int s2 = ( banknr + 1 ) * rows;
      for ( i2 = 0; i2 < rows; i2++ ) {
	paths->addElementAt( s2, new WCPath() );
      }
      maxbank++;
      banknr++;
      showPathBank();
      updateBankStr();
    } else if ( msg.button.button == delbb ) {
      if ( maxbank > 1 ) {
	int s2 = banknr * rows;
	WCPath *p1;
	for ( i2 = 0; i2 < rows; i2++ ) {
	  p1 = (WCPath*)paths->getElementAt( s2 );
	  delete p1;
	  paths->removeElementAt( s2 );
	}
	maxbank--;
	if ( banknr >= maxbank ) {
	  banknr--;
	}
        updateBankStr();
	showPathBank();
      }
    } else if ( msg.button.button == copyb ) {
      if ( ( m_mode == 1 ) || ( m_mode == 2 ) ) {
	sbsb->setText( catalog.getLocale( 76 ) );
	setMode( 0 );
      } else {
	sbsb->setText( catalog.getLocale( 77 ) );
	setMode( 1 );
      }
    } else if ( msg.button.button == swapb ) {
      if ( ( m_mode == 3 ) || ( m_mode == 4 ) ) {
	sbsb->setText( catalog.getLocale( 76 ) );
	setMode( 0 );
      } else {
	sbsb->setText( catalog.getLocale( 79 ) );
	setMode( 3 );
      }
    } else if ( msg.button.button == delb ) {
      if ( m_mode == 5 ) {
	sbsb->setText( catalog.getLocale( 76 ) );
	setMode( 0 );
      } else {
	sbsb->setText( catalog.getLocale( 81 ) );
	setMode( 5 );
      }
    } else {
      for ( i2 = 0; i2 < rows; i2++ ) {
	if ( msg.button.button == pbs[i2] ) {
	  int s1 = i2 + banknr * rows;
	  WCPath *p1, *p2;
	  switch ( m_mode ) {
	  case 1:
	    selindex = s1;
	    sbsb->setText( catalog.getLocale( 78 ) );
	    setMode( 2 );
	    break;
	  case 2:
	    // copy selindex -> s1
	    p1 = (WCPath*)paths->getElementAt( selindex );
	    p2 = p1->duplicate();
	    // reset shortkey to avoid duplicates
	    p2->setDoubleKeys( NULL );
	    
	    p1 = (WCPath*)paths->exchangeElement( s1, p2 );
	    if ( p1 != NULL ) delete p1;
	    showPathBank();
	    if ( extmode == true ) {
	      sbsb->setText( catalog.getLocale( 77 ) );
	      setMode( 1 );
	    } else {
	      sbsb->setText( catalog.getLocale( 76 ) );
	      setMode( 0 );
	    }
	    break;
	  case 3:
	    selindex = s1;
	    sbsb->setText( catalog.getLocale( 80 ) );
	    setMode( 4 );
	    break;
	  case 4:
	    // swap s1 <-> selindex
	    p1 = (WCPath*)paths->getElementAt( selindex );
	    p2 = (WCPath*)paths->exchangeElement( s1, p1 );
	    paths->exchangeElement( selindex, p2 );
	    showPathBank();
	    if ( extmode == true ) {
	      sbsb->setText( catalog.getLocale( 79 ) );
	      setMode( 3 );
	    } else {
	      sbsb->setText( catalog.getLocale( 76 ) );
	      setMode( 0 );
	    }
	    break;
	  case 5:
	    // del s1
	    p1 = new WCPath();
	    p2 = (WCPath*)paths->exchangeElement( s1, p1 );
	    if ( p2 != NULL ) delete p2;
	    showPathBank();
	    if ( extmode == false ) {
	      sbsb->setText( catalog.getLocale( 76 ) );
	      setMode( 0 );
	    }
	    break;
	  default:
	    // configure s1
	    p1 = (WCPath*)paths->getElementAt( s1 );
	    if ( p1 != NULL ) {
	      if(_baseconfig.configurePathIndex( s1 ) == true ) {
		showPathBank();
	      }
	    }
	  }
	  break;
	}
      }
    }
  } else if ( msg.type == AG_CYCLEBUTTONCLICKED ) {
    if ( msg.cyclebutton.cyclebutton == cyb ) {
      if ( msg.cyclebutton.option == 1 ) extmode = true;
      else extmode = false;
    }
  } else if ( msg.type == AG_KEYPRESSED ) {
    if ( msg.key.key == XK_Escape ) {
      sbsb->setText( catalog.getLocale( 76 ) );
      setMode( 0 );
    }
  }
}


WConfigPanel::panel_action_t PathPanel::setColors( List *colors )
{
  if ( colors != _baseconfig.getColors() ) {
    _baseconfig.setColors( colors );
  }

  return PANEL_NOACTION;
}

WConfigPanel::panel_action_t PathPanel::setRows( int r )
{
  if ( r != (int)_baseconfig.getRows() ) {
    _baseconfig.setRows( r );
  }

  _need_recreate = true;
  return PANEL_RECREATE;
}

int PathPanel::addButtons( List *buttons,
                           WConfigPanelCallBack::add_action_t action )
{
  int erg = 0;

  if ( buttons != NULL && action == WConfigPanelCallBack::CHECK_DOUBLEKEYS ) {
    erg = _baseconfig.fixDoubleKeys( NULL, _baseconfig.getPaths(), NULL, buttons, NULL );
  }
  _need_recreate = true;
  return erg;
}

int PathPanel::addHotkeys( List *hotkeys,
                           WConfigPanelCallBack::add_action_t action )
{
  int erg = 0;

  if ( hotkeys != NULL && action == WConfigPanelCallBack::CHECK_DOUBLEKEYS ) {
    erg = _baseconfig.fixDoubleKeys( NULL, _baseconfig.getPaths(), NULL, NULL, hotkeys );
  }
  _need_recreate = true;
  return erg;
}

void PathPanel::updateBankStr()
{
  char bankstr[ A_BYTESFORNUMBER( int ) ];

  sprintf( bankstr, "%2d", banknr + 1 );
  bnrt->setText( bankstr );
  sprintf( bankstr, "%2d", maxbank );
  maxbankt->setText( bankstr );
}

bool PathPanel::escapeInUse()
{
    // return current value and check if mode is still in use
    bool res = m_escape_active;

    if ( m_mode == 0 ) m_escape_active = false;

    return res;
}

void PathPanel::setMode( int m )
{
    if ( m != 0 ) m_escape_active = true;
    m_mode = m;
}
