<?php
/**
 * OpenSQLManager
 *
 * Free Database manager for Open Source Databases
 *
 * @package		OpenSQLManager
 * @author 		Timothy J. Warren
 * @copyright	Copyright (c) 2012
 * @link 		https://github.com/aviat4ion/OpenSQLManager
 * @license 	http://philsturgeon.co.uk/code/dbad-license
 */

// --------------------------------------------------------------------------

namespace OpenSQLManager;

/**
 * Widget for adding / Editing Connections
 *
 * @package OpenSQLManager
 * @subpackage Widgets
 */
class Connection_Manager extends \wxFrame {
	
	const TXT_CONN_NAME = 1;
	const COMBO_DB_TYPE = 2;
	const FILE_DB_FILE = 3;
	const TXT_DB_NAME = 4;
	const TXT_DB_HOST = 5;
	const TXT_DB_PORT = 6;
	const TXT_DB_USER = 7;
	const TXT_DB_PASS = 8;
	const BTN_TEST = 9;
	
	/**
	 * Array of fields for Connection Information manipulation
	 *
	 * @var array
	 */
	protected $fields = array();
	
	/**
	 * Create the window
	 *
	 * @param wxWindow
	 * @param mixed
	 */
	public function __construct($parent, $params = array())
	{
		parent::__construct($parent, 32, "Connection Manager", wxDefaultPosition);
		
		// Layout the window
		$this->_layout($params);
	}
	
	// --------------------------------------------------------------------------
	
	/**
	 * Layout fields on the form
	 *
	 * @param array
	 */
	protected function _layout($params)
	{
		$container_sizer = new \wxBoxSizer(wxVERTICAL);
		
		// Use a table-like sizer
		$sizer = new \wxFlexGridSizer(2, 5, 5);
		$sizer->SetHGap(5);
		$sizer->SetVGap(5);
		$sizer->SetFlexibleDirection(wxBOTH);
		$sizer->AddGrowableCol(0, 1);
		$sizer->AddGrowableCol(1, 1);
		
		$db_types = $this->get_available_dbs();
		
		if ($db_types === FALSE)
		{
			error("No valid databases set up in PHP");
			return;
		}
		
		// Create the controls
		// label => control
		$this->fields = array(
			'Connection Name' => new \wxTextCtrl($this, self::TXT_CONN_NAME),
			'Database Type' => $choice = new \wxChoice(),
			'Database File' => new \wxFilePickerCtrl($this, self::FILE_DB_FILE, wxEmptyString, "Select the database file", '*.*'),
			'Database Name' => new \wxTextCtrl($this, self::TXT_DB_NAME),
			'Host' => new \wxTextCtrl($this, self::TXT_DB_HOST),
			'Port' => new \wxTextCtrl($this, self::TXT_DB_PORT),
			'User' => new \wxTextCtrl($this, self::TXT_DB_USER),
			'Password' => new \wxTextCtrl($this, self::TXT_DB_PASS)
		);
		
		$choice->Create($this, self::COMBO_DB_TYPE, wxDefaultPosition, wxDefaultSize, $db_types);
		
		// Add the controls to the sizer
		$i = 1;
		foreach ($this->fields as $lbl => $ctrl)
		{
			$label = new \wxStaticText($this, $i, $lbl);
			
			$sizer->Add($label, 0, wxALIGN_LEFT);
			$sizer->Add($ctrl, 1, wxALIGN_RIGHT|wxEXPAND);
			
			$i++;
		}
		
		// Test Connection Button
		$test_button = new \wxButton($this, self::BTN_TEST, 'Test Connection');
		$test_button->Connect(wxEVT_COMMAND_BUTTON_CLICKED, array($this, 'test_conn'));
		
		// Add Connection Button
		// TODO: Add connection button		
		
		// Add the buttons to the sizer
		$sizer->Add($test_button, 1, wxEXPAND);
		
		// Add the sizer to the window
		// Add it inside of another sizer for padding.
		$container_sizer->Add($sizer, 1, wxALL|wxEXPAND, 10);
		$this->SetSizer($container_sizer);
		$this->Layout();
		
		// Autosize the window to fit the controls
		$this->Fit();
		$this->CenterOnScreen(wxBOTH);
	}
	
	// --------------------------------------------------------------------------
	
	/**
	 * Get the list of available database types
	 *
	 * return array
	 */
	protected function get_available_dbs()
	{
		$drivers = array("");
		
		$pdo_drivers = \pdo_drivers();
		
		// Add PDO drivers
		foreach ($pdo_drivers as &$d)
		{
			// Skip sqlite2 as opposed to sqlite3
			if ($d === 'sqlite2' && (in_array('sqlite', $pdo_drivers) || in_array('sqlite3', $pdo_drivers)))
			{
				continue;
			}
		
			// Use the ibase_functions over PDO::Firebird, at least for now
			if ($d === 'firebird')
			{
				continue;
			}
		
			// Replace default capitalization with something that looks better.
			$d = str_replace("sql", "SQL", $d);
			$d = str_ireplace("pg", "Postgre", $d);
			$d = str_ireplace("odbc", "ODBC", $d);
			$d = ucfirst($d);
		
			$drivers[] = $d;
		}
		
		// Add firebird support, if exists
		if (function_exists('fbird_connect'))
		{
			$drivers[] = "Firebird";
		}
		
		sort($drivers);
		
		return $drivers;
	}
	
	// --------------------------------------------------------------------------
	
	/**
	 * Set defaults for new database type
	 *
	 * @return void
	 */
	public function change_db()
	{
		
	}
	
	// --------------------------------------------------------------------------
	
	/**
	 * Test a db connection, and display a popup with the result
	 *
	 * @return void
	 */
	public function test_conn()
	{
		// Get the connection parameters
		$params = $this->_get_vals();
		
		// Smart alek error for smart alek behavior
		if (empty($params->type))
		{
			error("You need to select the correct database type");
			return;
		}
		
		// Catch connection exceptions, and
		// display the error message to the
		// user so they can edit the db
		// parameters
		try
		{
			new \Query_Builder($params);
		}
		catch (\PDOException $e)
		{
			error("Error connecting to database: \n\n" . $e->getMessage());
			return;
		}
		
		// Successful Connection?
		// Tell the user!
		alert("Successfully Connected.");
	}
	
	// --------------------------------------------------------------------------
	
	/**
	 * Get the values of the widgets in the window
	 *
	 * @return object
	 */
	private function _get_vals()
	{
		$params = new \stdClass();
		$fields =& $this->fields;
		
		$types = $this->get_available_dbs();
		$type_id = $fields['Database Type']->GetSelection();
		$type = (isset($types[$type_id])) 
                    ? $types[$type_id]
                    : "";
		
		$params->name = $fields['Connection Name']->GetValue();
		$params->type = $type;
		$params->file = $fields['Database File']->GetPath();
		$params->conn_db = $fields['Database Name']->GetValue();
		$params->host = $fields['Host']->GetValue();
		$params->port = $fields['Port']->GetValue();
		$params->user = $fields['User']->GetValue();
		$params->pass = $fields['Password']->GetValue();
		
		return $params;
	}
}

// End of connection_manager.php