/**
  * Create a new Route. 
  * 
  * @param string $pattern The pattern (TODO: explain patterns)
  * @param array $options Associative array containging the route configuration.
  * 
  * Possible options are:
  * 
  * option 			| type 			| default 	| description
  * ---------------- | ------------- | --------- | -------------------------
  * controller       | string 		| 			| The controller for this route
  * action 			| string 		| "Index" 	| The controller-action to use
  * model 			| string 		| ""		| The model for this route. This can be used to auto-generate urls for models, using Route::editPath($modelInstance), Route::newPath(ModelClass), etc.
  * method 			| string 		| "" 		| HTTP method filter (POST or GET). When no method is passed, all methods are accepted
  * protocol			| string		| ""		| Server protocol filter ("https" or "http"). By default all protocols are accepted
  * domains			| array			| 			| An array of domains this route is active for. By default this is empty, meaning all domains will match. You can use regular expressions in this array.
  * formats 			| array			| 			| The list of accepted formats. See ..........
  * 
  */
 public function __construct($pattern, $options)
 {
     // No controller given?
     if (!array_key_exists("controller", $options) || empty($options['controller'])) {
         throw new \Exception("You cannot create a Route without specifying a controller.", 1);
     }
     // Default options
     $options = ArrayUtil::Defaults($options, array("action" => "Index", "model" => "", "method" => "", "protocol" => "", "controllerPath" => "", "domains" => null, "formats" => null));
     // Localize
     $this->pattern = $pattern;
     $this->controller = $options['controller'];
     $this->action = $options['action'];
     $this->model = $options['model'];
     $this->method = $options['method'];
     $this->protocol = $options['protocol'];
     $this->controllerPath = $options['controllerPath'];
     $this->domains = $options['domains'];
     $this->formats = $options['formats'];
     // Is there a variable in pattern?
     if (strstr($this->pattern, "{") !== false) {
         // Find all { }'s
         preg_match_all("/({([^}]*)})/", $this->pattern, $matches);
         $this->_regExVars = $matches[2];
         // Create regular expression to match this pattern
         $regex = "/" . preg_replace(array("/({#([^}]*)})/", "/({([^}]*)})/"), array("([0-9]+)", "([a-zA-Z0-9_-]+)"), str_replace("/", "\\/", $this->pattern)) . "+\$/";
         $this->_regExPattern = $regex;
     } else {
         $this->_regExPattern = '/' . str_replace("/", "\\/", $this->pattern) . "\$/";
         $this->_regExVars = array();
     }
 }
 /**
  * Render a response to send to the browser
  * 
  * ## Render view
  * @param string $view The view you wish to render, e.g. "news/index"
  * @param array $options (Optional) An associative array containing rendering options. See below for more information.
  * 
  * *Calling the function in this way will in fact set $view as $options['view'].*
  * 
  * ## Custom rendering
  * @param array $options An associative containing the rendering options
  * 
  * ### Render target
  * Use one of the following options to set the content to render. You cannot use more than one of these in one `Render` call.
  * 
  * option 			| type 							| example 						| description
  * ---------------- | ----------------------------- | ----------------------------- | -----------------------------
  * view 			| string 						| `"news/index"`				| The reference to the view you wish to render. Usually `[path]/[file-without-extension]`. The controller will determine which output format to use by looking at the request (either specific format through request, or HTTP accept headers). If you add an extension (e.g. `news/index.html`) to the view, this behavior will be skipped.
  * partial 			| string 						| `"news/menu"`					| The reference to a partial you wish to render. This is the same a rendering a view, except in that it will render without a layout (unless you manually specify a layout in the `Render` call). Partial files usually begin with an `_`, (e.g.: `news/_menu.html.php`).
  * json  			| string / IJsonObject / array	| `$newsModelInstance`			| When you pass an object that implements IJsonObject (such as Model), its AsJson function will be called and used as output for rendering. You can also pass an associative array, or a string containing already parsed Json. Finally, you can also use a view to render the Json; just pass the view location, as you would normally do when rendering a view.
  * xml 				| string / IXMLObject / array 	| `$newsModelInstance`			| Render given object/view as XML. This works the same way as `json`.
  * text 			| string 						| `"OK"`						| Render the given string as plain text.
  * html 			| string 						| `""
  * 
  * 
  * ### Rendering options
  * 
  * option 			| type 					| example 						| description
  * ---------------- | --------------------- | ----------------------------- | -----------------------------
  * layout			| string / boolean		| `"newsletter"`				| Layout to render. If you don't pass a layout, it will look in the Controller for a default layout, and finally for a globally set default layout. If you set `layout` to `false`, it will render without a layout.
  * flash 			| array 				| `array("notice" => "abc")`	| The flash messages you wish the page to know about. This array will be available as `$this->flash` in your views.
  * content-type		| string 				| `"application/rss"`			| You can use this to override the default MIME content-type associated with the data you render. 
  * http-status		| int 					| `403`							| The HTTP status code to send to the browser. By default this is 200 (Success). 
  *
  */
 protected function Render()
 {
     // Get arguments
     $args = func_get_args();
     if (count($args) == 0) {
         throw new Exception("Render cannot be called without at least 1 argument.", 1);
     } elseif (count($args) >= 1 && is_string($args[0])) {
         // Render a view. Now add that to the options array, if there is one
         $options = array("view" => $args[0]);
         if (count($args) > 1) {
             $options = ArrayUtil::Defaults($options, $args[1]);
         }
     } else {
         // Interpret the first argument as an options array
         $options = $args[0];
     }
     // Set content type
     $contentType = $this->request->format->contentTypes[0];
     if (strpos(';', $contentType) === false) {
         $contentType .= ';charset=' . strtoupper(ChickenWire::get("defaultCharset"));
     }
     header("Content-type: " . $contentType);
     // Instantiate rendered content array
     $this->renderedContent = array("main" => "");
     // Start buffering
     $this->_currentContentKey = "main";
     ob_start();
     // Render object
     $renderType = $this->renderContent($options);
     // Buffering done
     $rendered = ob_get_contents();
     ob_end_clean();
     // Layout defined (we only render layouts for views...)?
     if ($renderType == "view" && (!array_key_exists("layout", $options) || $options['layout'] == "")) {
         // Get the default layout
         $options['layout'] = $this->getDefaultLayout();
     }
     // Any layout?
     if (array_key_exists("layout", $options) && $options['layout'] !== false) {
         // Store it
         $this->renderedContent['main'] .= $rendered;
         // Look for the layout file
         $layoutFilename = $this->lookForFile("layouts/" . $options['layout']);
         if ($layoutFilename === false) {
             throw new \Exception("Layout could not be found for " . $options['layout'], 1);
         }
         // Create layout
         $layout = new Layout($layoutFilename);
         $layout->Render($this->renderedContent);
     } else {
         // Just output rendered content
         echo $rendered;
     }
 }
 public function Stylesheet($filename, array $options = null)
 {
     // No options?
     if (is_null($options)) {
         $options = array();
     }
     // Check filename's extension
     if (pathinfo($filename, PATHINFO_EXTENSION) == "") {
         $filename .= ".css";
     }
     // Add static path and create URL
     if (strstr($filename, "://")) {
         $link = $filename;
     } else {
         $link = Url::Create(Path::Construct(ChickenWire::get("pathCSS")) . $filename);
     }
     // Create the tag
     return $this->SingleTag("link", ArrayUtil::Defaults($options, array("src" => $link, "rel" => "stylesheet", "type" => "text/css")));
 }